| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270 | /*! * elFinder - file manager for web * Version 2.1.43 (2018-11-24) * http://elfinder.org *  * Copyright 2009-2018, Studio 42 * Licensed under a 3-clauses BSD license */(function(root, factory) {	if (typeof define === 'function' && define.amd) {		// AMD		define(['jquery','jquery-ui'], factory);	} else if (typeof exports !== 'undefined') {		// CommonJS		var $, ui;		try {			$ = require('jquery');			ui = require('jquery-ui');		} catch (e) {}		module.exports = factory($, ui);	} else {		// Browser globals (Note: root is window)		factory(root.jQuery, root.jQuery.ui, true);	}}(this, function($, _ui, toGlobal) {toGlobal = toGlobal || false;/* * File: /js/elFinder.js *//** * @class elFinder - file manager for web * * @author Dmitry (dio) Levashov **/var elFinder = function(elm, opts, bootCallback) {		//this.time('load');	var self = this,				/**		 * Objects array of jQuery.Deferred that calls before elFinder boot up		 * 		 * @type Array		 */		dfrdsBeforeBootup = [],				/**		 * Plugin name to check for conflicts with bootstrap etc		 *		 * @type Array		 **/		conflictChecks = ['button', 'tooltip'],				/**		 * Node on which elfinder creating		 *		 * @type jQuery		 **/		node = $(elm),				/**		 * Object of events originally registered in this node		 * 		 * @type Object		 */		prevEvents = $.extend(true, {}, $._data(node.get(0), 'events')),				/**		 * Store node contents.		 *		 * @see this.destroy		 * @type jQuery		 **/		prevContent = $('<div/>').append(node.contents()).attr('class', node.attr('class') || '').attr('style', node.attr('style') || ''),				/**		 * Instance ID. Required to get/set cookie		 *		 * @type String		 **/		id = node.attr('id') || '',				/**		 * Events namespace		 *		 * @type String		 **/		namespace = 'elfinder-' + (id ? id : Math.random().toString().substr(2, 7)),				/**		 * Mousedown event		 *		 * @type String		 **/		mousedown = 'mousedown.'+namespace,				/**		 * Keydown event		 *		 * @type String		 **/		keydown = 'keydown.'+namespace,				/**		 * Keypress event		 *		 * @type String		 **/		keypress = 'keypress.'+namespace,				/**		 * Keypup event		 *		 * @type String		 **/		keyup    = 'keyup.'+namespace,		/**		 * Is shortcuts/commands enabled		 *		 * @type Boolean		 **/		enabled = false,				/**		 * Store enabled value before ajax request		 *		 * @type Boolean		 **/		prevEnabled = false,				/**		 * List of build-in events which mapped into methods with same names		 *		 * @type Array		 **/		events = ['enable', 'disable', 'load', 'open', 'reload', 'select',  'add', 'remove', 'change', 'dblclick', 'getfile', 'lockfiles', 'unlockfiles', 'selectfiles', 'unselectfiles', 'dragstart', 'dragstop', 'search', 'searchend', 'viewchange'],				/**		 * Rules to validate data from backend		 *		 * @type Object		 **/		rules = {},				/**		 * Current working directory hash		 *		 * @type String		 **/		cwd = '',				/**		 * Current working directory options default		 *		 * @type Object		 **/		cwdOptionsDefault = {			path          : '',			url           : '',			tmbUrl        : '',			disabled      : [],			separator     : '/',			archives      : [],			extract       : [],			copyOverwrite : true,			uploadOverwrite : true,			uploadMaxSize : 0,			jpgQuality    : 100,			tmbCrop       : false,			tmb           : false // old API		},				/**		 * Current working directory options		 *		 * @type Object		 **/		cwdOptions = {},				/**		 * Files/dirs cache		 *		 * @type Object		 **/		files = {},				/**		 * Hidden Files/dirs cache		 *		 * @type Object		 **/		hiddenFiles = {},		/**		 * Files/dirs hash cache of each dirs		 *		 * @type Object		 **/		ownFiles = {},				/**		 * Selected files hashes		 *		 * @type Array		 **/		selected = [],				/**		 * Events listeners		 *		 * @type Object		 **/		listeners = {},				/**		 * Shortcuts		 *		 * @type Object		 **/		shortcuts = {},				/**		 * Buffer for copied files		 *		 * @type Array		 **/		clipboard = [],				/**		 * Copied/cuted files hashes		 * Prevent from remove its from cache.		 * Required for dispaly correct files names in error messages		 *		 * @type Object		 **/		remember = {},				/**		 * Queue for 'open' requests		 *		 * @type Array		 **/		queue = [],				/**		 * Queue for only cwd requests e.g. `tmb`		 *		 * @type Array		 **/		cwdQueue = [],				/**		 * Commands prototype		 *		 * @type Object		 **/		base = new self.command(self),				/**		 * elFinder node width		 *		 * @type String		 * @default "auto"		 **/		width  = 'auto',				/**		 * elFinder node height		 * Number: pixcel or String: Number + "%"		 *		 * @type Number | String		 * @default 400		 **/		height = 400,				/**		 * Base node object or selector		 * Element which is the reference of the height percentage		 *		 * @type Object|String		 * @default null | $(window) (if height is percentage)		 **/		heightBase = null,				/**		 * MIME type list(Associative array) handled as a text file		 * 		 * @type Object|null		 */		textMimes = null,				/**		 * elfinder path for sound played on remove		 * @type String		 * @default ./sounds/		 **/		soundPath = 'sounds/',				/**		 * JSON.stringify of previous fm.sorters		 * @type String		 */		prevSorterStr = '',		/**		 * Map table of file extention to MIME-Type		 * @type Object		 */		extToMimeTable,		beeper = $(document.createElement('audio')).hide().appendTo('body')[0],					syncInterval,		autoSyncStop = 0,				uiCmdMapPrev = '',				gcJobRes = null,				open = function(data) {			// NOTES: Do not touch data object					var volumeid, contextmenu, emptyDirs = {}, stayDirs = {},				rmClass, hashes, calc, gc, collapsed, prevcwd, sorterStr;						if (self.api >= 2.1) {				// support volume driver option `uiCmdMap`				self.commandMap = (data.options.uiCmdMap && Object.keys(data.options.uiCmdMap).length)? data.options.uiCmdMap : {};				if (uiCmdMapPrev !== JSON.stringify(self.commandMap)) {					uiCmdMapPrev = JSON.stringify(self.commandMap);				}			} else {				self.options.sync = 0;			}						if (data.init) {				// init - reset cache				files = {};				ownFiles = {};			} else {				// remove only files from prev cwd				// and collapsed directory (included 100+ directories) to empty for perfomance tune in DnD				prevcwd = cwd;				rmClass = 'elfinder-subtree-loaded ' + self.res('class', 'navexpand');				collapsed = self.res('class', 'navcollapse');				hashes = Object.keys(files);				calc = function(i) {					if (!files[i]) {						return true;					}										var isDir = (files[i].mime === 'directory'),						phash = files[i].phash,						pnav;										if (						(!isDir							|| emptyDirs[phash]							|| (!stayDirs[phash]								&& $('#'+self.navHash2Id(files[i].hash)).is(':hidden')								&& $('#'+self.navHash2Id(phash)).next('.elfinder-navbar-subtree').children().length > 100							)						)						&& (isDir || phash !== cwd)						&& ! remember[i]					) {						if (isDir && !emptyDirs[phash]) {							emptyDirs[phash] = true;							$('#'+self.navHash2Id(phash))							 .removeClass(rmClass)							 .next('.elfinder-navbar-subtree').empty();						}						deleteCache(files[i]);					} else if (isDir) {						stayDirs[phash] = true;					}				};				gc = function() {					if (hashes.length) {						gcJobRes && gcJobRes._abort();						gcJobRes = self.asyncJob(calc, hashes, {							interval : 20,							numPerOnce : 100						}).done(function() {							var hd = self.storage('hide') || {items: {}};							if (Object.keys(hiddenFiles).length) {								$.each(hiddenFiles, function(h) {									if (!hd.items[h]) {										delete hiddenFiles[h];									}								});							}						});					}				};								self.trigger('filesgc').one('filesgc', function() {					hashes = [];				});								self.one('opendone', function() {					if (prevcwd !== cwd) {						if (! node.data('lazycnt')) {							gc();						} else {							self.one('lazydone', gc);						}					}				});			}			self.sorters = {};			cwd = data.cwd.hash;			cache(data.files);			if (!files[cwd]) {				cache([data.cwd]);			}			// trigger event 'sorterupdate'			sorterStr = JSON.stringify(self.sorters);			if (prevSorterStr !== sorterStr) {				self.trigger('sorterupdate');				prevSorterStr = sorterStr;			}			self.lastDir(cwd);						self.autoSync();		},				/**		 * Store info about files/dirs in "files" object.		 *		 * @param  Array  files		 * @param  String data type		 * @return void		 **/		cache = function(data, type) {			var defsorter = { name: true, perm: true, date: true,  size: true, kind: true },				sorterChk = !self.sorters._checked,				l         = data.length,				setSorter = function(file) {					var f = file || {},						sorters = [];					$.each(self.sortRules, function(key) {						if (defsorter[key] || typeof f[key] !== 'undefined' || (key === 'mode' && typeof f.perm !== 'undefined')) {							sorters.push(key);						}					});					self.sorters = self.arrayFlip(sorters, true);					self.sorters._checked = true;				},				keeps = ['sizeInfo'],				changedParents = {},				hideData = self.storage('hide') || {},				hides = hideData.items || {},				f, i, keepProp, parents, hidden;			for (i = 0; i < l; i++) {				f = Object.assign({}, data[i]);				hidden = (!hideData.show && hides[f.hash])? true : false;				if (f.name && f.hash && f.mime) {					if (!hidden) {						if (sorterChk && f.phash === cwd) {							setSorter(f);							sorterChk = false;						}												if (f.phash && (type === 'add' || type === 'change')) {							if (parents = self.parents(f.phash)) {								$.each(parents, function() {									changedParents[this] = true;								});							}						}					}					if (files[f.hash]) {						$.each(keeps, function() {							if(files[f.hash][this] && ! f[this]) {								f[this] = files[f.hash][this];							}						});						if (f.sizeInfo && !f.size) {							f.size = f.sizeInfo.size;						}						deleteCache(files[f.hash], true);					}					if (hides[f.hash]) {						hiddenFiles[f.hash] = f;					}					if (hidden) {						l--;						data.splice(i--, 1);					} else {						files[f.hash] = f;						if (f.mime === 'directory' && !ownFiles[f.hash]) {							ownFiles[f.hash] = {};						}						if (f.phash) {							if (!ownFiles[f.phash]) {								ownFiles[f.phash] = {};							}							ownFiles[f.phash][f.hash] = true;						}					}				}			}			// delete sizeInfo cache			$.each(Object.keys(changedParents), function() {				var target = files[this];				if (target && target.sizeInfo) {					delete target.sizeInfo;				}			});						// for empty folder			sorterChk && setSorter();		},				/**		 * Delete file object from files caches		 * 		 * @param  Array  removed hashes		 * @return void		 */		remove = function(removed) {			var l       = removed.length,				roots   = {},				rm      = function(hash) {					var file = files[hash], i;					if (file) {						if (file.mime === 'directory') {							if (roots[hash]) {								delete self.roots[roots[hash]];							}							// restore stats of deleted root parent directory							$.each(self.leafRoots, function(phash, roots) {								var idx, pdir;								if ((idx = $.inArray(hash, roots))!== -1) {									if (roots.length === 1) {										if ((pdir = Object.assign({}, files[phash])) && pdir._realStats) {											$.each(pdir._realStats, function(k, v) {												pdir[k] = v;											});											remove(files[phash]._realStats);											self.change({ changed: [pdir] });										}										delete self.leafRoots[phash];									} else {										self.leafRoots[phash].splice(idx, 1);									}								}							});							if (self.searchStatus.state < 2) {								$.each(files, function(h, f) {									f.phash == hash && rm(h);								});							}						}						if (file.phash) {							if (parents = self.parents(file.phash)) {								$.each(parents, function() {									changedParents[this] = true;								});							}						}						deleteCache(files[hash]);					}				},				changedParents = {},				parents;					$.each(self.roots, function(k, v) {				roots[v] = k;			});			while (l--) {				rm(removed[l]);			}			// delete sizeInfo cache			$.each(Object.keys(changedParents), function() {				var target = files[this];				if (target && target.sizeInfo) {					delete target.sizeInfo;				}			});		},				/**		 * Update file object in files caches		 * 		 * @param  Array  changed file objects		 * @return void		 */		change = function(changed) {			$.each(changed, function(i, file) {				var hash = file.hash;				if (files[hash]) {					$.each(Object.keys(files[hash]), function(i, v){						if (typeof file[v] === 'undefined') {							delete files[hash][v];						}					});				}				files[hash] = files[hash] ? Object.assign(files[hash], file) : file;			});		},				/**		 * Delete cache data of files, ownFiles and self.optionsByHashes		 * 		 * @param  Object  file		 * @param  Boolean update		 * @return void		 */		deleteCache = function(file, update) {			var hash = file.hash,				phash = file.phash;						if (phash && ownFiles[phash]) {				 delete ownFiles[phash][hash];			}			if (!update) {				ownFiles[hash] && delete ownFiles[hash];				self.optionsByHashes[hash] && delete self.optionsByHashes[hash];			}			delete files[hash];		},				/**		 * Maximum number of concurrent connections on request		 * 		 * @type Number		 */		requestMaxConn,				/**		 * Current number of connections		 * 		 * @type Number		 */		requestCnt = 0,				/**		 * Queue waiting for connection		 * 		 * @type Array		 */		requestQueue = [],				/**		 * Flag to cancel the `open` command waiting for connection		 * 		 * @type Boolean		 */		requestQueueSkipOpen = false,				/**		 * Exec shortcut		 *		 * @param  jQuery.Event  keydown/keypress event		 * @return void		 */		execShortcut = function(e) {			var code    = e.keyCode,				ctrlKey = !!(e.ctrlKey || e.metaKey),				isMousedown = e.type === 'mousedown',				ddm;			!isMousedown && (self.keyState.keyCode = code);			self.keyState.ctrlKey  = ctrlKey;			self.keyState.shiftKey = e.shiftKey;			self.keyState.metaKey  = e.metaKey;			self.keyState.altKey   = e.altKey;			if (isMousedown) {				return;			} else if (e.type === 'keyup') {				self.keyState.keyCode = null;				return;			}			if (enabled) {				$.each(shortcuts, function(i, shortcut) {					if (shortcut.type    == e.type 					&& shortcut.keyCode  == code 					&& shortcut.shiftKey == e.shiftKey 					&& shortcut.ctrlKey  == ctrlKey 					&& shortcut.altKey   == e.altKey) {						e.preventDefault();						e.stopPropagation();						shortcut.callback(e, self);						self.debug('shortcut-exec', i+' : '+shortcut.description);					}				});								// prevent tab out of elfinder				if (code == $.ui.keyCode.TAB && !$(e.target).is(':input')) {					e.preventDefault();				}								// cancel any actions by [Esc] key				if (e.type === 'keydown' && code == $.ui.keyCode.ESCAPE) {					// copy or cut 					if (! node.find('.ui-widget:visible').length) {						self.clipboard().length && self.clipboard([]);					}					// dragging					if ($.ui.ddmanager) {						ddm = $.ui.ddmanager.current;						ddm && ddm.helper && ddm.cancel();					}					// button menus					self.toHide(node.find('.ui-widget.elfinder-button-menu.elfinder-frontmost:visible'));					// trigger keydownEsc					self.trigger('keydownEsc', e);				}			}		},		date = new Date(),		utc,		i18n,		inFrame = (window.parent !== window),		parentIframe = (function() {			var pifm, ifms;			if (inFrame) {				try {					ifms = $('iframe', window.parent.document);					if (ifms.length) {						$.each(ifms, function(i, ifm) {							if (ifm.contentWindow === window) {								pifm = $(ifm);								return false;							}						});					}				} catch(e) {}			}			return pifm;		})(),		/**		 * elFinder boot up function		 * 		 * @type Function		 */		bootUp,		/**		 * Original function of XMLHttpRequest.prototype.send		 * 		 * @type Function		 */		savedXhrSend;		// opts must be an object	if (!opts) {		opts = {};	}		// set UA.Angle, UA.Rotated for mobile devices	if (self.UA.Mobile) {		$(window).on('orientationchange.'+namespace, function() {			var a = ((screen && screen.orientation && screen.orientation.angle) || window.orientation || 0) + 0;			if (a === -90) {				a = 270;			}			self.UA.Angle = a;			self.UA.Rotated = a % 180 === 0? false : true;		}).trigger('orientationchange.'+namespace);	}		// check opt.bootCallback	if (opts.bootCallback && typeof opts.bootCallback === 'function') {		(function() {			var func = bootCallback,				opFunc = opts.bootCallback;			bootCallback = function(fm, extraObj) {				func && typeof func === 'function' && func.call(this, fm, extraObj);				opFunc.call(this, fm, extraObj);			};		})();	}	delete opts.bootCallback;	/**	 * Protocol version	 *	 * @type String	 **/	this.api = null;		/**	 * elFinder use new api	 *	 * @type Boolean	 **/	this.newAPI = false;		/**	 * elFinder use old api	 *	 * @type Boolean	 **/	this.oldAPI = false;		/**	 * Net drivers names	 *	 * @type Array	 **/	this.netDrivers = [];		/**	 * Base URL of elfFinder library starting from Manager HTML	 * 	 * @type String	 */	this.baseUrl = '';		/**	 * Base URL of i18n js files	 * baseUrl + "js/i18n/" when empty value	 * 	 * @type String	 */	this.i18nBaseUrl = '';	/**	 * Is elFinder CSS loaded	 * 	 * @type Boolean	 */	this.cssloaded = false;		/**	 * Current theme object	 * 	 * @type Object|Null	 */	this.theme = null;	this.mimesCanMakeEmpty = {};	/**	 * Callback function at boot up that option specified at elFinder starting	 * 	 * @type Function	 */	this.bootCallback;	/**	 * ID. Required to create unique cookie name	 *	 * @type String	 **/	this.id = id;	/**	 * Method to store/fetch data	 *	 * @type Function	 **/	this.storage = (function() {		try {			if ('localStorage' in window && window['localStorage'] !== null) {				if (self.UA.Safari) {					// check for Mac/iOS safari private browsing mode					window.localStorage.setItem('elfstoragecheck', 1);					window.localStorage.removeItem('elfstoragecheck');				}				return self.localStorage;			} else {				return self.cookie;			}		} catch (e) {			return self.cookie;		}	})();	/**	 * Configuration options	 *	 * @type Object	 **/	//this.options = $.extend(true, {}, this._options, opts);	this.options = Object.assign({}, this._options);		// for old type configuration	if (opts.uiOptions) {		if (opts.uiOptions.toolbar && Array.isArray(opts.uiOptions.toolbar)) {			if ($.isPlainObject(opts.uiOptions.toolbar[opts.uiOptions.toolbar.length - 1])) {				self.options.uiOptions.toolbarExtra = Object.assign(self.options.uiOptions.toolbarExtra || {}, opts.uiOptions.toolbar.pop());			}		}	}		// Overwrite if opts value is an array	(function() {		var arrOv = function(obj, base) {			if ($.isPlainObject(obj)) {				$.each(obj, function(k, v) {					if ($.isPlainObject(v)) {						if (!base[k]) {							base[k] = {};						}						arrOv(v, base[k]);					} else {						base[k] = v;					}				});			}		};		arrOv(opts, self.options);	})();		// join toolbarExtra to toolbar	this.options.uiOptions.toolbar.push(this.options.uiOptions.toolbarExtra);	delete this.options.uiOptions.toolbarExtra;		// set fm.baseUrl	this.baseUrl = (function() {		var myTag, myCss, base, baseUrl;				if (self.options.baseUrl) {			return self.options.baseUrl;		} else {			baseUrl = '';			//myTag = $('head > script[src$="js/elfinder.min.js"],script[src$="js/elfinder.full.js"]:first');			myTag = null;			$('head > script').each(function() {				if (this.src && this.src.match(/js\/elfinder(?:-[a-z0-9_-]+)?\.(?:min|full)\.js$/i)) {					myTag = $(this);					return false;				}			});			if (myTag) {				myCss = $('head > link[href$="css/elfinder.min.css"],link[href$="css/elfinder.full.css"]:first').length;				if (! myCss) {					// to request CSS auto loading					self.cssloaded = null;				}				baseUrl = myTag.attr('src').replace(/js\/[^\/]+$/, '');				if (! baseUrl.match(/^(https?\/\/|\/)/)) {					// check <base> tag					if (base = $('head > base[href]').attr('href')) {						baseUrl = base.replace(/\/$/, '') + '/' + baseUrl; 					}				}			}			if (baseUrl !== '') {				self.options.baseUrl = baseUrl;			} else {				if (! self.options.baseUrl) {					self.options.baseUrl = './';				}				baseUrl = self.options.baseUrl;			}			return baseUrl;		}	})();		this.i18nBaseUrl = (this.options.i18nBaseUrl || this.baseUrl + 'js/i18n').replace(/\/$/, '') + '/';	// set dispInlineRegex	cwdOptionsDefault['dispInlineRegex'] = this.options.dispInlineRegex;		// auto load required CSS	if (this.options.cssAutoLoad) {		(function() {			var baseUrl = self.baseUrl;						if (self.cssloaded === null) {				// hide elFinder node while css loading				node.data('cssautoloadHide', $('<style>.elfinder{visibility:hidden;overflow:hidden}</style>'));				$('head').append(node.data('cssautoloadHide'));								// load CSS				self.loadCss([baseUrl+'css/elfinder.min.css', baseUrl+'css/theme.css'], {					dfd: $.Deferred().always(function() {						if (node.data('cssautoloadHide')) {							node.data('cssautoloadHide').remove();							node.removeData('cssautoloadHide');						}					}).done(function() {						if (!self.cssloaded) {							self.cssloaded = true;							self.trigger('cssloaded');						}					}).fail(function() {						self.cssloaded = false;						self.error(['errRead', 'CSS (elfinder or theme)']);					})				});								// additional CSS files				if (Array.isArray(self.options.cssAutoLoad)) {					self.loadCss(self.options.cssAutoLoad);				}			}			self.options.cssAutoLoad = false;		})();	}	// load theme if exists	self.changeTheme(self.storage('theme') || self.options.theme);		/**	 * Volume option to set the properties of the root Stat	 * 	 * @type Object	 */	this.optionProperties = {		icon: void(0),		csscls: void(0),		tmbUrl: void(0),		uiCmdMap: {},		netkey: void(0),		disabled: []	};		if (! inFrame && ! this.options.enableAlways && $('body').children().length === 2) { // only node and beeper		this.options.enableAlways = true;	}		// make options.debug	if (this.options.debug === true) {		this.options.debug = 'all';	} else if (Array.isArray(this.options.debug)) {		(function() {			var d = {};			$.each(self.options.debug, function() {				d[this] = true;			});			self.options.debug = d;		})();	} else {		this.options.debug = false;	}		/**	 * Original functions evacuated by conflict check	 * 	 * @type Object	 */	this.noConflicts = {};		/**	 * Check and save conflicts with bootstrap etc	 * 	 * @type Function	 */	this.noConflict = function() {		$.each(conflictChecks, function(i, p) {			if ($.fn[p] && typeof $.fn[p].noConflict === 'function') {				self.noConflicts[p] = $.fn[p].noConflict();			}		});	};	// do check conflict	this.noConflict();		/**	 * Is elFinder over CORS	 *	 * @type Boolean	 **/	this.isCORS = false;		// configure for CORS	(function(){		if (typeof self.options.cors !== 'undefined' && self.options.cors !== null) {			self.isCORS = self.options.cors? true : false;		} else {			var parseUrl = document.createElement('a'),				parseUploadUrl,				selfProtocol = window.location.protocol,				portReg = function(protocol) {					protocol = (!protocol || protocol === ':')? selfProtocol : protocol;					return protocol === 'https:'? /\:443$/ : /\:80$/;				},				selfHost = window.location.host.replace(portReg(selfProtocol), '');			parseUrl.href = opts.url;			if (opts.urlUpload && (opts.urlUpload !== opts.url)) {				parseUploadUrl = document.createElement('a');				parseUploadUrl.href = opts.urlUpload;			}			if (selfHost !== parseUrl.host.replace(portReg(parseUrl.protocol), '')				|| (parseUrl.protocol !== ':'&& parseUrl.protocol !== '' && (selfProtocol !== parseUrl.protocol))				|| (parseUploadUrl && 					(selfHost !== parseUploadUrl.host.replace(portReg(parseUploadUrl.protocol), '')					|| (parseUploadUrl.protocol !== ':' && parseUploadUrl.protocol !== '' && (selfProtocol !== parseUploadUrl.protocol))					)				)			) {				self.isCORS = true;			}		}		if (self.isCORS) {			if (!$.isPlainObject(self.options.customHeaders)) {				self.options.customHeaders = {};			}			if (!$.isPlainObject(self.options.xhrFields)) {				self.options.xhrFields = {};			}			self.options.requestType = 'post';			self.options.customHeaders['X-Requested-With'] = 'XMLHttpRequest';			self.options.xhrFields['withCredentials'] = true;		}	})();	/**	 * Ajax request type	 *	 * @type String	 * @default "get"	 **/	this.requestType = /^(get|post)$/i.test(this.options.requestType) ? this.options.requestType.toLowerCase() : 'get';		// set `requestMaxConn` by option	requestMaxConn = Math.max(parseInt(this.options.requestMaxConn), 1);		/**	 * Custom data that given as options	 * 	 * @type Object	 * @default {}	 */	this.optsCustomData = $.isPlainObject(this.options.customData) ? this.options.customData : {};	/**	 * Any data to send across every ajax request	 *	 * @type Object	 * @default {}	 **/	this.customData = Object.assign({}, this.optsCustomData);	/**	 * Previous custom data from connector	 * 	 * @type Object|null	 */	this.prevCustomData = null;	/**	 * Any custom headers to send across every ajax request	 *	 * @type Object	 * @default {}	*/	this.customHeaders = $.isPlainObject(this.options.customHeaders) ? this.options.customHeaders : {};	/**	 * Any custom xhrFields to send across every ajax request	 *	 * @type Object	 * @default {}	 */	this.xhrFields = $.isPlainObject(this.options.xhrFields) ? this.options.xhrFields : {};	/**	 * Replace XMLHttpRequest.prototype.send to extended function for 3rd party libs XHR request etc.	 * 	 * @type Function	 */	this.replaceXhrSend = function() {		if (! savedXhrSend) {			savedXhrSend = XMLHttpRequest.prototype.send;		}		XMLHttpRequest.prototype.send = function() {			var xhr = this;			// set request headers			if (self.customHeaders) {				$.each(self.customHeaders, function(key) {					xhr.setRequestHeader(key, this);				});			}			// set xhrFields			if (self.xhrFields) {				$.each(self.xhrFields, function(key) {					if (key in xhr) {						xhr[key] = this;					}				});			}			return savedXhrSend.apply(this, arguments);		};	};		/**	 * Restore saved original XMLHttpRequest.prototype.send	 * 	 * @type Function	 */	this.restoreXhrSend = function() {		savedXhrSend && (XMLHttpRequest.prototype.send = savedXhrSend);	};	/**	 * command names for into queue for only cwd requests	 * these commands aborts before `open` request	 *	 * @type Array	 * @default ['tmb', 'parents']	 */	this.abortCmdsOnOpen = this.options.abortCmdsOnOpen || ['tmb', 'parents'];	/**	 * ui.nav id prefix	 * 	 * @type String	 */	this.navPrefix = 'nav' + (elFinder.prototype.uniqueid? elFinder.prototype.uniqueid : '') + '-';		/**	 * ui.cwd id prefix	 * 	 * @type String	 */	this.cwdPrefix = elFinder.prototype.uniqueid? ('cwd' + elFinder.prototype.uniqueid + '-') : '';		// Increment elFinder.prototype.uniqueid	++elFinder.prototype.uniqueid;		/**	 * URL to upload files	 *	 * @type String	 **/	this.uploadURL = opts.urlUpload || opts.url;		/**	 * Events namespace	 *	 * @type String	 **/	this.namespace = namespace;	/**	 * Today timestamp	 *	 * @type Number	 **/	this.today = (new Date(date.getFullYear(), date.getMonth(), date.getDate())).getTime()/1000;		/**	 * Yesterday timestamp	 *	 * @type Number	 **/	this.yesterday = this.today - 86400;		utc = this.options.UTCDate ? 'UTC' : '';		this.getHours    = 'get'+utc+'Hours';	this.getMinutes  = 'get'+utc+'Minutes';	this.getSeconds  = 'get'+utc+'Seconds';	this.getDate     = 'get'+utc+'Date';	this.getDay      = 'get'+utc+'Day';	this.getMonth    = 'get'+utc+'Month';	this.getFullYear = 'get'+utc+'FullYear';		/**	 * elFinder node z-index (auto detect on elFinder load)	 *	 * @type null | Number	 **/	this.zIndex;	/**	 * Current search status	 * 	 * @type Object	 */	this.searchStatus = {		state  : 0, // 0: search ended, 1: search started, 2: in search result		query  : '',		target : '',		mime   : '',		mixed  : false, // in multi volumes search: false or Array that target volume ids		ininc  : false // in incremental search	};	/**	 * Interface language	 *	 * @type String	 * @default "en"	 **/	this.lang = this.storage('lang') || this.options.lang;	if (this.lang === 'jp') {		this.lang = this.options.lang = 'ja';	}	this.viewType = this.storage('view') || this.options.defaultView || 'icons';	this.sortType = this.storage('sortType') || this.options.sortType || 'name';		this.sortOrder = this.storage('sortOrder') || this.options.sortOrder || 'asc';	this.sortStickFolders = this.storage('sortStickFolders');	if (this.sortStickFolders === null) {		this.sortStickFolders = !!this.options.sortStickFolders;	} else {		this.sortStickFolders = !!this.sortStickFolders;	}	this.sortAlsoTreeview = this.storage('sortAlsoTreeview');	if (this.sortAlsoTreeview === null) {		this.sortAlsoTreeview = !!this.options.sortAlsoTreeview;	} else {		this.sortAlsoTreeview = !!this.sortAlsoTreeview;	}	this.sortRules = $.extend(true, {}, this._sortRules, this.options.sortRules);		$.each(this.sortRules, function(name, method) {		if (typeof method != 'function') {			delete self.sortRules[name];		} 	});		this.compare = $.proxy(this.compare, this);		/**	 * Delay in ms before open notification dialog	 *	 * @type Number	 * @default 500	 **/	this.notifyDelay = this.options.notifyDelay > 0 ? parseInt(this.options.notifyDelay) : 500;		/**	 * Dragging UI Helper object	 *	 * @type jQuery | null	 **/	this.draggingUiHelper = null;		/**	 * Base droppable options	 *	 * @type Object	 **/	this.droppable = {		greedy     : true,		tolerance  : 'pointer',		accept     : '.elfinder-cwd-file-wrapper,.elfinder-navbar-dir,.elfinder-cwd-file,.elfinder-cwd-filename',		hoverClass : this.res('class', 'adroppable'),		classes    : { // Deprecated hoverClass jQueryUI>=1.12.0			'ui-droppable-hover': this.res('class', 'adroppable')		},		autoDisable: true, // elFinder original, see jquery.elfinder.js		drop : function(e, ui) {			var dst     = $(this),				targets = $.grep(ui.helper.data('files')||[], function(h) { return h? true : false; }),				result  = [],				dups    = [],				faults  = [],				isCopy  = ui.helper.hasClass('elfinder-drag-helper-plus'),				c       = 'class',				cnt, hash, i, h;						if (typeof e.button === 'undefined' || ui.helper.data('namespace') !== namespace || ! self.insideWorkzone(e.pageX, e.pageY)) {				return false;			}			if (dst.hasClass(self.res(c, 'cwdfile'))) {				hash = self.cwdId2Hash(dst.attr('id'));			} else if (dst.hasClass(self.res(c, 'navdir'))) {				hash = self.navId2Hash(dst.attr('id'));			} else {				hash = cwd;			}			cnt = targets.length;						while (cnt--) {				h = targets[cnt];				// ignore drop into itself or in own location				if (h != hash && files[h].phash != hash) {					result.push(h);				} else {					((isCopy && h !== hash && files[hash].write)? dups : faults).push(h);				}			}						if (faults.length) {				return false;			}						ui.helper.data('droped', true);						if (dups.length) {				ui.helper.hide();				self.exec('duplicate', dups, {_userAction: true});			}						if (result.length) {				ui.helper.hide();				self.clipboard(result, !isCopy);				self.exec('paste', hash, {_userAction: true}, hash).always(function(){					self.clipboard([]);					self.trigger('unlockfiles', {files : targets});				});				self.trigger('drop', {files : targets});			}		}	};		/**	 * Return true if filemanager is active	 *	 * @return Boolean	 **/	this.enabled = function() {		return enabled && this.visible();	};		/**	 * Return true if filemanager is visible	 *	 * @return Boolean	 **/	this.visible = function() {		return node[0].elfinder && node.is(':visible');	};		/**	 * Return file is root?	 * 	 * @param  Object  target file object	 * @return Boolean	 */	this.isRoot = function(file) {		return (file.isroot || ! file.phash)? true : false;	};		/**	 * Return root dir hash for current working directory	 * 	 * @param  String   target hash	 * @param  Boolean  include fake parent (optional)	 * @return String	 */	this.root = function(hash, fake) {		hash = hash || cwd;		var dir, i;				if (! fake) {			$.each(self.roots, function(id, rhash) {				if (hash.indexOf(id) === 0) {					dir = rhash;					return false;				}			});			if (dir) {				return dir;			}		}				dir = files[hash];		while (dir && dir.phash && (fake || ! dir.isroot)) {			dir = files[dir.phash];		}		if (dir) {			return dir.hash;		}				while (i in files && files.hasOwnProperty(i)) {			dir = files[i];			if (dir.mime === 'directory' && !dir.phash && dir.read) {				return dir.hash;			}		}				return '';	};		/**	 * Return current working directory info	 * 	 * @return Object	 */	this.cwd = function() {		return files[cwd] || {};	};		/**	 * Return required cwd option	 * 	 * @param  String  option name	 * @param  String  target hash (optional)	 * @return mixed	 */	this.option = function(name, target) {		var res, item;		target = target || cwd;		if (self.optionsByHashes[target] && typeof self.optionsByHashes[target][name] !== 'undefined') {			return self.optionsByHashes[target][name];		}		if (self.hasVolOptions && cwd !== target && (!(item = self.file(target)) || item.phash !== cwd)) {			res = '';			$.each(self.volOptions, function(id, opt) {				if (target.indexOf(id) === 0) {					res = opt[name] || '';					return false;				}			});			return res;		} else {			return cwdOptions[name] || '';		}	};		/**	 * Return disabled commands by each folder	 * 	 * @param  Array  target hashes	 * @return Array	 */	this.getDisabledCmds = function(targets, flip) {		var disabled = {'hidden': true};		if (! Array.isArray(targets)) {			targets = [ targets ];		}		$.each(targets, function(i, h) {			var disCmds = self.option('disabledFlip', h);			if (disCmds) {				Object.assign(disabled, disCmds);			}		});		return flip? disabled : Object.keys(disabled);	};		/**	 * Return file data from current dir or tree by it's hash	 * 	 * @param  String  file hash	 * @return Object	 */	this.file = function(hash, alsoHidden) { 		return hash? (files[hash] || (alsoHidden? hiddenFiles[hash] : void(0))) : void(0); 	};		/**	 * Return all cached files	 * 	 * @param  String  parent hash	 * @return Object	 */	this.files = function(phash) {		var items = {};		if (phash) {			if (!ownFiles[phash]) {				return {};			}			$.each(ownFiles[phash], function(h) {				if (files[h]) {					items[h] = files[h];				} else {					delete ownFiles[phash][h];				}			});			return Object.assign({}, items);		}		return Object.assign({}, files);	};		/**	 * Return list of file parents hashes include file hash	 * 	 * @param  String  file hash	 * @return Array	 */	this.parents = function(hash) {		var parents = [],			dir;				while (hash && (dir = this.file(hash))) {			parents.unshift(dir.hash);			hash = dir.phash;		}		return parents;	};		this.path2array = function(hash, i18) {		var file, 			path = [];					while (hash) {			if ((file = files[hash]) && file.hash) {				path.unshift(i18 && file.i18 ? file.i18 : file.name);				hash = file.isroot? null : file.phash;			} else {				path = [];				break;			}		}					return path;	};		/**	 * Return file path or Get path async with jQuery.Deferred	 * 	 * @param  Object  file	 * @param  Boolean i18	 * @param  Object  asyncOpt	 * @return String|jQuery.Deferred	 */	this.path = function(hash, i18, asyncOpt) { 		var path = files[hash] && files[hash].path			? files[hash].path			: this.path2array(hash, i18).join(cwdOptions.separator);		if (! asyncOpt || ! files[hash]) {			return path;		} else {			asyncOpt = Object.assign({notify: {type : 'parents', cnt : 1, hideCnt : true}}, asyncOpt);						var dfd    = $.Deferred(),				notify = asyncOpt.notify,				noreq  = false,				req    = function() {					self.request({						data : {cmd : 'parents', target : files[hash].phash},						notify : notify,						preventFail : true					})					.done(done)					.fail(function() {						dfd.reject();					});				},				done   = function() {					self.one('parentsdone', function() {						path = self.path(hash, i18);						if (path === '' && noreq) {							//retry with request							noreq = false;							req();						} else {							if (notify) {								clearTimeout(ntftm);								notify.cnt = -(parseInt(notify.cnt || 0));								self.notify(notify);							}							dfd.resolve(path);						}					});				},				ntftm;					if (path) {				return dfd.resolve(path);			} else {				if (self.ui['tree']) {					// try as no request					if (notify) {						ntftm = setTimeout(function() {							self.notify(notify);						}, self.notifyDelay);					}					noreq = true;					done(true);				} else {					req();				}				return dfd;			}		}	};		/**	 * Return file url if set	 * 	 * @param  String  file hash	 * @param  Object  Options	 * @return String	 */	this.url = function(hash, o) {		var file   = files[hash],			opts   = o || {},			async  = opts.async || false,			temp   = opts.temporary || false,			dfrd   = async? $.Deferred() : null,			getUrl = function(url) {				if (url) {					return url;				}				if (file.url) {					return file.url;				}								if (typeof baseUrl === 'undefined') {					baseUrl = self.option('url', (!self.isRoot(file) && file.phash) || file.hash);				}								if (baseUrl) {					return baseUrl + $.map(self.path2array(hash), function(n) { return encodeURIComponent(n); }).slice(1).join('/');				}				var params = Object.assign({}, self.customData, {					cmd: 'file',					target: file.hash				});				if (self.oldAPI) {					params.cmd = 'open';					params.current = file.phash;				}				return self.options.url + (self.options.url.indexOf('?') === -1 ? '?' : '&') + $.param(params, true);			}, 			baseUrl, res;				if (!file || !file.read) {			return async? dfrd.resolve('') : '';		}				if (file.url == '1' || (temp && !file.url && !(baseUrl = self.option('url', (!self.isRoot(file) && file.phash) || file.hash)))) {			this.request({				data : { cmd : 'url', target : hash, options : { temporary: temp? 1 : 0 } },				preventDefault : true,				options: {async: async},				notify: async? {type : temp? 'file' : 'url', cnt : 1, hideCnt : true} : {}			})			.done(function(data) {				file.url = data.url || '';			})			.fail(function() {				file.url = '';			})			.always(function() {				var url;				if (file.url && temp) {					url = file.url;					file.url = '1'; // restore				}				if (async) {					dfrd.resolve(getUrl(url));				} else {					return getUrl(url);				}			});		} else {			if (async) {				dfrd.resolve(getUrl());			} else {				return getUrl();			}		}				if (async) {			return dfrd;		}	};		/**	 * Return file url for open in elFinder	 * 	 * @param  String  file hash	 * @param  Boolean for download link	 * @return String	 */	this.openUrl = function(hash, download) {		var file = files[hash],			url  = '';				if (!file || !file.read) {			return '';		}				if (!download) {			if (file.url) {				if (file.url != 1) {					url = file.url;				}			} else if (cwdOptions.url && file.hash.indexOf(self.cwd().volumeid) === 0) {				url = cwdOptions.url + $.map(this.path2array(hash), function(n) { return encodeURIComponent(n); }).slice(1).join('/');			}			if (url) {				url += (url.match(/\?/)? '&' : '?') + '_'.repeat((url.match(/[\?&](_+)t=/g) || ['&t=']).sort().shift().match(/[\?&](_*)t=/)[1].length + 1) + 't=' + (file.ts || parseInt(+new Date()/1000));				return url;			}		}				url = this.options.url;		url = url + (url.indexOf('?') === -1 ? '?' : '&')			+ (this.oldAPI ? 'cmd=open¤t='+file.phash : 'cmd=file')			+ '&target=' + file.hash			+ '&_t=' + (file.ts || parseInt(+new Date()/1000));				if (download) {			url += '&download=1';		}				$.each(this.customData, function(key, val) {			url += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(val);		});				return url;	};		/**	 * Return thumbnail url	 * 	 * @param  Object  file object	 * @return String	 */	this.tmb = function(file) {		var tmbUrl, tmbCrop,			cls    = 'elfinder-cwd-bgurl',			url    = '';		if ($.isPlainObject(file)) {			if (self.searchStatus.state && file.hash.indexOf(self.cwd().volumeid) !== 0) {				tmbUrl = self.option('tmbUrl', file.hash);				tmbCrop = self.option('tmbCrop', file.hash);			} else {				tmbUrl = cwdOptions['tmbUrl'];				tmbCrop = cwdOptions['tmbCrop'];			}			if (tmbCrop) {				cls += ' elfinder-cwd-bgurl-crop';			}			if (tmbUrl === 'self' && file.mime.indexOf('image/') === 0) {				url = self.openUrl(file.hash);				cls += ' elfinder-cwd-bgself';			} else if ((self.oldAPI || tmbUrl) && file && file.tmb && file.tmb != 1) {				url = tmbUrl + file.tmb;			} else if (self.newAPI && file && file.tmb && file.tmb != 1) {				url = file.tmb;			}			if (url) {				if (file.ts && tmbUrl !== 'self') {					url += (url.match(/\?/)? '&' : '?') + '_t=' + file.ts;				}				return { url: url, className: cls };			}		}				return false;	};		/**	 * Return selected files hashes	 *	 * @return Array	 **/	this.selected = function() {		return selected.slice(0);	};		/**	 * Return selected files info	 * 	 * @return Array	 */	this.selectedFiles = function() {		return $.map(selected, function(hash) { return files[hash] ? Object.assign({}, files[hash]) : null; });	};		/**	 * Return true if file with required name existsin required folder	 * 	 * @param  String  file name	 * @param  String  parent folder hash	 * @return Boolean	 */	this.fileByName = function(name, phash) {		var hash;			for (hash in files) {			if (files.hasOwnProperty(hash) && files[hash].phash == phash && files[hash].name == name) {				return files[hash];			}		}	};		/**	 * Valid data for required command based on rules	 * 	 * @param  String  command name	 * @param  Object  cammand's data	 * @return Boolean	 */	this.validResponse = function(cmd, data) {		return data.error || this.rules[this.rules[cmd] ? cmd : 'defaults'](data);	};		/**	 * Return bytes from ini formated size	 * 	 * @param  String  ini formated size	 * @return Integer	 */	this.returnBytes = function(val) {		var last;		if (isNaN(val)) {			if (! val) {				val = '';			}			// for ex. 1mb, 1KB			val = val.replace(/b$/i, '');			last = val.charAt(val.length - 1).toLowerCase();			val = val.replace(/[tgmk]$/i, '');			if (last == 't') {				val = val * 1024 * 1024 * 1024 * 1024;			} else if (last == 'g') {				val = val * 1024 * 1024 * 1024;			} else if (last == 'm') {				val = val * 1024 * 1024;			} else if (last == 'k') {				val = val * 1024;			}			val = isNaN(val)? 0 : parseInt(val);		} else {			val = parseInt(val);			if (val < 1) val = 0;		}		return val;	};		/**	 * Process ajax request.	 * Fired events :	 * @todo	 * @example	 * @todo	 * @return $.Deferred	 */	this.request = function(opts) { 		var self     = this,			o        = this.options,			dfrd     = $.Deferred(),			// request ID			reqId    = (+ new Date()).toString(16) + Math.floor(1000 * Math.random()).toString(16), 			// request data			data     = Object.assign({}, self.customData, {mimes : o.onlyMimes}, opts.data || opts),			// command name			cmd      = data.cmd,			// request type is binary			isBinary = (opts.options || {}).dataType === 'binary',			// current cmd is "open"			isOpen   = (!opts.asNotOpen && cmd === 'open'),			// call default fail callback (display error dialog) ?			deffail  = !(isBinary || opts.preventDefault || opts.preventFail),			// call default success callback ?			defdone  = !(isBinary || opts.preventDefault || opts.preventDone),			// options for notify dialog			notify   = Object.assign({}, opts.notify),			// make cancel button			cancel   = !!opts.cancel,			// do not normalize data - return as is			raw      = isBinary || !!opts.raw,			// sync files on request fail			syncOnFail = opts.syncOnFail,			// use lazy()			lazy     = !!opts.lazy,			// prepare function before done()			prepare  = opts.prepare,			// navigate option object when cmd done			navigate = opts.navigate,			// open notify dialog timeout			timeout,			// use browser cache			useCache = (opts.options || {}).cache,			// request options			options = Object.assign({				url      : o.url,				async    : true,				type     : this.requestType,				dataType : 'json',				cache    : (self.api >= 2.1029), // api >= 2.1029 has unique request ID				data     : data,				headers  : this.customHeaders,				xhrFields: this.xhrFields			}, opts.options || {}),			/**			 * Default success handler. 			 * Call default data handlers and fire event with command name.			 *			 * @param Object  normalized response data			 * @return void			 **/			done = function(data) {				data.warning && self.error(data.warning);								if (isOpen) {					open(data);				} else {					self.updateCache(data);				}								data.changed && data.changed.length && change(data.changed);								self.lazy(function() {					// fire some event to update cache/ui					data.removed && data.removed.length && self.remove(data);					data.added   && data.added.length   && self.add(data);					data.changed && data.changed.length && self.change(data);				}).then(function() {					// fire event with command name					return self.lazy(function() {						self.trigger(cmd, data, false);					});				}).then(function() {					// fire event with command name + 'done'					return self.lazy(function() {						self.trigger(cmd + 'done');					});				}).then(function() {					// make toast message					if (data.toasts && Array.isArray(data.toasts)) {						$.each(data.toasts, function() {							this.msg && self.toast(this);						});					}					// force update content					data.sync && self.sync();				});			},			/**			 * Request error handler. Reject dfrd with correct error message.			 *			 * @param jqxhr  request object			 * @param String request status			 * @return void			 **/			error = function(xhr, status) {				var error, data, 					d = self.options.debug;								switch (status) {					case 'abort':						error = xhr.quiet ? '' : ['errConnect', 'errAbort'];						break;					case 'timeout':	    						error = ['errConnect', 'errTimeout'];						break;					case 'parsererror': 						error = ['errResponse', 'errDataNotJSON'];						if (xhr.responseText) {							if (! cwd || (d && (d === 'all' || d['backend-error']))) {								error.push(xhr.responseText);							}						}						break;					default:						if (xhr.responseText) {							// check responseText, Is that JSON?							try {								data = JSON.parse(xhr.responseText);								if (data && data.error) {									error = data.error;								}							} catch(e) {}						}						if (! error) {							if (xhr.status == 403) {								error = ['errConnect', 'errAccess', 'HTTP error ' + xhr.status];							} else if (xhr.status == 404) {								error = ['errConnect', 'errNotFound', 'HTTP error ' + xhr.status];							} else if (xhr.status >= 500) {								error = ['errResponse', 'errServerError', 'HTTP error ' + xhr.status];							} else {								if (xhr.status == 414 && options.type === 'get') {									// retry by POST method									options.type = 'post';									self.abortXHR(xhr);									dfrd.xhr = xhr = self.transport.send(options).fail(error).done(success);									return;								}								error = xhr.quiet ? '' : ['errConnect', 'HTTP error ' + xhr.status];							} 						}				}								self.trigger(cmd + 'done');				dfrd.reject({error: error}, xhr, status);			},			/**			 * Request success handler. Valid response data and reject/resolve dfrd.			 *			 * @param Object  response data			 * @param String request status			 * @return void			 **/			success = function(response) {				var d = self.options.debug;								// Set currrent request command name				self.currentReqCmd = cmd;								if (response.debug && (!d || d !== 'all')) {					if (!d) {						d = self.options.debug = {};					}					d['backend-error'] = true;					d['warning'] = true;				}								if (raw) {					self.abortXHR(xhr);					response && response.debug && self.debug('backend-debug', response);					return dfrd.resolve(response);				}								if (!response) {					return dfrd.reject({error :['errResponse', 'errDataEmpty']}, xhr, response);				} else if (!$.isPlainObject(response)) {					return dfrd.reject({error :['errResponse', 'errDataNotJSON']}, xhr, response);				} else if (response.error) {					if (isOpen) {						// check leafRoots						$.each(self.leafRoots, function(phash, roots) {							self.leafRoots[phash] = $.grep(roots, function(h) { return h !== data.target; });						});					}					return dfrd.reject({error :response.error}, xhr, response);				}								var resolve = function() {					var pushLeafRoots = function(name) {						if (self.leafRoots[data.target] && response[name]) {							$.each(self.leafRoots[data.target], function(i, h) {								var root;								if (root = self.file(h)) {									response[name].push(root);								}							});						}					},					setTextMimes = function() {						self.textMimes = {};						$.each(self.res('mimes', 'text'), function() {							self.textMimes[this.toLowerCase()] = true;						});					},					actionTarget;										if (isOpen) {						pushLeafRoots('files');					} else if (cmd === 'tree') {						pushLeafRoots('tree');					}										response = self.normalize(response);										if (!self.validResponse(cmd, response)) {						return dfrd.reject({error :(response.norError || 'errResponse')}, xhr, response);					}										if (isOpen) {						if (!self.api) {							self.api    = response.api || 1;							if (self.api == '2.0' && typeof response.options.uploadMaxSize !== 'undefined') {								self.api = '2.1';							}							self.newAPI = self.api >= 2;							self.oldAPI = !self.newAPI;						}												if (response.textMimes && Array.isArray(response.textMimes)) {							self.resources.mimes.text = response.textMimes;							setTextMimes();						}						!self.textMimes && setTextMimes();												if (response.options) {							cwdOptions = Object.assign({}, cwdOptionsDefault, response.options);						}						if (response.netDrivers) {							self.netDrivers = response.netDrivers;						}						if (response.maxTargets) {							self.maxTargets = response.maxTargets;						}						if (!!data.init) {							self.uplMaxSize = self.returnBytes(response.uplMaxSize);							self.uplMaxFile = !!response.uplMaxFile? Math.max(parseInt(response.uplMaxFile), 50) : 20;						}					}					if (typeof prepare === 'function') {						prepare(response);					}										if (navigate) {						actionTarget = navigate.target || 'added';						if (response[actionTarget] && response[actionTarget].length) {							self.one(cmd + 'done', function() {								var targets  = response[actionTarget],									newItems = self.findCwdNodes(targets),									inCwdHashes = function() {										var cwdHash = self.cwd().hash;										return $.map(targets, function(f) { return (f.phash && cwdHash === f.phash)? f.hash : null; });									},									hashes   = inCwdHashes(),									makeToast  = function(t) {										var node = void(0),											data = t.action? t.action.data : void(0),											cmd, msg, done;										if ((data || hashes.length) && t.action && (msg = t.action.msg) && (cmd = t.action.cmd) && (!t.action.cwdNot || t.action.cwdNot !== self.cwd().hash)) {											done = t.action.done;											data = t.action.data;											node = $('<div/>')												.append(													$('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all elfinder-tabstop"><span class="ui-button-text">'														+self.i18n(msg)														+'</span></button>')													.on('mouseenter mouseleave', function(e) { 														$(this).toggleClass('ui-state-hover', e.type == 'mouseenter');													})													.on('click', function() {														self.exec(cmd, data || hashes, {_userAction: true, _currentType: 'toast', _currentNode: $(this) });														if (done) {															self.one(cmd+'done', function() {																if (typeof done === 'function') {																	done();																} else if (done === 'select') {																	self.trigger('selectfiles', {files : inCwdHashes()});																}															});														}													})												);										}										delete t.action;										t.extNode = node;										return t;									};																if (! navigate.toast) {									navigate.toast = {};								}																!navigate.noselect && self.trigger('selectfiles', {files : self.searchStatus.state > 1 ? $.map(targets, function(f) { return f.hash; }) : hashes});																if (newItems.length) {									if (!navigate.noscroll) {										newItems.first().trigger('scrolltoview', {blink : false});										self.resources.blink(newItems, 'lookme');									}									if ($.isPlainObject(navigate.toast.incwd)) {										self.toast(makeToast(navigate.toast.incwd));									}								} else {									if ($.isPlainObject(navigate.toast.inbuffer)) {										self.toast(makeToast(navigate.toast.inbuffer));									}								}							});						}					}										dfrd.resolve(response);										response.debug && self.debug('backend-debug', response);				};				self.abortXHR(xhr);				lazy? self.lazy(resolve) : resolve();			},			xhr, _xhr,			xhrAbort = function(e) {				if (xhr && xhr.state() === 'pending') {					self.abortXHR(xhr, { quiet: true , abort: true });					if (!e || (e.type !== 'unload' && e.type !== 'destroy')) {						self.autoSync();					}				}			},			abort = function(e){				self.trigger(cmd + 'done');				if (e.type == 'autosync') {					if (e.data.action != 'stop') return;				} else if (e.type != 'unload' && e.type != 'destroy' && e.type != 'openxhrabort') {					if (!e.data.added || !e.data.added.length) {						return;					}				}				xhrAbort(e);			},			request = function(mode) {				var queueAbort = function() {					syncOnFail = false;					dfrd.reject();				};								if (mode) {					if (mode === 'cmd') {						return cmd;					}				}								if (isOpen) {					if (requestQueueSkipOpen) {						return dfrd.reject();					}					requestQueueSkipOpen = true;				}								dfrd.always(function() {					delete options.headers['X-elFinderReqid'];				}).fail(function(error, xhr, response) {					var errData = {						cmd: cmd,						err: error,						xhr: xhr,						rc: response					};					// unset this cmd queue when user canceling					// see notify : function - `cancel.reject(0);`					if (error === 0) {						if (requestQueue.length) {							requestQueue = $.grep(requestQueue, function(req) {								return (req('cmd') === cmd) ? false : true;							});						}					}					// trigger "requestError" event					self.trigger('requestError', errData);					if (errData._event && errData._event.isDefaultPrevented()) {						deffail = false;						syncOnFail = false;						if (error) {							error.error = '';						}					}					// abort xhr					xhrAbort();					if (isOpen) {						openDir = self.file(data.target);						openDir && openDir.volumeid && self.isRoot(openDir) && delete self.volumeExpires[openDir.volumeid];					}					self.trigger(cmd + 'fail', response);					if (error) {						deffail ? self.error(error) : self.debug('error', self.i18n(error));					}					syncOnFail && self.sync();				});				if (!cmd) {					syncOnFail = false;					return dfrd.reject({error :'errCmdReq'});				}								if (self.maxTargets && data.targets && data.targets.length > self.maxTargets) {					syncOnFail = false;					return dfrd.reject({error :['errMaxTargets', self.maxTargets]});				}				defdone && dfrd.done(done);								// quiet abort not completed "open" requests				if (isOpen) {					while ((_xhr = queue.pop())) {						_xhr.queueAbort();					}					if (cwd !== data.target) {						while ((_xhr = cwdQueue.pop())) {							_xhr.queueAbort();						}					}				}				// trigger abort autoSync for commands to add the item				if ($.inArray(cmd, (self.cmdsToAdd + ' autosync').split(' ')) !== -1) {					if (cmd !== 'autosync') {						self.autoSync('stop');						dfrd.always(function() {							self.autoSync();						});					}					self.trigger('openxhrabort');				}				delete options.preventFail;				if (self.api >= 2.1029) {					if (useCache) {						options.headers['X-elFinderReqid'] = reqId;					} else {						Object.assign(options.data, { reqid : reqId });					}				}								// function for set value of this syncOnFail				dfrd.syncOnFail = function(state) {					syncOnFail = !!state;				};				requestCnt++;				dfrd.xhr = xhr = self.transport.send(options).always(function() {					// set responseURL from native xhr object					if (options._xhr && typeof options._xhr.responseURL !== 'undefined') {						xhr.responseURL = options._xhr.responseURL || '';					}					--requestCnt;					if (requestQueue.length) {						requestQueue.shift()();					} else {						requestQueueSkipOpen = false;					}				}).fail(error).done(success);								if (self.api >= 2.1029) {					xhr._requestId = reqId;				}								if (isOpen || (data.compare && cmd === 'info')) {					// regist function queueAbort					xhr.queueAbort = queueAbort;					// add autoSync xhr into queue					queue.unshift(xhr);					// bind abort()					data.compare && self.bind(self.cmdsToAdd + ' autosync openxhrabort', abort);					dfrd.always(function() {						var ndx = $.inArray(xhr, queue);						data.compare && self.unbind(self.cmdsToAdd + ' autosync openxhrabort', abort);						ndx !== -1 && queue.splice(ndx, 1);					});				} else if ($.inArray(cmd, self.abortCmdsOnOpen) !== -1) {					// regist function queueAbort					xhr.queueAbort = queueAbort;					// add "open" xhr, only cwd xhr into queue					cwdQueue.unshift(xhr);					dfrd.always(function() {						var ndx = $.inArray(xhr, cwdQueue);						ndx !== -1 && cwdQueue.splice(ndx, 1);					});				}								// abort pending xhr on window unload or elFinder destroy				self.bind('unload destroy', abort);				dfrd.always(function() {					self.unbind('unload destroy', abort);				});								return dfrd;			},			queueingRequest = function() {				// show notify				if (notify.type && notify.cnt) {					if (cancel) {						notify.cancel = dfrd;						opts.eachCancel && (notify.id = +new Date());					}					timeout = setTimeout(function() {						self.notify(notify);						dfrd.always(function() {							notify.cnt = -(parseInt(notify.cnt)||0);							self.notify(notify);						});					}, self.notifyDelay);										dfrd.always(function() {						clearTimeout(timeout);					});				}				// queueing				if (isOpen) {					requestQueueSkipOpen = false;				}				if (requestCnt < requestMaxConn) {					// do request					return request();				} else {					if (isOpen) {						requestQueue.unshift(request);					} else {						requestQueue.push(request);					}					return dfrd;				}			},			bindData = {opts: opts, result: true},			openDir;				// prevent request initial request is completed		if (!self.api && !data.init) {			syncOnFail = false;			return dfrd.reject();		}		// trigger "request.cmd" that callback be able to cancel request by substituting "false" for "event.data.result"		self.trigger('request.' + cmd, bindData, true);				if (! bindData.result) {			self.trigger(cmd + 'done');			return dfrd.reject();		} else if (typeof bindData.result === 'object' && bindData.result.promise) {			bindData.result				.done(queueingRequest)				.fail(function() {					self.trigger(cmd + 'done');					dfrd.reject();				});			return dfrd;		}				return queueingRequest();	};		/**	 * Call cache()	 * Store info about files/dirs in "files" object.	 *	 * @param  Array  files	 * @return void	 */	this.cache = function(dataArray) {		if (! Array.isArray(dataArray)) {			dataArray = [ dataArray ];		}		cache(dataArray);	};		/**	 * Update file object caches by respose data object	 * 	 * @param  Object  respose data object	 * @return void	 */	this.updateCache = function(data) {		if ($.isPlainObject(data)) {			data.files && data.files.length && cache(data.files, 'files');			data.tree && data.tree.length && cache(data.tree, 'tree');			data.removed && data.removed.length && remove(data.removed);			data.added && data.added.length && cache(data.added, 'add');			data.changed && data.changed.length && change(data.changed, 'change');		}	};		/**	 * Compare current files cache with new files and return diff	 * 	 * @param  Array   new files	 * @param  String  target folder hash	 * @param  Array   exclude properties to compare	 * @return Object	 */	this.diff = function(incoming, onlydir, excludeProps) {		var raw       = {},			added     = [],			removed   = [],			changed   = [],			excludes  = null,			isChanged = function(hash) {				var l = changed.length;				while (l--) {					if (changed[l].hash == hash) {						return true;					}				}			};				$.each(incoming, function(i, f) {			raw[f.hash] = f;		});				// make excludes object		if (excludeProps && excludeProps.length) {			excludes = {};			$.each(excludeProps, function() {				excludes[this] = true;			});		}				// find removed		$.each(files, function(hash, f) {			if (! raw[hash] && (! onlydir || f.phash === onlydir)) {				removed.push(hash);			}		});				// compare files		$.each(raw, function(hash, file) {			var origin  = files[hash],				orgKeys = {},				chkKeyLen;			if (!origin) {				added.push(file);			} else {				// make orgKeys object				$.each(Object.keys(origin), function() {					orgKeys[this] = true;				});				$.each(file, function(prop) {					delete orgKeys[prop];					if (! excludes || ! excludes[prop]) {						if (file[prop] !== origin[prop]) {							changed.push(file);							orgKeys = {};							return false;						}					}				});				chkKeyLen = Object.keys(orgKeys).length;				if (chkKeyLen !== 0) {					if (excludes) {						$.each(orgKeys, function(prop) {							if (excludes[prop]) {								--chkKeyLen;							}						});					}					(chkKeyLen !== 0) && changed.push(file);				}			}		});				// parents of removed dirs mark as changed (required for tree correct work)		$.each(removed, function(i, hash) {			var file  = files[hash], 				phash = file.phash;			if (phash 			&& file.mime == 'directory' 			&& $.inArray(phash, removed) === -1 			&& raw[phash] 			&& !isChanged(phash)) {				changed.push(raw[phash]);			}		});				return {			added   : added,			removed : removed,			changed : changed		};	};		/**	 * Sync content	 * 	 * @return jQuery.Deferred	 */	this.sync = function(onlydir, polling) {		this.autoSync('stop');		var self  = this,			compare = function(){				var c = '', cnt = 0, mtime = 0;				if (onlydir && polling) {					$.each(files, function(h, f) {						if (f.phash && f.phash === onlydir) {							++cnt;							mtime = Math.max(mtime, f.ts);						}						c = cnt+':'+mtime;					});				}				return c;			},			comp  = compare(),			dfrd  = $.Deferred().done(function() { self.trigger('sync'); }),			opts = [this.request({				data           : {cmd : 'open', reload : 1, target : cwd, tree : (! onlydir && this.ui.tree) ? 1 : 0, compare : comp},				preventDefault : true			})],			exParents = function() {				var parents = [],					curRoot = self.file(self.root(cwd)),					curId = curRoot? curRoot.volumeid : null,					phash = self.cwd().phash,					isroot,pdir;								while(phash) {					if (pdir = self.file(phash)) {						if (phash.indexOf(curId) !== 0) {							parents.push( {target: phash, cmd: 'tree'} );							if (! self.isRoot(pdir)) {								parents.push( {target: phash, cmd: 'parents'} );							}							curRoot = self.file(self.root(phash));							curId = curRoot? curRoot.volumeid : null;						}						phash = pdir.phash;					} else {						phash = null;					}				}				return parents;			};				if (! onlydir && self.api >= 2) {			(cwd !== this.root()) && opts.push(this.request({				data           : {cmd : 'parents', target : cwd},				preventDefault : true			}));			$.each(exParents(), function(i, data) {				opts.push(self.request({					data           : {cmd : data.cmd, target : data.target},					preventDefault : true				}));			});		}		$.when.apply($, opts)		.fail(function(error, xhr) {			if (! polling || $.inArray('errOpen', error) !== -1) {				dfrd.reject(error);				self.parseError(error) && self.request({					data   : {cmd : 'open', target : (self.lastDir('') || self.root()), tree : 1, init : 1},					notify : {type : 'open', cnt : 1, hideCnt : true}				});			} else {				dfrd.reject((error && xhr.status != 0)? error : void 0);			}		})		.done(function(odata) {			var pdata, argLen, i;						if (odata.cwd.compare) {				if (comp === odata.cwd.compare) {					return dfrd.reject();				}			}						// for 2nd and more requests			pdata = {tree : []};						// results marge of 2nd and more requests			argLen = arguments.length;			if (argLen > 1) {				for(i = 1; i < argLen; i++) {					if (arguments[i].tree && arguments[i].tree.length) {						pdata.tree.push.apply(pdata.tree, arguments[i].tree);					}				}			}						if (self.api < 2.1) {				if (! pdata.tree) {					pdata.tree = [];				}				pdata.tree.push(odata.cwd);			}						// data normalize			odata = self.normalize(odata);			if (!self.validResponse('open', odata)) {				return dfrd.reject((odata.norError || 'errResponse'));			}			pdata = self.normalize(pdata);			if (!self.validResponse('tree', pdata)) {				return dfrd.reject((pdata.norError || 'errResponse'));			}						var diff = self.diff(odata.files.concat(pdata && pdata.tree ? pdata.tree : []), onlydir);			diff.added.push(odata.cwd);						self.updateCache(diff);						// trigger events			diff.removed.length && self.remove(diff);			diff.added.length   && self.add(diff);			diff.changed.length && self.change(diff);			return dfrd.resolve(diff);		})		.always(function() {			self.autoSync();		});				return dfrd;	};		this.upload = function(files) {		return this.transport.upload(files, this);	};		/**	 * Arrays that has to unbind events	 * 	 * @type Object	 */	this.toUnbindEvents = {};		/**	 * Attach listener to events	 * To bind to multiply events at once, separate events names by space	 * 	 * @param  String  event(s) name(s)	 * @param  Object  event handler or {done: handler}	 * @param  Boolean priority first	 * @return elFinder	 */	this.bind = function(event, callback, priorityFirst) {		var i, len;				if (callback && (typeof callback === 'function' || typeof callback.done === 'function')) {			event = ('' + event).toLowerCase().replace(/^\s+|\s+$/g, '').split(/\s+/);						len = event.length;			for (i = 0; i < len; i++) {				if (listeners[event[i]] === void(0)) {					listeners[event[i]] = [];				}				listeners[event[i]][priorityFirst? 'unshift' : 'push'](callback);			}		}		return this;	};		/**	 * Remove event listener if exists	 * To un-bind to multiply events at once, separate events names by space	 *	 * @param  String    event(s) name(s)	 * @param  Function  callback	 * @return elFinder	 */	this.unbind = function(event, callback) {		var i, len, l, ci;				event = ('' + event).toLowerCase().split(/\s+/);				len = event.length;		for (i = 0; i < len; i++) {			if (l = listeners[event[i]]) {				ci = $.inArray(callback, l);				ci > -1 && l.splice(ci, 1);			}		}				callback = null;		return this;	};		/**	 * Fire event - send notification to all event listeners	 * In the callback `this` becames an event object	 *	 * @param  String   event type	 * @param  Object   data to send across event	 * @param  Boolean  allow modify data (call by reference of data) default: true	 * @return elFinder	 */	this.trigger = function(evType, data, allowModify) {		var type      = evType.toLowerCase(),			isopen    = (type === 'open'),			dataIsObj = (typeof data === 'object'),			handlers  = listeners[type] || [],			dones     = [],			i, l, jst, event;				this.debug('event-'+type, data);				if (! dataIsObj || typeof allowModify === 'undefined') {			allowModify = true;		}		if (l = handlers.length) {			event = $.Event(type);			if (data) {				data._event = event;			}			if (allowModify) {				event.data = data;			}			for (i = 0; i < l; i++) {				if (! handlers[i]) {					// probably un-binded this handler					continue;				}				// handler is $.Deferred(), call all functions upon completion				if (handlers[i].done) {					dones.push(handlers[i].done);					continue;				}								// set `event.data` only callback has argument				if (handlers[i].length) {					if (!allowModify) {						// to avoid data modifications. remember about "sharing" passing arguments in js :) 						if (typeof jst === 'undefined') {							try {								jst = JSON.stringify(data);							} catch(e) {								jst = false;							}						}						event.data = jst? JSON.parse(jst) : data;					}				}				try {					if (handlers[i].call(event, event, this) === false || event.isDefaultPrevented()) {						this.debug('event-stoped', event.type);						break;					}				} catch (ex) {					window.console && window.console.log && window.console.log(ex);				}							}						// call done functions			if (l = dones.length) {				for (i = 0; i < l; i++) {					try {						if (dones[i].call(event, event, this) === false || event.isDefaultPrevented()) {							this.debug('event-stoped', event.type + '(done)');							break;						}					} catch (ex) {						window.console && window.console.log && window.console.log(ex);					}				}			}			if (this.toUnbindEvents[type] && this.toUnbindEvents[type].length) {				$.each(this.toUnbindEvents[type], function(i, v) {					self.unbind(v.type, v.callback);				});				delete this.toUnbindEvents[type];			}		}		return this;	};		/**	 * Get event listeners	 *	 * @param  String   event type	 * @return Array    listed event functions	 */	this.getListeners = function(event) {		return event? listeners[event.toLowerCase()] : listeners;	};		/**	 * Bind keybord shortcut to keydown event	 *	 * @example	 *    elfinder.shortcut({ 	 *       pattern : 'ctrl+a', 	 *       description : 'Select all files', 	 *       callback : function(e) { ... }, 	 *       keypress : true|false (bind to keypress instead of keydown) 	 *    })	 *	 * @param  Object  shortcut config	 * @return elFinder	 */	this.shortcut = function(s) {		var patterns, pattern, code, i, parts;				if (this.options.allowShortcuts && s.pattern && $.isFunction(s.callback)) {			patterns = s.pattern.toUpperCase().split(/\s+/);						for (i= 0; i < patterns.length; i++) {				pattern = patterns[i];				parts   = pattern.split('+');				code    = (code = parts.pop()).length == 1 					? (code > 0 ? code : code.charCodeAt(0))					: (code > 0 ? code : $.ui.keyCode[code]);				if (code && !shortcuts[pattern]) {					shortcuts[pattern] = {						keyCode     : code,						altKey      : $.inArray('ALT', parts)   != -1,						ctrlKey     : $.inArray('CTRL', parts)  != -1,						shiftKey    : $.inArray('SHIFT', parts) != -1,						type        : s.type || 'keydown',						callback    : s.callback,						description : s.description,						pattern     : pattern					};				}			}		}		return this;	};		/**	 * Registered shortcuts	 *	 * @type Object	 **/	this.shortcuts = function() {		var ret = [];				$.each(shortcuts, function(i, s) {			ret.push([s.pattern, self.i18n(s.description)]);		});		return ret;	};		/**	 * Get/set clipboard content.	 * Return new clipboard content.	 *	 * @example	 *   this.clipboard([]) - clean clipboard	 *   this.clipboard([{...}, {...}], true) - put 2 files in clipboard and mark it as cutted	 * 	 * @param  Array    new files hashes	 * @param  Boolean  cut files?	 * @return Array	 */	this.clipboard = function(hashes, cut) {		var map = function() { return $.map(clipboard, function(f) { return f.hash; }); };		if (hashes !== void(0)) {			clipboard.length && this.trigger('unlockfiles', {files : map()});			remember = {};						clipboard = $.map(hashes||[], function(hash) {				var file = files[hash];				if (file) {										remember[hash] = true;										return {						hash   : hash,						phash  : file.phash,						name   : file.name,						mime   : file.mime,						read   : file.read,						locked : file.locked,						cut    : !!cut					};				}				return null;			});			this.trigger('changeclipboard', {clipboard : clipboard.slice(0, clipboard.length)});			cut && this.trigger('lockfiles', {files : map()});		}		// return copy of clipboard instead of refrence		return clipboard.slice(0, clipboard.length);	};		/**	 * Return true if command enabled	 * 	 * @param  String       command name	 * @param  String|void  hash for check of own volume's disabled cmds	 * @return Boolean	 */	this.isCommandEnabled = function(name, dstHash) {		var disabled, cmd,			cvid = self.cwd().volumeid || '';				// In serach results use selected item hash to check		if (!dstHash && self.searchStatus.state > 1 && self.selected().length) {			dstHash = self.selected()[0];		}		if (dstHash && (! cvid || dstHash.indexOf(cvid) !== 0)) {			disabled = self.option('disabledFlip', dstHash);			//if (! disabled) {			//	disabled = {};			//}		} else {			disabled = cwdOptions.disabledFlip/* || {}*/;		}		cmd = this._commands[name];		return cmd ? (cmd.alwaysEnabled || !disabled[name]) : false;	};		/**	 * Exec command and return result;	 *	 * @param  String         command name	 * @param  String|Array   usualy files hashes	 * @param  String|Array   command options	 * @param  String|void    hash for enabled check of own volume's disabled cmds	 * @return $.Deferred	 */			this.exec = function(cmd, files, opts, dstHash) {		var dfrd, resType;				// apply commandMap for keyboard shortcut		if (!dstHash && this.commandMap[cmd] && this.commandMap[cmd] !== 'hidden') {			cmd = this.commandMap[cmd];		}		if (cmd === 'open') {			if (this.searchStatus.state || this.searchStatus.ininc) {				this.trigger('searchend', { noupdate: true });			}			this.autoSync('stop');		}		if (!dstHash && files) {			if ($.isArray(files)) {				if (files.length) {					dstHash = files[0];				}			} else {				dstHash = files;			}		}		dfrd = this._commands[cmd] && this.isCommandEnabled(cmd, dstHash) 			? this._commands[cmd].exec(files, opts) 			: $.Deferred().reject('No such command');				resType = typeof dfrd;		if (!(resType === 'object' && dfrd.promise)) {			self.debug('warning', '"cmd.exec()" should be returned "$.Deferred" but cmd "' + cmd + '" returned "' + resType + '"');			dfrd = $.Deferred().resolve();		}				this.trigger('exec', { dfrd : dfrd, cmd : cmd, files : files, opts : opts, dstHash : dstHash });		return dfrd;	};		/**	 * Create and return dialog.	 *	 * @param  String|DOMElement  dialog content	 * @param  Object             dialog options	 * @return jQuery	 */	this.dialog = function(content, options) {		var dialog = $('<div/>').append(content).appendTo(node).elfinderdialog(options, self),			dnode  = dialog.closest('.ui-dialog'),			resize = function(){				! dialog.data('draged') && dialog.is(':visible') && dialog.elfinderdialog('posInit');			};		if (dnode.length) {			self.bind('resize', resize);			dnode.on('remove', function() {				self.unbind('resize', resize);			});		}		return dialog;	};		/**	 * Create and return toast.	 *	 * @param  Object  toast options - see ui/toast.js	 * @return jQuery	 */	this.toast = function(options) {		return $('<div class="ui-front"/>').appendTo(this.ui.toast).elfindertoast(options || {}, this);	};		/**	 * Return UI widget or node	 *	 * @param  String  ui name	 * @return jQuery	 */	this.getUI = function(ui) {		return this.ui[ui] || (ui? $() : node);	};		/**	 * Return elFinder.command instance or instances array	 *	 * @param  String  command name	 * @return Object | Array	 */	this.getCommand = function(name) {		return name === void(0) ? this._commands : this._commands[name];	};		/**	 * Resize elfinder node	 * 	 * @param  String|Number  width	 * @param  String|Number  height	 * @return void	 */	this.resize = function(w, h) {		var getMargin = function() {				var m = node.outerHeight(true) - node.innerHeight(),					p = node;								while(p.get(0) !== heightBase.get(0)) {					p = p.parent();					m += p.outerHeight(true) - p.innerHeight();					if (! p.parent().length) {						// reached the document						break;					}				}				return m;			},			fit = ! node.hasClass('ui-resizable'),			prv = node.data('resizeSize') || {w: 0, h: 0},			mt, size = {};		if (heightBase && heightBase.data('resizeTm')) {			clearTimeout(heightBase.data('resizeTm'));		}				if (typeof h === 'string') {			if (mt = h.match(/^([0-9.]+)%$/)) {				// setup heightBase				if (! heightBase || ! heightBase.length) {					heightBase = $(window);				}				if (! heightBase.data('marginToMyNode')) {					heightBase.data('marginToMyNode', getMargin());				}				if (! heightBase.data('fitToBaseFunc')) {					heightBase.data('fitToBaseFunc', function(e) {						var tm = heightBase.data('resizeTm');						e.preventDefault();						e.stopPropagation();						tm && cancelAnimationFrame(tm);						if (! node.hasClass('elfinder-fullscreen') && (!self.UA.Mobile || heightBase.data('rotated') !== self.UA.Rotated)) {							heightBase.data('rotated', self.UA.Rotated);							heightBase.data('resizeTm', requestAnimationFrame(function() {								self.restoreSize();							}));						}					});				}				if (typeof heightBase.data('rotated') === 'undefined') {					heightBase.data('rotated', self.UA.Rotated);				}				h = heightBase.height() * (mt[1] / 100) - heightBase.data('marginToMyNode');								heightBase.off('resize.' + self.namespace, heightBase.data('fitToBaseFunc'));				fit && heightBase.on('resize.' + self.namespace, heightBase.data('fitToBaseFunc'));			}		}				node.css({ width : w, height : parseInt(h) });		size.w = Math.round(node.width());		size.h = Math.round(node.height());		node.data('resizeSize', size);		if (size.w !== prv.w || size.h !== prv.h) {			node.trigger('resize');			this.trigger('resize', {width : size.w, height : size.h});		}	};		/**	 * Restore elfinder node size	 * 	 * @return elFinder	 */	this.restoreSize = function() {		this.resize(width, height);	};		this.show = function() {		node.show();		this.enable().trigger('show');	};		this.hide = function() {		if (this.options.enableAlways) {			prevEnabled = enabled;			enabled = false;		}		this.disable();		this.trigger('hide');		node.hide();	};		/**	 * Lazy execution function	 * 	 * @param  Object  function	 * @param  Number  delay	 * @param  Object  options	 * @return Object  jQuery.Deferred	 */	this.lazy = function(func, delay, opts) {		var busy = function(state) {				var cnt = node.data('lazycnt'),					repaint;								if (state) {					repaint = node.data('lazyrepaint')? false : opts.repaint;					if (! cnt) {						node.data('lazycnt', 1)							.addClass('elfinder-processing');					} else {						node.data('lazycnt', ++cnt);					}					if (repaint) {						node.data('lazyrepaint', true).css('display'); // force repaint					}				} else {					if (cnt && cnt > 1) {						node.data('lazycnt', --cnt);					} else {						repaint = node.data('lazyrepaint');						node.data('lazycnt', 0)							.removeData('lazyrepaint')							.removeClass('elfinder-processing');						repaint && node.css('display'); // force repaint;						self.trigger('lazydone');					}				}			},			dfd  = $.Deferred(),			callFunc = function() {				dfd.resolve(func.call(dfd));				busy(false);			};				delay = delay || 0;		opts = opts || {};		busy(true);				if (delay) {			setTimeout(callFunc, delay);		} else {			requestAnimationFrame(callFunc);		}				return dfd;	};		/**	 * Destroy this elFinder instance	 *	 * @return void	 **/	this.destroy = function() {		if (node && node[0].elfinder) {			node.hasClass('elfinder-fullscreen') && self.toggleFullscreen(node);			this.options.syncStart = false;			this.autoSync('forcestop');			this.trigger('destroy').disable();			clipboard = [];			selected = [];			listeners = {};			shortcuts = {};			$(window).off('.' + namespace);			$(document).off('.' + namespace);			self.trigger = function(){};			$(beeper).remove();			node.off()				.removeData()				.empty()				.append(prevContent.contents())				.attr('class', prevContent.attr('class'))				.attr('style', prevContent.attr('style'));			delete node[0].elfinder;			// restore kept events			$.each(prevEvents, function(n, arr) {				$.each(arr, function(i, o) {					node.on(o.type + (o.namespace? '.'+o.namespace : ''), o.selector, o.handler);				});			});		}	};		/**	 * Start or stop auto sync	 * 	 * @param  String|Bool  stop	 * @return void	 */	this.autoSync = function(mode) {		var sync;		if (self.options.sync >= 1000) {			if (syncInterval) {				clearTimeout(syncInterval);				syncInterval = null;				self.trigger('autosync', {action : 'stop'});			}						if (mode === 'stop') {				++autoSyncStop;			} else {				autoSyncStop = Math.max(0, --autoSyncStop);			}						if (autoSyncStop || mode === 'forcestop' || ! self.options.syncStart) {				return;			} 						// run interval sync			sync = function(start){				var timeout;				if (cwdOptions.syncMinMs && (start || syncInterval)) {					start && self.trigger('autosync', {action : 'start'});					timeout = Math.max(self.options.sync, cwdOptions.syncMinMs);					syncInterval && clearTimeout(syncInterval);					syncInterval = setTimeout(function() {						var dosync = true, hash = cwd, cts;						if (cwdOptions.syncChkAsTs && files[hash] && (cts = files[hash].ts)) {							self.request({								data : {cmd : 'info', targets : [hash], compare : cts, reload : 1},								preventDefault : true							})							.done(function(data){								var ts;								dosync = true;								if (data.compare) {									ts = data.compare;									if (ts == cts) {										dosync = false;									}								}								if (dosync) {									self.sync(hash).always(function(){										if (ts) {											// update ts for cache clear etc.											files[hash].ts = ts;										}										sync();									});								} else {									sync();								}							})							.fail(function(error, xhr){								var err = self.parseError(error);								if (err && xhr.status != 0) {									self.error(err);									if (Array.isArray(err) && $.inArray('errOpen', err) !== -1) {										self.request({											data   : {cmd : 'open', target : (self.lastDir('') || self.root()), tree : 1, init : 1},											notify : {type : 'open', cnt : 1, hideCnt : true}										});									}								} else {									syncInterval = setTimeout(function() {										sync();									}, timeout);								}							});						} else {							self.sync(cwd, true).always(function(){								sync();							});						}					}, timeout);				}			};			sync(true);		}	};		/**	 * Return bool is inside work zone of specific point	 * 	 * @param  Number event.pageX	 * @param  Number event.pageY	 * @return Bool	 */	this.insideWorkzone = function(x, y, margin) {		var rectangle = this.getUI('workzone').data('rectangle');				margin = margin || 1;		if (x < rectangle.left + margin		|| x > rectangle.left + rectangle.width + margin		|| y < rectangle.top + margin		|| y > rectangle.top + rectangle.height + margin) {			return false;		}		return true;	};		/**	 * Target ui node move to last of children of elFinder node fot to show front	 * 	 * @param  Object  target    Target jQuery node object	 */	this.toFront = function(target) {		var nodes = node.children('.ui-front').removeClass('elfinder-frontmost'),			lastnode = nodes.last();		nodes.css('z-index', '');		$(target).addClass('ui-front elfinder-frontmost').css('z-index', lastnode.css('z-index') + 1);	};		/**	 * Remove class 'elfinder-frontmost' and hide() to target ui node	 *	 * @param      Object   target  Target jQuery node object	 * @param      Boolean  nohide  Do not hide	 */	this.toHide =function(target, nohide) {		var tgt = $(target),			last;		!nohide && tgt.hide();		if (tgt.hasClass('elfinder-frontmost')) {			tgt.removeClass('elfinder-frontmost');			last = node.children('.ui-front:visible:not(.elfinder-frontmost)').last();			if (last.length) {				requestAnimationFrame(function() {					if (!node.children('.elfinder-frontmost:visible').length) {						self.toFront(last);						last.trigger('frontmost');					}				});			}		}	};	/**	 * Return css object for maximize	 * 	 * @return Object	 */	this.getMaximizeCss = function() {		return {			width   : '100%',			height  : '100%',			margin  : 0,			top     : 0,			left    : 0,			display : 'block',			position: 'fixed',			zIndex  : Math.max(self.zIndex? (self.zIndex + 1) : 0 , 1000),			maxWidth : '',			maxHeight: ''		};	};		// Closure for togglefullscreen	(function() {		// check is in iframe		if (inFrame && self.UA.Fullscreen) {			self.UA.Fullscreen = false;			if (parentIframe && typeof parentIframe.attr('allowfullscreen') !== 'undefined') {				self.UA.Fullscreen = true;			}		}		var orgStyle, bodyOvf, resizeTm, fullElm, exitFull, toFull,			cls = 'elfinder-fullscreen',			clsN = 'elfinder-fullscreen-native',			checkDialog = function() {				var t = 0,					l = 0;				$.each(node.children('.ui-dialog,.ui-draggable'), function(i, d) {					var $d = $(d),						pos = $d.position();										if (pos.top < 0) {						$d.css('top', t);						t += 20;					}					if (pos.left < 0) {						$d.css('left', l);						l += 20;					}				});			},			funcObj = self.UA.Fullscreen? {				// native full screen mode								fullElm: function() {					return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || null;				},								exitFull: function() {					if (document.exitFullscreen) {						return document.exitFullscreen();					} else if (document.webkitExitFullscreen) {						return document.webkitExitFullscreen();					} else if (document.mozCancelFullScreen) {						return document.mozCancelFullScreen();					} else if (document.msExitFullscreen) {						return document.msExitFullscreen();					}				},								toFull: function(elem) {					if (elem.requestFullscreen) {						return elem.requestFullscreen();					} else if (elem.webkitRequestFullscreen) {						return elem.webkitRequestFullscreen();					} else if (elem.mozRequestFullScreen) {						return elem.mozRequestFullScreen();					} else if (elem.msRequestFullscreen) {						return elem.msRequestFullscreen();					}					return false;				}			} : {				// node element maximize mode								fullElm: function() {					var full;					if (node.hasClass(cls)) {						return node.get(0);					} else {						full = node.find('.' + cls);						if (full.length) {							return full.get(0);						}					}					return null;				},								exitFull: function() {					var elm;										$(window).off('resize.' + namespace, resize);					if (bodyOvf !== void(0)) {						$('body').css('overflow', bodyOvf);					}					bodyOvf = void(0);										if (orgStyle) {						elm = orgStyle.elm;						restoreStyle(elm);						$(elm).trigger('resize', {fullscreen: 'off'});					}										$(window).trigger('resize');				},								toFull: function(elem) {					bodyOvf = $('body').css('overflow') || '';					$('body').css('overflow', 'hidden');										$(elem).css(self.getMaximizeCss())						.addClass(cls)						.trigger('resize', {fullscreen: 'on'});										checkDialog();										$(window).on('resize.' + namespace, resize).trigger('resize');										return true;				}			},			restoreStyle = function(elem) {				if (orgStyle && orgStyle.elm == elem) {					$(elem).removeClass(cls + ' ' + clsN).attr('style', orgStyle.style);					orgStyle = null;				}			},			resize = function(e) {				var elm;				if (e.target === window) {					resizeTm && cancelAnimationFrame(resizeTm);					resizeTm = requestAnimationFrame(function() {						if (elm = funcObj.fullElm()) {							$(elm).trigger('resize', {fullscreen: 'on'});						}					});				}			};				$(document).on('fullscreenchange.' + namespace + ' webkitfullscreenchange.' + namespace + ' mozfullscreenchange.' + namespace + ' MSFullscreenChange.' + namespace, function(e){			if (self.UA.Fullscreen) {				var elm = funcObj.fullElm(),					win = $(window);								resizeTm && cancelAnimationFrame(resizeTm);				if (elm === null) {					win.off('resize.' + namespace, resize);					if (orgStyle) {						elm = orgStyle.elm;						restoreStyle(elm);						$(elm).trigger('resize', {fullscreen: 'off'});					}				} else {					$(elm).addClass(cls + ' ' + clsN)						.attr('style', 'width:100%; height:100%; margin:0; padding:0;')						.trigger('resize', {fullscreen: 'on'});					win.on('resize.' + namespace, resize);					checkDialog();				}				win.trigger('resize');			}		});				/**		 * Toggle Full Scrren Mode		 * 		 * @param  Object target		 * @param  Bool   full		 * @return Object | Null  DOM node object of current full scrren		 */		self.toggleFullscreen = function(target, full) {			var elm = $(target).get(0),				curElm = null;						curElm = funcObj.fullElm();			if (curElm) {				if (curElm == elm) {					if (full === true) {						return curElm;					}				} else {					if (full === false) {						return curElm;					}				}				funcObj.exitFull();				return null;			} else {				if (full === false) {					return null;				}			}						orgStyle = {elm: elm, style: $(elm).attr('style')};			if (funcObj.toFull(elm) !== false) {				return elm;			} else {				orgStyle = null;				return null;			}		};	})();		// Closure for toggleMaximize	(function(){		var cls = 'elfinder-maximized',		resizeTm,		resize = function(e) {			if (e.target === window && e.data && e.data.elm) {				var elm = e.data.elm;				resizeTm && cancelAnimationFrame(resizeTm);				resizeTm = requestAnimationFrame(function() {					elm.trigger('resize', {maximize: 'on'});				});			}		},		exitMax = function(elm) {			$(window).off('resize.' + namespace, resize);			$('body').css('overflow', elm.data('bodyOvf'));			elm.removeClass(cls)				.attr('style', elm.data('orgStyle'))				.removeData('bodyOvf')				.removeData('orgStyle');			elm.trigger('resize', {maximize: 'off'});		},		toMax = function(elm) {			elm.data('bodyOvf', $('body').css('overflow') || '')				.data('orgStyle', elm.attr('style'))				.addClass(cls)				.css(self.getMaximizeCss());			$('body').css('overflow', 'hidden');			$(window).on('resize.' + namespace, {elm: elm}, resize);			elm.trigger('resize', {maximize: 'on'});		};				/**		 * Toggle Maximize target node		 * 		 * @param  Object target		 * @param  Bool   max		 * @return void		 */		self.toggleMaximize = function(target, max) {			var elm = $(target),				maximized = elm.hasClass(cls);						if (maximized) {				if (max === true) {					return;				}				exitMax(elm);			} else {				if (max === false) {					return;				}				toMax(elm);			}		};	})();		/*************  init stuffs  ****************/	Object.assign($.ui.keyCode, {		'F1' : 112,		'F2' : 113,		'F3' : 114,		'F4' : 115,		'F5' : 116,		'F6' : 117,		'F7' : 118,		'F8' : 119,		'F9' : 120,		'F10' : 121,		'F11' : 122,		'F12' : 123,		'DIG0' : 48,		'DIG1' : 49,		'DIG2' : 50,		'DIG3' : 51,		'DIG4' : 52,		'DIG5' : 53,		'DIG6' : 54,		'DIG7' : 55,		'DIG8' : 56,		'DIG9' : 57,		'NUM0' : 96,		'NUM1' : 97,		'NUM2' : 98,		'NUM3' : 99,		'NUM4' : 100,		'NUM5' : 101,		'NUM6' : 102,		'NUM7' : 103,		'NUM8' : 104,		'NUM9' : 105,		'CONTEXTMENU' : 93,		'DOT'  : 190	});		this.dragUpload = false;	this.xhrUpload  = (typeof XMLHttpRequestUpload != 'undefined' || typeof XMLHttpRequestEventTarget != 'undefined') && typeof File != 'undefined' && typeof FormData != 'undefined';		// configure transport object	this.transport = {};	if (typeof(this.options.transport) == 'object') {		this.transport = this.options.transport;		if (typeof(this.transport.init) == 'function') {			this.transport.init(this);		}	}		if (typeof(this.transport.send) != 'function') {		this.transport.send = function(opts) {			if (!self.UA.IE) {				// keep native xhr object for handling property responseURL				opts._xhr = new XMLHttpRequest();				opts.xhr = function() { return opts._xhr; };			}			return $.ajax(opts);		};	}		if (this.transport.upload == 'iframe') {		this.transport.upload = $.proxy(this.uploads.iframe, this);	} else if (typeof(this.transport.upload) == 'function') {		this.dragUpload = !!this.options.dragUploadAllow;	} else if (this.xhrUpload && !!this.options.dragUploadAllow) {		this.transport.upload = $.proxy(this.uploads.xhr, this);		this.dragUpload = true;	} else {		this.transport.upload = $.proxy(this.uploads.iframe, this);	}	/**	 * Decoding 'raw' string converted to unicode	 * 	 * @param  String str	 * @return String	 */	this.decodeRawString = function(str) {		var charCodes = function(str) {			var i, len, arr;			for (i=0,len=str.length,arr=[]; i<len; i++) {				arr.push(str.charCodeAt(i));			}			return arr;		},		scalarValues = function(arr) {			var scalars = [], i, len, c;			if (typeof arr === 'string') {arr = charCodes(arr);}			for (i=0,len=arr.length; c=arr[i],i<len; i++) {				if (c >= 0xd800 && c <= 0xdbff) {					scalars.push((c & 1023) + 64 << 10 | arr[++i] & 1023);				} else {					scalars.push(c);				}			}			return scalars;		},		decodeUTF8 = function(arr) {			var i, len, c, str, char = String.fromCharCode;			for (i=0,len=arr.length,str=""; c=arr[i],i<len; i++) {				if (c <= 0x7f) {					str += char(c);				} else if (c <= 0xdf && c >= 0xc2) {					str += char((c&31)<<6 | arr[++i]&63);				} else if (c <= 0xef && c >= 0xe0) {					str += char((c&15)<<12 | (arr[++i]&63)<<6 | arr[++i]&63);				} else if (c <= 0xf7 && c >= 0xf0) {					str += char(						0xd800 | ((c&7)<<8 | (arr[++i]&63)<<2 | arr[++i]>>>4&3) - 64,						0xdc00 | (arr[i++]&15)<<6 | arr[i]&63					);				} else {					str += char(0xfffd);				}			}			return str;		};				return decodeUTF8(scalarValues(str));	};	/**	 * Gets target file contents by file.hash	 *	 * @param      String  hash          The hash	 * @param      String  responseType  'blob' or 'arraybuffer' (default)	 * @return     arraybuffer|blob  The contents.	 */	this.getContents = function(hash, responseType) {		var self = this,			dfd = $.Deferred(),			type = responseType || 'arraybuffer',			url, req;		dfd.fail(function() {			req && req.state() === 'pending' && req.reject();		});		url = self.openUrl(hash);		if (!self.isSameOrigin(url)) {			url = self.openUrl(hash, true);		}		req = self.request({			data    : {cmd : 'get'},			options : {				url: url,				type: 'get',				cache : true,				dataType : 'binary',				responseType : type,				processData: false			}		})		.fail(function() {			dfd.reject();		})		.done(function(data) {			dfd.resolve(data);		});		return dfd;	};	this.getMimetype = function(name, orgMime) {		var mime = orgMime,			ext, m;		m = (name + '').match(/\.([^.]+)$/);		if (m && (ext = m[1])) {			if (!extToMimeTable) {				extToMimeTable = self.arrayFlip(self.mimeTypes);			}			if (!(mime = extToMimeTable[ext.toLowerCase()])) {				mime = orgMime;			}		}		return mime;	};	/**	 * Supported check hash algorisms	 * 	 * @type Array	 */	self.hashCheckers = [];	/**	 * Closure of getContentsHashes()	 */	(function(self) {		var hashLibs = {				check : true			},			md5Calc = function(arr) {				var spark = new hashLibs.SparkMD5.ArrayBuffer(),					job;				job = self.asyncJob(function(buf) {					spark.append(buf);				}, arr).done(function() {					job._md5 = spark.end();				});				return job;			},			shaCalc = function(arr, length) {				var sha, job;				try {					sha = new hashLibs.jsSHA('SHA' + (length.substr(0, 1) === '3'? length : ('-' + length)), 'ARRAYBUFFER');					job = self.asyncJob(function(buf) {						sha.update(buf);					}, arr).done(function() {						job._sha = sha.getHash('HEX');					});				} catch(e) {					job = $.Deferred.reject();				}				return job;			};		// make fm.hashCheckers		if (self.options.cdns.sparkmd5) {			self.hashCheckers.push('md5');		}		if (self.options.cdns.jssha) {			self.hashCheckers = self.hashCheckers.concat(['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha3-224', 'sha3-256', 'sha3-384', 'sha3-512', 'shake128', 'shake256']);		}		/**		 * Gets the contents hashes.		 *		 * @param      String  target      target file.hash		 * @param      Object  needHashes  need hash lib names		 * @return     Object  hashes with lib name as key		 */		self.getContentsHashes = function(target, needHashes) {			var dfd = $.Deferred(),				needs = self.arrayFlip(needHashes || ['md5'], true),				libs = [],				jobs = [],				res = {},				req;			dfd.fail(function() {				req && req.reject();			});			if (hashLibs.check) {				delete hashLibs.check;				// load SparkMD5				var libsmd5 = $.Deferred();				if (window.ArrayBuffer && self.options.cdns.sparkmd5) {					libs.push(libsmd5);					self.loadScript([self.options.cdns.sparkmd5],						function(res) { 							var SparkMD5 = res || window.SparkMD5;							window.SparkMD5 && delete window.SparkMD5;							libsmd5.resolve();							if (SparkMD5) {								hashLibs.SparkMD5 = SparkMD5;							}						},						{							tryRequire: true,							error: function() {								libsmd5.reject();							}						}					);				}				// load jsSha				var libssha = $.Deferred();				if (window.ArrayBuffer && self.options.cdns.jssha) {					libs.push(libssha);					self.loadScript([self.options.cdns.jssha],						function(res) { 							var jsSHA = res || window.jsSHA;							window.jsSHA && delete window.jsSHA;							libssha.resolve();							if (jsSHA) {								hashLibs.jsSHA = jsSHA;							}						},						{							tryRequire: true,							error: function() {								libssha.reject();							}						}					);				}			}						$.when.apply(null, libs).always(function() {				if (Object.keys(hashLibs).length) {					req = self.getContents(target).done(function(arrayBuffer) {						var arr = (arrayBuffer instanceof ArrayBuffer && arrayBuffer.byteLength > 0)? self.sliceArrayBuffer(arrayBuffer, 1048576) : false,							i;						if (needs.md5 && hashLibs.SparkMD5) {							jobs.push(function() {								var job = md5Calc(arr).done(function() {									var f;									res.md5 = job._md5;									if (f = self.file(target)) {										f.md5 = job._md5;									}									dfd.notify(res);								});								dfd.fail(function() {									job.reject();								});								return job;							});						}						if (hashLibs.jsSHA) {							$.each(['1', '224', '256', '384', '512', '3-224', '3-256', '3-384', '3-512', 'ke128', 'ke256'], function(i, v) {								if (needs['sha' + v]) {									jobs.push(function() {										var job = shaCalc(arr, v).done(function() {											var f;											res['sha' + v] = job._sha;											if (f = self.file(target)) {												f['sha' + v] = job._sha;											}											dfd.notify(res);										});										return job;									});								}							});						}						if (jobs.length) {							self.sequence(jobs).always(function() {								dfd.resolve(res);							});						} else {							dfd.reject();						}					}).fail(function() {						dfd.reject();					});				} else {					dfd.reject();				}			});			return dfd;		};	})(this);	/**	 * Parse error value to display	 *	 * @param  Mixed  error	 * @return Mixed  parsed error	 */	this.parseError = function(error) {		var arg = error;		if ($.isPlainObject(arg)) {			arg = arg.error;		}		return arg;	};	/**	 * Alias for this.trigger('error', {error : 'message'})	 *	 * @param  String  error message	 * @return elFinder	 **/	this.error = function() {		var arg = arguments[0],			opts = arguments[1] || null,			err;		if (arguments.length == 1 && typeof(arg) === 'function') {			return self.bind('error', arg);		} else {			err = this.parseError(arg);			return (err === true || !err)? this : self.trigger('error', {error: err, opts : opts});		}	};		// create bind/trigger aliases for build-in events	$.each(events, function(i, name) {		self[name] = function() {			var arg = arguments[0];			return arguments.length == 1 && typeof(arg) == 'function'				? self.bind(name, arg)				: self.trigger(name, $.isPlainObject(arg) ? arg : {});		};	});	// bind core event handlers	this		.enable(function() {			if (!enabled && self.api && self.visible() && self.ui.overlay.is(':hidden') && ! node.children('.elfinder-dialog.' + self.res('class', 'editing') + ':visible').length) {				enabled = true;				document.activeElement && document.activeElement.blur();				node.removeClass('elfinder-disabled');			}		})		.disable(function() {			prevEnabled = enabled;			enabled = false;			node.addClass('elfinder-disabled');		})		.open(function() {			selected = [];		})		.select(function(e) {			var cnt = 0,				unselects = [];			selected = $.grep(e.data.selected || e.data.value|| [], function(hash) {				if (unselects.length || (self.maxTargets && ++cnt > self.maxTargets)) {					unselects.push(hash);					return false;				} else {					return files[hash] ? true : false;				}			});			if (unselects.length) {				self.trigger('unselectfiles', {files: unselects, inselect: true});				self.toast({mode: 'warning', msg: self.i18n(['errMaxTargets', self.maxTargets])});			}		})		.error(function(e) { 			var opts  = {					cssClass  : 'elfinder-dialog-error',					title     : self.i18n(self.i18n('error')),					resizable : false,					destroyOnClose : true,					buttons   : {}			};						opts.buttons[self.i18n(self.i18n('btnClose'))] = function() { $(this).elfinderdialog('close'); };			if (e.data.opts && $.isPlainObject(e.data.opts)) {				Object.assign(opts, e.data.opts);			}			self.dialog('<span class="elfinder-dialog-icon elfinder-dialog-icon-error"/>'+self.i18n(e.data.error), opts);		})		.bind('tmb', function(e) {			$.each(e.data.images||[], function(hash, tmb) {				if (files[hash]) {					files[hash].tmb = tmb;				}			});		})		.bind('searchstart', function(e) {			Object.assign(self.searchStatus, e.data);			self.searchStatus.state = 1;		})		.bind('search', function(e) {			self.searchStatus.state = 2;		})		.bind('searchend', function() {			self.searchStatus.state = 0;			self.searchStatus.ininc = false;			self.searchStatus.mixed = false;		})		.bind('canMakeEmptyFile', function(e) {			var data = e.data,				obj = {};			if (data && Array.isArray(data.mimes)) {				if (!data.unshift) {					obj = self.mimesCanMakeEmpty;				}				$.each(data.mimes, function() {					if (!obj[this]) {						obj[this] = self.mimeTypes[this];					}				});				if (data.unshift) {					self.mimesCanMakeEmpty = Object.assign(obj, self.mimesCanMakeEmpty);				}			}		})		.bind('themechange', function() {			requestAnimationFrame(function() {				self.trigger('uiresize');			});		})		;	// We listen and emit a sound on delete according to option	if (true === this.options.sound) {		this.bind('playsound', function(e) {			var play  = beeper.canPlayType && beeper.canPlayType('audio/wav; codecs="1"'),				file = e.data && e.data.soundFile;			play && file && play != '' && play != 'no' && $(beeper).html('<source src="' + soundPath + file + '" type="audio/wav">')[0].play();		});	}	// bind external event handlers	$.each(this.options.handlers, function(event, callback) {		self.bind(event, callback);	});	/**	 * History object. Store visited folders	 *	 * @type Object	 **/	this.history = new this.history(this);		/**	 * Root hashed	 * 	 * @type Object	 */	this.roots = {};		/**	 * leaf roots	 * 	 * @type Object	 */	this.leafRoots = {};		this.volumeExpires = {};	/**	 * Loaded commands	 *	 * @type Object	 **/	this._commands = {};		if (!Array.isArray(this.options.commands)) {		this.options.commands = [];	}		if ($.inArray('*', this.options.commands) !== -1) {		this.options.commands = Object.keys(this.commands);	}		/**	 * UI command map of cwd volume ( That volume driver option `uiCmdMap` )	 *	 * @type Object	 **/	this.commandMap = {};		/**	 * cwd options of each volume	 * key: volumeid	 * val: options object	 * 	 * @type Object	 */	this.volOptions = {};	/**	 * Has volOptions data	 * 	 * @type Boolean	 */	this.hasVolOptions = false;	/**	 * Hash of trash holders	 * key: trash folder hash	 * val: source volume hash	 * 	 * @type Object	 */	this.trashes = {};	/**	 * cwd options of each folder/file	 * key: hash	 * val: options object	 *	 * @type Object	 */	this.optionsByHashes = {};		/**	 * UI Auto Hide Functions	 * Each auto hide function mast be call to `fm.trigger('uiautohide')` at end of process	 *	 * @type Array	 **/	this.uiAutoHide = [];		// trigger `uiautohide`	this.one('open', function() {		if (self.uiAutoHide.length) {			setTimeout(function() {				self.trigger('uiautohide');			}, 500);		}	});		// Auto Hide Functions sequential processing start	this.bind('uiautohide', function() {		if (self.uiAutoHide.length) {			self.uiAutoHide.shift()();		}	});	if (this.options.width) {		width = this.options.width;	}		if (this.options.height) {		height = this.options.height;	}		if (this.options.heightBase) {		heightBase = $(this.options.heightBase);	}		if (this.options.soundPath) {		soundPath = this.options.soundPath.replace(/\/+$/, '') + '/';	} else {		soundPath = this.baseUrl + soundPath;	}		self.one('opendone', function() {		var tm;		// attach events to document		$(document)			// disable elfinder on click outside elfinder			.on('click.'+namespace, function(e) { enabled && ! self.options.enableAlways && !$(e.target).closest(node).length && self.disable(); })			// exec shortcuts			.on(keydown+' '+keypress+' '+keyup+' '+mousedown, execShortcut);				// attach events to window		self.options.useBrowserHistory && $(window)			.on('popstate.' + namespace, function(ev) {				var state = ev.originalEvent.state || {},					hasThash = state.thash? true : false,					dialog = node.find('.elfinder-frontmost:visible'),					input = node.find('.elfinder-navbar-dir,.elfinder-cwd-filename').find('input,textarea'),					onOpen, toast;				if (!hasThash) {					state = { thash: self.cwd().hash };					// scroll to elFinder node					$('html,body').animate({ scrollTop: node.offset().top });				}				if (dialog.length || input.length) {					history.pushState(state, null, location.pathname + location.search + '#elf_' + state.thash);					if (dialog.length) {						if (!dialog.hasClass(self.res('class', 'preventback'))) {							if (dialog.hasClass('elfinder-contextmenu')) {								$(document).trigger($.Event('keydown', { keyCode: $.ui.keyCode.ESCAPE, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));							} else if (dialog.hasClass('elfinder-dialog')) {								dialog.elfinderdialog('close');							} else {								dialog.trigger('close');							}						}					} else {						input.trigger($.Event('keydown', { keyCode: $.ui.keyCode.ESCAPE, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));					}				} else {					if (hasThash) {						!$.isEmptyObject(self.files()) && self.request({							data   : {cmd  : 'open', target : state.thash, onhistory : 1},							notify : {type : 'open', cnt : 1, hideCnt : true},							syncOnFail : true						});					} else {						onOpen = function() {							toast.trigger('click');						};						self.one('open', onOpen, true);						toast = self.toast({							msg: self.i18n('pressAgainToExit'),							onHidden: function() {								self.unbind('open', onOpen);								history.pushState(state, null, location.pathname + location.search + '#elf_' + state.thash);							}						});					}				}			});				$(window).on('resize.' + namespace, function(e){			if (e.target === this) {				tm && cancelAnimationFrame(tm);				tm = requestAnimationFrame(function() {					var prv = node.data('resizeSize') || {w: 0, h: 0},						size = {w: Math.round(node.width()), h: Math.round(node.height())};					node.data('resizeSize', size);					if (size.w !== prv.w || size.h !== prv.h) {						node.trigger('resize');						self.trigger('resize', {width : size.w, height : size.h});					}				});			}		})		.on('beforeunload.' + namespace,function(e){			var msg, cnt;			if (node.is(':visible')) {				if (self.ui.notify.children().length && $.inArray('hasNotifyDialog', self.options.windowCloseConfirm) !== -1) {					msg = self.i18n('ntfsmth');				} else if (node.find('.'+self.res('class', 'editing')).length && $.inArray('editingFile', self.options.windowCloseConfirm) !== -1) {					msg = self.i18n('editingFile');				} else if ((cnt = Object.keys(self.selected()).length) && $.inArray('hasSelectedItem', self.options.windowCloseConfirm) !== -1) {					msg = self.i18n('hasSelected', ''+cnt);				} else if ((cnt = Object.keys(self.clipboard()).length) && $.inArray('hasClipboardData', self.options.windowCloseConfirm) !== -1) {					msg = self.i18n('hasClipboard', ''+cnt);				}				if (msg) {					e.returnValue = msg;					return msg;				}			}			self.trigger('unload');		});		// bind window onmessage for CORS		$(window).on('message.' + namespace, function(e){			var res = e.originalEvent || null,				obj, data;			if (res && self.uploadURL.indexOf(res.origin) === 0) {				try {					obj = JSON.parse(res.data);					data = obj.data || null;					if (data) {						if (data.error) {							if (obj.bind) {								self.trigger(obj.bind+'fail', data);							}							self.error(data.error);						} else {							data.warning && self.error(data.warning);							self.updateCache(data);							data.removed && data.removed.length && self.remove(data);							data.added   && data.added.length   && self.add(data);							data.changed && data.changed.length && self.change(data);							if (obj.bind) {								self.trigger(obj.bind, data);								self.trigger(obj.bind+'done');							}							data.sync && self.sync();						}					}				} catch (e) {					self.sync();				}			}		});		// elFinder enable always		if (self.options.enableAlways) {			$(window).on('focus.' + namespace, function(e){				(e.target === this) && self.enable();			});			if (inFrame) {				$(window.top).on('focus.' + namespace, function() {					if (self.enable() && (! parentIframe || parentIframe.is(':visible'))) {						requestAnimationFrame(function() {							$(window).trigger('focus');						});					}				});			}		} else if (inFrame) {			$(window).on('blur.' + namespace, function(e){				enabled && e.target === this && self.disable();			});		}		// return focus to the window on click (elFInder in the frame)		if (inFrame) {			node.on('click', function(e) {				$(window).trigger('focus');			});		}				// elFinder to enable by mouse over		if (self.options.enableByMouseOver) {			node.on('mouseenter touchstart', function(e) {				(inFrame) && $(window).trigger('focus');				! self.enabled() && self.enable();			});		}	});	// store instance in node	node[0].elfinder = this;	// auto load language file	dfrdsBeforeBootup.push((function() {		var lang   = self.lang,			langJs = self.i18nBaseUrl + 'elfinder.' + lang + '.js',			dfd    = $.Deferred().done(function() {				if (self.i18[lang]) {					self.lang = lang;				}				self.trigger('i18load');				i18n = self.lang === 'en' 					? self.i18['en'] 					: $.extend(true, {}, self.i18['en'], self.i18[self.lang]);			});				if (!self.i18[lang]) {			self.lang = 'en';			if (self.hasRequire) {				require([langJs], function() {					dfd.resolve();				}, function() {					dfd.resolve();				});			} else {				self.loadScript([langJs], function() {					dfd.resolve();				}, {					loadType: 'tag',					error : function() {						dfd.resolve();					}				});			}		} else {			dfd.resolve();		}		return dfd;	})());		// elFinder boot up function	bootUp = function() {		var columnNames;		/**		 * i18 messages		 *		 * @type Object		 **/		self.messages = i18n.messages;				// check jquery ui		if (!($.fn.selectable && $.fn.draggable && $.fn.droppable && $.fn.resizable && $.fn.slider)) {			return alert(self.i18n('errJqui'));		}				// check node		if (!node.length) {			return alert(self.i18n('errNode'));		}		// check connector url		if (!self.options.url) {			return alert(self.i18n('errURL'));		}				// column key/name map for fm.getColumnName()		columnNames = Object.assign({			name : self.i18n('name'),			perm : self.i18n('perms'),			date : self.i18n('modify'),			size : self.i18n('size'),			kind : self.i18n('kind'),			modestr : self.i18n('mode'),			modeoct : self.i18n('mode'),			modeboth : self.i18n('mode')		}, self.options.uiOptions.cwd.listView.columnsCustomName);		/**		 * Gets the column name of cwd list view		 *		 * @param      String  key     The key		 * @return     String  The column name.		 */		self.getColumnName = function(key) {			return columnNames[key] || self.i18n(key);		};		/**		 * Interface direction		 *		 * @type String		 * @default "ltr"		 **/		self.direction = i18n.direction;				/**		 * Date/time format		 *		 * @type String		 * @default "m.d.Y"		 **/		self.dateFormat = self.options.dateFormat || i18n.dateFormat;				/**		 * Date format like "Yesterday 10:20:12"		 *		 * @type String		 * @default "{day} {time}"		 **/		self.fancyFormat = self.options.fancyDateFormat || i18n.fancyDateFormat;				/**		 * Date format for if upload file has not original unique name		 * e.g. Clipboard image data, Image data taken with iOS		 *		 * @type String		 * @default "ymd-His"		 **/		self.nonameDateFormat = (self.options.nonameDateFormat || i18n.nonameDateFormat).replace(/[\/\\]/g, '_');		/**		 * Css classes 		 *		 * @type String		 **/		self.cssClass = 'ui-helper-reset ui-helper-clearfix ui-widget ui-widget-content ui-corner-all elfinder elfinder-'				+(self.direction == 'rtl' ? 'rtl' : 'ltr')				+(self.UA.Touch? (' elfinder-touch' + (self.options.resizable ? ' touch-punch' : '')) : '')				+(self.UA.Mobile? ' elfinder-mobile' : '')				+(self.UA.iOS? ' elfinder-ios' : '')				+' '+self.options.cssClass;		// prepare node		node.addClass(self.cssClass)			.on(mousedown, function() {				!enabled && self.enable();			});		// draggable closure		(function() {			var ltr, wzRect, wzBottom, wzBottom2, nodeStyle,				keyEvt = keydown + 'draggable' + ' keyup.' + namespace + 'draggable';						/**			 * Base draggable options			 *			 * @type Object			 **/			self.draggable = {				appendTo   : node,				addClasses : false,				distance   : 4,				revert     : true,				refreshPositions : false,				cursor     : 'crosshair',				cursorAt   : {left : 50, top : 47},				scroll     : false,				start      : function(e, ui) {					var helper   = ui.helper,						targets  = $.grep(helper.data('files')||[], function(h) {							if (h) {								remember[h] = true;								return true;							}							return false;						}),						locked   = false,						cnt, h;										// fix node size					nodeStyle = node.attr('style');					node.width(node.width()).height(node.height());										// set var for drag()					ltr = (self.direction === 'ltr');					wzRect = self.getUI('workzone').data('rectangle');					wzBottom = wzRect.top + wzRect.height;					wzBottom2 = wzBottom - self.getUI('navdock').outerHeight(true);										self.draggingUiHelper = helper;					cnt = targets.length;					while (cnt--) {						h = targets[cnt];						if (files[h].locked) {							locked = true;							helper.data('locked', true);							break;						}					}					!locked && self.trigger('lockfiles', {files : targets});							helper.data('autoScrTm', setInterval(function() {						if (helper.data('autoScr')) {							self.autoScroll[helper.data('autoScr')](helper.data('autoScrVal'));						}					}, 50));				},				drag       : function(e, ui) {					var helper = ui.helper,						autoScr, autoUp, bottom;										if ((autoUp = wzRect.top > e.pageY) || wzBottom2 < e.pageY) {						if (wzRect.cwdEdge > e.pageX) {							autoScr = (ltr? 'navbar' : 'cwd') + (autoUp? 'Up' : 'Down');						} else {							autoScr = (ltr? 'cwd' : 'navbar') + (autoUp? 'Up' : 'Down');						}						if (!autoUp) {							if (autoScr.substr(0, 3) === 'cwd') {								if (wzBottom < e.pageY) {									bottom = wzBottom;								} else {									autoScr = null;								}							} else {								bottom = wzBottom2;							}						}						if (autoScr) {							helper.data('autoScr', autoScr);							helper.data('autoScrVal', Math.pow((autoUp? wzRect.top - e.pageY : e.pageY - bottom), 1.3));						}					}					if (! autoScr) {						if (helper.data('autoScr')) {							helper.data('refreshPositions', 1).data('autoScr', null);						}					}					if (helper.data('refreshPositions') && $(this).elfUiWidgetInstance('draggable')) {						if (helper.data('refreshPositions') > 0) {							$(this).draggable('option', { refreshPositions : true, elfRefresh : true });							helper.data('refreshPositions', -1);						} else {							$(this).draggable('option', { refreshPositions : false, elfRefresh : false });							helper.data('refreshPositions', null);						}					}				},				stop       : function(e, ui) {					var helper = ui.helper,						files;										$(document).off(keyEvt);					$(this).elfUiWidgetInstance('draggable') && $(this).draggable('option', { refreshPositions : false });					self.draggingUiHelper = null;					self.trigger('focus').trigger('dragstop');					if (! helper.data('droped')) {						files = $.grep(helper.data('files')||[], function(h) { return h? true : false ;});						self.trigger('unlockfiles', {files : files});						self.trigger('selectfiles', {files : self.selected()});					}					self.enable();										// restore node style					node.attr('style', nodeStyle);										helper.data('autoScrTm') && clearInterval(helper.data('autoScrTm'));				},				helper     : function(e, ui) {					var element = this.id ? $(this) : $(this).parents('[id]:first'),						helper  = $('<div class="elfinder-drag-helper"><span class="elfinder-drag-helper-icon-status"/></div>'),						icon    = function(f) {							var mime = f.mime, i, tmb = self.tmb(f);							i = '<div class="elfinder-cwd-icon elfinder-cwd-icon-drag '+self.mime2class(mime)+' ui-corner-all"/>';							if (tmb) {								i = $(i).addClass(tmb.className).css('background-image', "url('"+tmb.url+"')").get(0).outerHTML;							} else if (f.icon) {								i = $(i).css(self.getIconStyle(f, true)).get(0).outerHTML;							}							if (f.csscls) {								i = '<div class="'+f.csscls+'">' + i + '</div>';							}							return i;						},						hashes, l, ctr;										self.draggingUiHelper && self.draggingUiHelper.stop(true, true);										self.trigger('dragstart', {target : element[0], originalEvent : e}, true);										hashes = element.hasClass(self.res('class', 'cwdfile')) 						? self.selected() 						: [self.navId2Hash(element.attr('id'))];										helper.append(icon(files[hashes[0]])).data('files', hashes).data('locked', false).data('droped', false).data('namespace', namespace).data('dropover', 0);							if ((l = hashes.length) > 1) {						helper.append(icon(files[hashes[l-1]]) + '<span class="elfinder-drag-num">'+l+'</span>');					}										$(document).on(keyEvt, function(e){						var chk = (e.shiftKey||e.ctrlKey||e.metaKey);						if (ctr !== chk) {							ctr = chk;							if (helper.is(':visible') && helper.data('dropover') && ! helper.data('droped')) {								helper.toggleClass('elfinder-drag-helper-plus', helper.data('locked')? true : ctr);								self.trigger(ctr? 'unlockfiles' : 'lockfiles', {files : hashes, helper: helper});							}						}					});										return helper;				}			};		})();		// in getFileCallback set - change default actions on double click/enter/ctrl+enter		if (self.commands.getfile) {			if (typeof(self.options.getFileCallback) == 'function') {				self.bind('dblclick', function(e) {					e.preventDefault();					self.exec('getfile').fail(function() {						self.exec('open', e.data && e.data.file? [ e.data.file ]: void(0));					});				});				self.shortcut({					pattern     : 'enter',					description : self.i18n('cmdgetfile'),					callback    : function() { self.exec('getfile').fail(function() { self.exec(self.OS == 'mac' ? 'rename' : 'open'); }); }				})				.shortcut({					pattern     : 'ctrl+enter',					description : self.i18n(self.OS == 'mac' ? 'cmdrename' : 'cmdopen'),					callback    : function() { self.exec(self.OS == 'mac' ? 'rename' : 'open'); }				});			} else {				self.options.getFileCallback = null;			}		}		// load commands		$.each(self.commands, function(name, cmd) {			var proto = Object.assign({}, cmd.prototype),				extendsCmd, opts;			if ($.isFunction(cmd) && !self._commands[name] && (cmd.prototype.forceLoad || $.inArray(name, self.options.commands) !== -1)) {				extendsCmd = cmd.prototype.extendsCmd || '';				if (extendsCmd) {					if ($.isFunction(self.commands[extendsCmd])) {						cmd.prototype = Object.assign({}, base, new self.commands[extendsCmd](), cmd.prototype);					} else {						return true;					}				} else {					cmd.prototype = Object.assign({}, base, cmd.prototype);				}				self._commands[name] = new cmd();				cmd.prototype = proto;				opts = self.options.commandsOptions[name] || {};				if (extendsCmd && self.options.commandsOptions[extendsCmd]) {					opts = $.extend(true, {}, self.options.commandsOptions[extendsCmd], opts);				}				self._commands[name].setup(name, opts);				// setup linked commands				if (self._commands[name].linkedCmds.length) {					$.each(self._commands[name].linkedCmds, function(i, n) {						var lcmd = self.commands[n];						if ($.isFunction(lcmd) && !self._commands[n]) {							lcmd.prototype = base;							self._commands[n] = new lcmd();							self._commands[n].setup(n, self.options.commandsOptions[n]||{});						}					});				}			}		});		/**		 * UI nodes		 *		 * @type Object		 **/		self.ui = {			// container for nav panel and current folder container			workzone : $('<div/>').appendTo(node).elfinderworkzone(self),			// container for folders tree / places			navbar : $('<div/>').appendTo(node).elfindernavbar(self, self.options.uiOptions.navbar || {}),			// container for for preview etc at below the navbar			navdock : $('<div/>').appendTo(node).elfindernavdock(self, self.options.uiOptions.navdock || {}),			// contextmenu			contextmenu : $('<div/>').appendTo(node).elfindercontextmenu(self),			// overlay			overlay : $('<div/>').appendTo(node).elfinderoverlay({				show : function() { self.disable(); },				hide : function() { prevEnabled && self.enable(); }			}),			// current folder container			cwd : $('<div/>').appendTo(node).elfindercwd(self, self.options.uiOptions.cwd || {}),			// notification dialog window			notify : self.dialog('', {				cssClass      : 'elfinder-dialog-notify',				position      : self.options.notifyDialog.position,				absolute      : true,				resizable     : false,				autoOpen      : false,				closeOnEscape : false,				title         : ' ',				width         : self.options.notifyDialog.width? parseInt(self.options.notifyDialog.width) : null,				minHeight     : null			}),			statusbar : $('<div class="ui-widget-header ui-helper-clearfix ui-corner-bottom elfinder-statusbar"/>').hide().appendTo(node),			toast : $('<div class="elfinder-toast"/>').appendTo(node),			bottomtray : $('<div class="elfinder-bottomtray">').appendTo(node)		};		self.trigger('uiready');		// load required ui		$.each(self.options.ui || [], function(i, ui) {			var name = 'elfinder'+ui,				opts = self.options.uiOptions[ui] || {};				if (!self.ui[ui] && $.fn[name]) {				// regist to self.ui before make instance				self.ui[ui] = $('<'+(opts.tag || 'div')+'/>').appendTo(node);				self.ui[ui][name](self, opts);			}		});				// update size			self.resize(width, height);				// make node resizable		if (self.options.resizable) {			node.resizable({				resize    : function(e, ui) {					self.resize(ui.size.width, ui.size.height);				},				handles   : 'se',				minWidth  : 300,				minHeight : 200			});			if (self.UA.Touch) {				node.addClass('touch-punch');			}		}		(function() {			var navbar = self.getUI('navbar'),				cwd    = self.getUI('cwd').parent();						self.autoScroll = {				navbarUp   : function(v) {					navbar.scrollTop(Math.max(0, navbar.scrollTop() - v));				},				navbarDown : function(v) {					navbar.scrollTop(navbar.scrollTop() + v);				},				cwdUp     : function(v) {					cwd.scrollTop(Math.max(0, cwd.scrollTop() - v));				},				cwdDown   : function(v) {					cwd.scrollTop(cwd.scrollTop() + v);				}			};		})();		// Swipe on the touch devices to show/hide of toolbar or navbar		if (self.UA.Touch) {			(function() {				var lastX, lastY, nodeOffset, nodeWidth, nodeTop, navbarW, toolbarH,					navbar = self.getUI('navbar'),					toolbar = self.getUI('toolbar'),					moveEv = 'touchmove.stopscroll',					moveTm,					moveUpOn = function(e) {						var touches = e.originalEvent.touches || [{}],							y = touches[0].pageY || null;						if (!lastY || y < lastY) {							e.preventDefault();							moveTm && clearTimeout(moveTm);						}					},					moveDownOn = function(e) {						e.preventDefault();						moveTm && clearTimeout(moveTm);					},					moveOff = function() {						moveTm = setTimeout(function() {							node.off(moveEv);						}, 100);					},					handleW, handleH = 50;				navbar = navbar.children().length? navbar : null;				toolbar = toolbar.length? toolbar : null;				node.on('touchstart touchmove touchend', function(e) {					if (e.type === 'touchend') {						lastX = false;						lastY = false;						moveOff();						return;					}										var touches = e.originalEvent.touches || [{}],						x = touches[0].pageX || null,						y = touches[0].pageY || null,						ltr = (self.direction === 'ltr'),						navbarMode, treeWidth, swipeX, moveX, toolbarT, mode;										if (x === null || y === null || (e.type === 'touchstart' && touches.length > 1)) {						return;					}										if (e.type === 'touchstart') {						nodeOffset = node.offset();						nodeWidth = node.width();						if (navbar) {							lastX = false;							if (navbar.is(':hidden')) {								if (! handleW) {									handleW = Math.max(50, nodeWidth / 10);								}								if ((ltr? (x - nodeOffset.left) : (nodeWidth + nodeOffset.left - x)) < handleW) {									lastX = x;								}							} else if (! e.originalEvent._preventSwipeX) {								navbarW = navbar.width();								if (ltr) {									swipeX = (x < nodeOffset.left + navbarW);								} else {									swipeX = (x > nodeOffset.left + nodeWidth - navbarW);								}								if (swipeX) {									handleW = Math.max(50, nodeWidth / 10);									lastX = x;								} else {									lastX = false;								}							}						}						if (toolbar) {							lastY = false;							if (! e.originalEvent._preventSwipeY) {								toolbarH = toolbar.height();								nodeTop = nodeOffset.top;								if (y - nodeTop < (toolbar.is(':hidden')? handleH : (toolbarH + 30))) {									lastY = y;									node.on(moveEv, toolbar.is(':hidden')? moveDownOn: moveUpOn);								}							}						}					} else {						if (navbar && lastX !== false) {							navbarMode = (ltr? (lastX > x) : (lastX < x))? 'navhide' : 'navshow';							moveX = Math.abs(lastX - x);							if (navbarMode === 'navhide' && moveX > navbarW * 0.6								|| (moveX > (navbarMode === 'navhide'? navbarW / 3 : 45)									&& (navbarMode === 'navshow'										|| (ltr? x < nodeOffset.left + 20 : x > nodeOffset.left + nodeWidth - 20)									))							) {								self.getUI('navbar').trigger(navbarMode, {handleW: handleW});								lastX = false;							}						}						if (toolbar && lastY !== false ) {							toolbarT = toolbar.offset().top;							if (Math.abs(lastY - y) > Math.min(45, toolbarH / 3)) {								mode = (lastY > y)? 'slideUp' : 'slideDown';								if (mode === 'slideDown' || toolbarT + 20 > y) {									if (toolbar.is(mode === 'slideDown' ? ':hidden' : ':visible')) {										toolbar.stop(true, true).trigger('toggle', {duration: 100, handleH: handleH});									}									lastY = false;								}							}						}					}				});			})();		}		if (self.dragUpload) {			// add event listener for HTML5 DnD upload			(function() {				var isin = function(e) {					return (e.target.nodeName !== 'TEXTAREA' && e.target.nodeName !== 'INPUT' && $(e.target).closest('div.ui-dialog-content').length === 0);				},				ent       = 'native-drag-enter',				disable   = 'native-drag-disable',				c         = 'class',				navdir    = self.res(c, 'navdir'),				droppable = self.res(c, 'droppable'),				dropover  = self.res(c, 'adroppable'),				arrow     = self.res(c, 'navarrow'),				clDropActive = self.res(c, 'adroppable'),				wz        = self.getUI('workzone'),				ltr       = (self.direction === 'ltr'),				clearTm   = function() {					autoScrTm && cancelAnimationFrame(autoScrTm);					autoScrTm = null;				},				wzRect, autoScrFn, autoScrTm;								node.on('dragenter', function(e) {					clearTm();					if (isin(e)) {						e.preventDefault();						e.stopPropagation();						wzRect = wz.data('rectangle');					}				})				.on('dragleave', function(e) {					clearTm();					if (isin(e)) {						e.preventDefault();						e.stopPropagation();					}				})				.on('dragover', function(e) {					var autoUp;					if (isin(e)) {						e.preventDefault();						e.stopPropagation();						e.originalEvent.dataTransfer.dropEffect = 'none';						if (! autoScrTm) {							autoScrTm = requestAnimationFrame(function() {								var wzBottom = wzRect.top + wzRect.height,									wzBottom2 = wzBottom - self.getUI('navdock').outerHeight(true),									fn;								if ((autoUp = e.pageY < wzRect.top) || e.pageY > wzBottom2 ) {									if (wzRect.cwdEdge > e.pageX) {										fn = (ltr? 'navbar' : 'cwd') + (autoUp? 'Up' : 'Down');									} else {										fn = (ltr? 'cwd' : 'navbar') + (autoUp? 'Up' : 'Down');									}									if (!autoUp) {										if (fn.substr(0, 3) === 'cwd') {											if (wzBottom < e.pageY) {												wzBottom2 = wzBottom;											} else {												fn = '';											}										}									}									fn && self.autoScroll[fn](Math.pow((autoUp? wzRect.top - e.pageY : e.pageY - wzBottom2), 1.3));								}								autoScrTm = null;							});						}					} else {						clearTm();					}				})				.on('drop', function(e) {					clearTm();					if (isin(e)) {						e.stopPropagation();						e.preventDefault();					}				});								node.on('dragenter', '.native-droppable', function(e){					if (e.originalEvent.dataTransfer) {						var $elm = $(e.currentTarget),							id   = e.currentTarget.id || null,							cwd  = null,							elfFrom;						if (!id) { // target is cwd							cwd = self.cwd();							$elm.data(disable, false);							try {								$.each(e.originalEvent.dataTransfer.types, function(i, v){									if (v.substr(0, 13) === 'elfinderfrom:') {										elfFrom = v.substr(13).toLowerCase();									}								});							} catch(e) {}						}						if (!cwd || (cwd.write && (!elfFrom || elfFrom !== (window.location.href + cwd.hash).toLowerCase()))) {							e.preventDefault();							e.stopPropagation();							$elm.data(ent, true);							$elm.addClass(clDropActive);						} else {							$elm.data(disable, true);						}					}				})				.on('dragleave', '.native-droppable', function(e){					if (e.originalEvent.dataTransfer) {						var $elm = $(e.currentTarget);						e.preventDefault();						e.stopPropagation();						if ($elm.data(ent)) {							$elm.data(ent, false);						} else {							$elm.removeClass(clDropActive);						}					}				})				.on('dragover', '.native-droppable', function(e){					if (e.originalEvent.dataTransfer) {						var $elm = $(e.currentTarget);						e.preventDefault();						e.stopPropagation();						e.originalEvent.dataTransfer.dropEffect = $elm.data(disable)? 'none' : 'copy';						$elm.data(ent, false);					}				})				.on('drop', '.native-droppable', function(e){					if (e.originalEvent && e.originalEvent.dataTransfer) {						var $elm = $(e.currentTarget),							id;						e.preventDefault();						e.stopPropagation();						$elm.removeClass(clDropActive);						if (e.currentTarget.id) {							id = $elm.hasClass(navdir)? self.navId2Hash(e.currentTarget.id) : self.cwdId2Hash(e.currentTarget.id);						} else {							id = self.cwd().hash;						}						e.originalEvent._target = id;						self.exec('upload', {dropEvt: e.originalEvent, target: id}, void 0, id);					}				});			})();		}		// trigger event cssloaded if cddAutoLoad disabled		if (self.cssloaded === null) {			// check css loaded and remove hide			(function() {				var loaded = function() {						if (node.data('cssautoloadHide')) {							node.data('cssautoloadHide').remove();							node.removeData('cssautoloadHide');						}						self.cssloaded = true;						requestAnimationFrame(function() {							self.trigger('cssloaded');						});					},					cnt, fi;				if (node.css('visibility') === 'hidden') {					cnt = 1000; // timeout 10 secs					fi  = setInterval(function() {						if (--cnt < 0 || node.css('visibility') !== 'hidden') {							clearInterval(fi);							loaded();						}					}, 10);				} else {					loaded();				}			})();		} else {			self.cssloaded = true;			self.trigger('cssloaded');		}		// calculate elFinder node z-index		self.zIndexCalc();		// send initial request and start to pray >_<		self.trigger('init')			.request({				data        : {cmd : 'open', target : self.startDir(), init : 1, tree : 1}, 				preventDone : true,				notify      : {type : 'open', cnt : 1, hideCnt : true},				freeze      : true			})			.fail(function() {				self.trigger('fail').disable().lastDir('');				listeners = {};				shortcuts = {};				$(document).add(node).off('.'+namespace);				self.trigger = function() { };			})			.done(function(data) {				var trashDisable = function(th) {						var src = self.file(self.trashes[th]),							d = self.options.debug,							error;												if (src && src.volumeid) {							delete self.volOptions[src.volumeid].trashHash;						}						self.trashes[th] = false;						self.debug('backend-error', 'Trash hash "'+th+'" was not found or not writable.');					},					toChkTh = {};								// regist rawStringDecoder				if (self.options.rawStringDecoder) {					self.registRawStringDecoder(self.options.rawStringDecoder);				}				// re-calculate elFinder node z-index				self.zIndexCalc();								self.load().debug('api', self.api);				// update ui's size after init				node.trigger('resize');				// initial open				open(data);				self.trigger('open', data, false);				self.trigger('opendone');								if (inFrame && self.options.enableAlways) {					$(window).trigger('focus');				}								// check self.trashes				$.each(self.trashes, function(th) {					var dir = self.file(th),						src;					if (! dir) {						toChkTh[th] = true;					} else if (dir.mime !== 'directory' || ! dir.write) {						trashDisable(th);					}				});				if (Object.keys(toChkTh).length) {					self.request({						data : {cmd : 'info', targets : Object.keys(toChkTh)},						preventDefault : true					}).done(function(data) {						if (data && data.files) {							$.each(data.files, function(i, dir) {								if (dir.mime === 'directory' && dir.write) {									delete toChkTh[dir.hash];								}							});						}					}).always(function() {						$.each(toChkTh, trashDisable);					});				}				// to enable / disable				self[self.options.enableAlways? 'enable' : 'disable']();			});				// self.timeEnd('load');		// End of bootUp()	};		// call bootCallback function with elFinder instance, extraObject - { dfrdsBeforeBootup: dfrdsBeforeBootup }	if (bootCallback && typeof bootCallback === 'function') {		self.bootCallback = bootCallback;		bootCallback.call(node.get(0), self, { dfrdsBeforeBootup: dfrdsBeforeBootup });	}		// call dfrdsBeforeBootup functions then boot up elFinder	$.when.apply(null, dfrdsBeforeBootup).done(function() {		bootUp();	}).fail(function(error) {		self.error(error);	});};//register elFinder to global scopeif (typeof toGlobal === 'undefined' || toGlobal) {	window.elFinder = elFinder;}/** * Prototype *  * @type  Object */elFinder.prototype = {		uniqueid : 0,		res : function(type, id) {		return this.resources[type] && this.resources[type][id];	}, 	/**	 * User os. Required to bind native shortcuts for open/rename	 *	 * @type String	 **/	OS : navigator.userAgent.indexOf('Mac') !== -1 ? 'mac' : navigator.userAgent.indexOf('Win') !== -1  ? 'win' : 'other',		/**	 * User browser UA.	 * jQuery.browser: version deprecated: 1.3, removed: 1.9	 *	 * @type Object	 **/	UA : (function(){		var self = this,			webkit = !document.unqueID && !window.opera && !window.sidebar && window.localStorage && 'WebkitAppearance' in document.documentElement.style,			chrome = webkit && window.chrome,			/*setRotated = function() {				var a = ((screen && screen.orientation && screen.orientation.angle) || window.orientation || 0) + 0;				if (a === -90) {					a = 270;				}				UA.Angle = a;				UA.Rotated = a % 180 === 0? false : true;			},*/			UA = {				// Browser IE <= IE 6				ltIE6   : typeof window.addEventListener == "undefined" && typeof document.documentElement.style.maxHeight == "undefined",				// Browser IE <= IE 7				ltIE7   : typeof window.addEventListener == "undefined" && typeof document.querySelectorAll == "undefined",				// Browser IE <= IE 8				ltIE8   : typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined",				// Browser IE <= IE 9				ltIE9  : document.uniqueID && document.documentMode <= 9,				// Browser IE <= IE 10				ltIE10  : document.uniqueID && document.documentMode <= 10,				// Browser IE >= IE 11				gtIE11  : document.uniqueID && document.documentMode >= 11,				IE      : document.uniqueID,				Firefox : window.sidebar,				Opera   : window.opera,				Webkit  : webkit,				Chrome  : chrome,				Edge    : (chrome && window.msCredentials)? true : false,				Safari  : webkit && !window.chrome,				Mobile  : typeof window.orientation != "undefined",				Touch   : typeof window.ontouchstart != "undefined",				iOS     : navigator.platform.match(/^iP(?:[ao]d|hone)/),				Fullscreen : (typeof (document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen) !== 'undefined'),				Angle   : 0,				Rotated : false,				CSS : (function() {					var aStyle = document.createElement('a').style,						pStyle = document.createElement('p').style,						css;					css = 'position:sticky;position:-webkit-sticky;';					css += 'width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:max-content;';					aStyle.cssText = css;					return {						positionSticky : aStyle.position.indexOf('sticky')!==-1,						widthMaxContent : aStyle.width.indexOf('max-content')!==-1,						flex : typeof pStyle.flex !== 'undefined'					};				})()			};			return UA;	})(),		/**	 * Has RequireJS?	 * 	 * @type Boolean	 */	hasRequire : (typeof define === 'function' && define.amd),		/**	 * Current request command	 * 	 * @type  String	 */	currentReqCmd : '',		/**	 * Current keyboard state	 * 	 * @type  Object	 */	keyState : {},		/**	 * Internationalization object	 * 	 * @type  Object	 */	i18 : {		en : {			translator      : '',			language        : 'English',			direction       : 'ltr',			dateFormat      : 'd.m.Y H:i',			fancyDateFormat : '$1 H:i',			nonameDateFormat : 'ymd-His',			messages        : {}		},		months : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],		monthsShort : ['msJan', 'msFeb', 'msMar', 'msApr', 'msMay', 'msJun', 'msJul', 'msAug', 'msSep', 'msOct', 'msNov', 'msDec'],		days : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],		daysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']	},		/**	 * File mimetype to kind mapping	 * 	 * @type  Object	 */	kinds : 	{			'unknown'                       : 'Unknown',			'directory'                     : 'Folder',			'group'                         : 'Selects',			'symlink'                       : 'Alias',			'symlink-broken'                : 'AliasBroken',			'application/x-empty'           : 'TextPlain',			'application/postscript'        : 'Postscript',			'application/vnd.ms-office'     : 'MsOffice',			'application/msword'            : 'MsWord',			'application/vnd.ms-word'       : 'MsWord',			'application/vnd.openxmlformats-officedocument.wordprocessingml.document' : 'MsWord',			'application/vnd.ms-word.document.macroEnabled.12'                        : 'MsWord',			'application/vnd.openxmlformats-officedocument.wordprocessingml.template' : 'MsWord',			'application/vnd.ms-word.template.macroEnabled.12'                        : 'MsWord',			'application/vnd.ms-excel'      : 'MsExcel',			'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'       : 'MsExcel',			'application/vnd.ms-excel.sheet.macroEnabled.12'                          : 'MsExcel',			'application/vnd.openxmlformats-officedocument.spreadsheetml.template'    : 'MsExcel',			'application/vnd.ms-excel.template.macroEnabled.12'                       : 'MsExcel',			'application/vnd.ms-excel.sheet.binary.macroEnabled.12'                   : 'MsExcel',			'application/vnd.ms-excel.addin.macroEnabled.12'                          : 'MsExcel',			'application/vnd.ms-powerpoint' : 'MsPP',			'application/vnd.openxmlformats-officedocument.presentationml.presentation' : 'MsPP',			'application/vnd.ms-powerpoint.presentation.macroEnabled.12'              : 'MsPP',			'application/vnd.openxmlformats-officedocument.presentationml.slideshow'  : 'MsPP',			'application/vnd.ms-powerpoint.slideshow.macroEnabled.12'                 : 'MsPP',			'application/vnd.openxmlformats-officedocument.presentationml.template'   : 'MsPP',			'application/vnd.ms-powerpoint.template.macroEnabled.12'                  : 'MsPP',			'application/vnd.ms-powerpoint.addin.macroEnabled.12'                     : 'MsPP',			'application/vnd.openxmlformats-officedocument.presentationml.slide'      : 'MsPP',			'application/vnd.ms-powerpoint.slide.macroEnabled.12'                     : 'MsPP',			'application/pdf'               : 'PDF',			'application/xml'               : 'XML',			'application/vnd.oasis.opendocument.text' : 'OO',			'application/vnd.oasis.opendocument.text-template'         : 'OO',			'application/vnd.oasis.opendocument.text-web'              : 'OO',			'application/vnd.oasis.opendocument.text-master'           : 'OO',			'application/vnd.oasis.opendocument.graphics'              : 'OO',			'application/vnd.oasis.opendocument.graphics-template'     : 'OO',			'application/vnd.oasis.opendocument.presentation'          : 'OO',			'application/vnd.oasis.opendocument.presentation-template' : 'OO',			'application/vnd.oasis.opendocument.spreadsheet'           : 'OO',			'application/vnd.oasis.opendocument.spreadsheet-template'  : 'OO',			'application/vnd.oasis.opendocument.chart'                 : 'OO',			'application/vnd.oasis.opendocument.formula'               : 'OO',			'application/vnd.oasis.opendocument.database'              : 'OO',			'application/vnd.oasis.opendocument.image'                 : 'OO',			'application/vnd.openofficeorg.extension'                  : 'OO',			'application/x-shockwave-flash' : 'AppFlash',			'application/flash-video'       : 'Flash video',			'application/x-bittorrent'      : 'Torrent',			'application/javascript'        : 'JS',			'application/rtf'               : 'RTF',			'application/rtfd'              : 'RTF',			'application/x-font-ttf'        : 'TTF',			'application/x-font-otf'        : 'OTF',			'application/x-rpm'             : 'RPM',			'application/x-web-config'      : 'TextPlain',			'application/xhtml+xml'         : 'HTML',			'application/docbook+xml'       : 'DOCBOOK',			'application/x-awk'             : 'AWK',			'application/x-gzip'            : 'GZIP',			'application/x-bzip2'           : 'BZIP',			'application/x-xz'              : 'XZ',			'application/zip'               : 'ZIP',			'application/x-zip'               : 'ZIP',			'application/x-rar'             : 'RAR',			'application/x-tar'             : 'TAR',			'application/x-7z-compressed'   : '7z',			'application/x-jar'             : 'JAR',			'text/plain'                    : 'TextPlain',			'text/x-php'                    : 'PHP',			'text/html'                     : 'HTML',			'text/javascript'               : 'JS',			'text/css'                      : 'CSS',			'text/rtf'                      : 'RTF',			'text/rtfd'                     : 'RTF',			'text/x-c'                      : 'C',			'text/x-csrc'                   : 'C',			'text/x-chdr'                   : 'CHeader',			'text/x-c++'                    : 'CPP',			'text/x-c++src'                 : 'CPP',			'text/x-c++hdr'                 : 'CPPHeader',			'text/x-shellscript'            : 'Shell',			'application/x-csh'             : 'Shell',			'text/x-python'                 : 'Python',			'text/x-java'                   : 'Java',			'text/x-java-source'            : 'Java',			'text/x-ruby'                   : 'Ruby',			'text/x-perl'                   : 'Perl',			'text/x-sql'                    : 'SQL',			'text/xml'                      : 'XML',			'text/x-comma-separated-values' : 'CSV',			'text/x-markdown'               : 'Markdown',			'image/x-ms-bmp'                : 'BMP',			'image/jpeg'                    : 'JPEG',			'image/gif'                     : 'GIF',			'image/png'                     : 'PNG',			'image/tiff'                    : 'TIFF',			'image/x-targa'                 : 'TGA',			'image/vnd.adobe.photoshop'     : 'PSD',			'image/xbm'                     : 'XBITMAP',			'image/pxm'                     : 'PXM',			'audio/mpeg'                    : 'AudioMPEG',			'audio/midi'                    : 'AudioMIDI',			'audio/ogg'                     : 'AudioOGG',			'audio/mp4'                     : 'AudioMPEG4',			'audio/x-m4a'                   : 'AudioMPEG4',			'audio/wav'                     : 'AudioWAV',			'audio/x-mp3-playlist'          : 'AudioPlaylist',			'video/x-dv'                    : 'VideoDV',			'video/mp4'                     : 'VideoMPEG4',			'video/mpeg'                    : 'VideoMPEG',			'video/x-msvideo'               : 'VideoAVI',			'video/quicktime'               : 'VideoMOV',			'video/x-ms-wmv'                : 'VideoWM',			'video/x-flv'                   : 'VideoFlash',			'video/x-matroska'              : 'VideoMKV',			'video/ogg'                     : 'VideoOGG'		},		/**	 * File mimetype to file extention mapping	 * 	 * @type  Object	 * @see   elFinder.mimetypes.js	 */	mimeTypes : {},		/**	 * Ajax request data validation rules	 * 	 * @type  Object	 */	rules : {		defaults : function(data) {			if (!data			|| (data.added && !Array.isArray(data.added))			||  (data.removed && !Array.isArray(data.removed))			||  (data.changed && !Array.isArray(data.changed))) {				return false;			}			return true;		},		open    : function(data) { return data && data.cwd && data.files && $.isPlainObject(data.cwd) && Array.isArray(data.files); },		tree    : function(data) { return data && data.tree && Array.isArray(data.tree); },		parents : function(data) { return data && data.tree && Array.isArray(data.tree); },		tmb     : function(data) { return data && data.images && ($.isPlainObject(data.images) || Array.isArray(data.images)); },		upload  : function(data) { return data && ($.isPlainObject(data.added) || Array.isArray(data.added));},		search  : function(data) { return data && data.files && Array.isArray(data.files); }	},		/**	 * Commands costructors	 *	 * @type Object	 */	commands : {},		/**	 * Commands to add the item (space delimited)	 * 	 * @type String	 */	cmdsToAdd : 'archive duplicate extract mkdir mkfile paste rm upload',		parseUploadData : function(text) {		var self = this,			data;				if (!$.trim(text)) {			return {error : ['errResponse', 'errDataEmpty']};		}				try {			data = JSON.parse(text);		} catch (e) {			return {error : ['errResponse', 'errDataNotJSON']};		}				data = self.normalize(data);		if (!self.validResponse('upload', data)) {			return {error : (response.norError || ['errResponse'])};		}		data.removed = $.merge((data.removed || []), $.map(data.added || [], function(f) { return self.file(f.hash)? f.hash : null; }));		return data;			},		iframeCnt : 0,		uploads : {		// xhr muiti uploading flag		xhrUploading: false,				// Timer of request fail to sync		failSyncTm: null,				// current chunkfail requesting chunk		chunkfailReq: {},				// check file/dir exists		checkExists: function(files, target, fm, isDir) {			var dfrd = $.Deferred(),				names, renames = [], hashes = {}, chkFiles = [],				cancel = function() {					var i = files.length;					while (--i > -1) {						files[i]._remove = true;					}				},				resolve = function() {					dfrd.resolve(renames, hashes);				},				check = function() {					var existed = [], exists = [], i, c,						pathStr = target !== fm.cwd().hash? fm.path(target, true) + fm.option('separator', target) : '',						confirm = function(ndx) {							var last = ndx == exists.length-1,								opts = {									cssClass : 'elfinder-confirm-upload',									title  : fm.i18n('cmdupload'),									text   : ['errExists', pathStr + exists[ndx].name, 'confirmRepl'], 									all    : !last,									accept : {										label    : 'btnYes',										callback : function(all) {											!last && !all												? confirm(++ndx)												: resolve();										}									},									reject : {										label    : 'btnNo',										callback : function(all) {											var i;														if (all) {												i = exists.length;												while (ndx < i--) {													files[exists[i].i]._remove = true;												}											} else {												files[exists[ndx].i]._remove = true;											}														!last && !all												? confirm(++ndx)												: resolve();										}									},									cancel : {										label    : 'btnCancel',										callback : function() {											cancel();											resolve();										}									},									buttons : [										{											label : 'btnBackup',											cssClass : 'elfinder-confirm-btn-backup',											callback : function(all) {												var i;												if (all) {													i = exists.length;													while (ndx < i--) {														renames.push(exists[i].name);													}												} else {													renames.push(exists[ndx].name);												}												!last && !all													? confirm(++ndx)													: resolve();											}										}									]								};														if (!isDir) {								opts.buttons.push({									label : 'btnRename' + (last? '' : 'All'),									cssClass : 'elfinder-confirm-btn-rename',									callback : function() {										renames = null;										resolve();									}								});							}							if (fm.iframeCnt > 0) {								delete opts.reject;							}							fm.confirm(opts);						};										if (! fm.file(target).read) {						// for dropbox type						resolve();						return;					}										names = $.map(files, function(file, i) { return file.name && (!fm.UA.iOS || file.name !== 'image.jpg')? {i: i, name: file.name} : null ;});										fm.request({						data : {cmd : 'ls', target : target, intersect : $.map(names, function(item) { return item.name;})},						notify : {type : 'preupload', cnt : 1, hideCnt : true},						preventDefault : true					})					.done(function(data) {						var existedArr, cwdItems;						if (data) {							if (data.error) {								cancel();							} else {								if (fm.options.overwriteUploadConfirm && fm.option('uploadOverwrite', target)) {									if (data.list) {										if (Array.isArray(data.list)) {											existed = data.list || [];										} else {											existedArr = [];											existed = $.map(data.list, function(n) {												if (typeof n === 'string') {													return n;												} else {													// support to >=2.1.11 plugin Normalizer, Sanitizer													existedArr = existedArr.concat(n);													return false;												}											});											if (existedArr.length) {												existed = existed.concat(existedArr);											}											hashes = data.list;										}										exists = $.grep(names, function(name){											return $.inArray(name.name, existed) !== -1 ? true : false ;										});										if (exists.length && existed.length && target == fm.cwd().hash) {											cwdItems = $.map(fm.files(target), function(file) { return file.name; } );											if ($.grep(existed, function(n) { 												return $.inArray(n, cwdItems) === -1? true : false;											}).length){												fm.sync();											}										}									}								}							}						}						if (exists.length > 0) {							confirm(0);						} else {							resolve();						}					})					.fail(function(error) {						cancel();						resolve();						error && fm.error(error);					});				};			if (fm.api >= 2.1 && typeof files[0] == 'object') {				check();			} else {				resolve();			}			return dfrd;		},				// check droped contents		checkFile : function(data, fm, target) {			if (!!data.checked || data.type == 'files') {				return data.files;			} else if (data.type == 'data') {				var dfrd = $.Deferred(),				scanDfd = $.Deferred(),				files = [],				paths = [],				dirctorys = [],				processing = 0,				items,				mkdirs = [],				cancel = false,				toArray = function(list) {					return Array.prototype.slice.call(list || [], 0);				},				doScan = function(items) {					var entry, readEntries,						excludes = fm.options.folderUploadExclude[fm.OS] || null,						length = items.length,						check = function() {							if (--processing < 1 && scanDfd.state() === 'pending') {								scanDfd.resolve();							}						},						pushItem = function(file) {							if (! excludes || ! file.name.match(excludes)) {								paths.push(entry.fullPath || '');								files.push(file);							}							check();						},						readEntries = function(dirReader) {							var entries = [],								read = function() {									dirReader.readEntries(function(results) {										if (cancel || !results.length) {											for (var i = 0; i < entries.length; i++) {												if (cancel) {													scanDfd.reject();													break;												}												doScan([entries[i]]);											}											check();										} else {											entries = entries.concat(toArray(results));											read();										}									}, check);								};							read();						};										processing++;					for (var i = 0; i < length; i++) {						if (cancel) {							scanDfd.reject();							break;						}						entry = items[i];						if (entry) {							if (entry.isFile) {								processing++;								entry.file(pushItem, check);							} else if (entry.isDirectory) {								if (fm.api >= 2.1) {									processing++;									mkdirs.push(entry.fullPath);									readEntries(entry.createReader()); // Start reading dirs.								}							}						}					}					check();					return scanDfd;				}, hasDirs;								items = $.map(data.files.items, function(item){					return item.getAsEntry? item.getAsEntry() : item.webkitGetAsEntry();				});				$.each(items, function(i, item) {					if (item.isDirectory) {						hasDirs = true;						return false;					}				});				if (items.length > 0) {					fm.uploads.checkExists(items, target, fm, hasDirs).done(function(renames, hashes){						var dfds = [];						if (fm.options.overwriteUploadConfirm && fm.option('uploadOverwrite', target)) {							if (renames === null) {								data.overwrite = 0;								renames = [];							}							items = $.grep(items, function(item){								var i, bak, hash, dfd, hi;								if (item.isDirectory && renames.length) {									i = $.inArray(item.name, renames);									if (i !== -1) {										renames.splice(i, 1);										bak = fm.uniqueName(item.name + fm.options.backupSuffix , null, '');										$.each(hashes, function(h, name) {											if (item.name == name) {												hash = h;												return false;											}										});										if (! hash) {											hash = fm.fileByName(item.name, target).hash;										}										fm.lockfiles({files : [hash]});										dfd = fm.request({											data   : {cmd : 'rename', target : hash, name : bak},											notify : {type : 'rename', cnt : 1}										})										.fail(function() {											item._remove = true;											fm.sync();										})										.always(function() {											fm.unlockfiles({files : [hash]});										});										dfds.push(dfd);									}								}								return !item._remove? true : false;							});						}						$.when.apply($, dfds).done(function(){							var notifyto, msg,								id = +new Date();														if (items.length > 0) {								msg = fm.escape(items[0].name);								if (items.length > 1) {									msg += ' ... ' + items.length + fm.i18n('items');								}								notifyto = setTimeout(function() {									fm.notify({										type : 'readdir',										id : id,										cnt : 1,										hideCnt: true,										msg : fm.i18n('ntfreaddir') + ' (' + msg + ')',										cancel: function() {											cancel = true;										}									});								}, fm.options.notifyDelay);								doScan(items).done(function() {									notifyto && clearTimeout(notifyto);									fm.notify({type : 'readdir', id: id, cnt : -1});									if (cancel) {										dfrd.reject();									} else {										dfrd.resolve([files, paths, renames, hashes, mkdirs]);									}								}).fail(function() {									dfrd.reject();								});							} else {								dfrd.reject();							}						});					});					return dfrd.promise();				} else {					return dfrd.reject();				}			} else {				var ret = [];				var check = [];				var str = data.files[0];				if (data.type == 'html') {					var tmp = $("<html/>").append($.parseHTML(str.replace(/ src=/ig, ' _elfsrc='))),						atag;					$('img[_elfsrc]', tmp).each(function(){						var url, purl,						self = $(this),						pa = self.closest('a');						if (pa && pa.attr('href') && pa.attr('href').match(/\.(?:jpe?g|gif|bmp|png)/i)) {							purl = pa.attr('href');						}						url = self.attr('_elfsrc');						if (url) {							if (purl) {								$.inArray(purl, ret) == -1 && ret.push(purl);								$.inArray(url, check) == -1 &&  check.push(url);							} else {								$.inArray(url, ret) == -1 && ret.push(url);							}						}						// Probably it's clipboard data						if (ret.length === 1 && ret[0].match(/^data:image\/png/)) {							data.clipdata = true;						}					});					atag = $('a[href]', tmp);					atag.each(function(){						var text, loc,							parseUrl = function(url) {								var a = document.createElement('a');								a.href = url;								return a;							};						if (text = $(this).text()) {							loc = parseUrl($(this).attr('href'));							if (loc.href && loc.href.match(/^(?:ht|f)tp/i) && (atag.length === 1 || ! loc.pathname.match(/(?:\.html?|\/[^\/.]*)$/i) || $.trim(text).match(/\.[a-z0-9-]{1,10}$/i))) {								if ($.inArray(loc.href, ret) == -1 && $.inArray(loc.href, check) == -1) ret.push(loc.href);							}						}					});				} else {					var regex, m, url;					regex = /(http[^<>"{}|\\^\[\]`\s]+)/ig;					while (m = regex.exec(str)) {						url = m[1].replace(/&/g, '&');						if ($.inArray(url, ret) == -1) ret.push(url);					}				}				return ret;			}		},		// upload transport using XMLHttpRequest		xhr : function(data, fm) { 			var self   = fm ? fm : this,				node        = self.getUI(),				xhr         = new XMLHttpRequest(),				notifyto    = null, notifyto2 = null,				dataChecked = data.checked,				isDataType  = (data.isDataType || data.type == 'data'),				target      = (data.target || self.cwd().hash),				dropEvt     = (data.dropEvt || null),				extraData  = data.extraData || null,				chunkEnable = (self.option('uploadMaxConn', target) != -1),				multiMax    = Math.min(5, Math.max(1, self.option('uploadMaxConn', target))),				retryWait   = 10000, // 10 sec				retryMax    = 30, // 10 sec * 30 = 300 secs (Max 5 mins)				retry       = 0,				getFile     = function(files) {					var dfd = $.Deferred(),						file;					if (files.promise) {						files.always(function(f) {							dfd.resolve(Array.isArray(f) && f.length? (isDataType? f[0][0] : f[0]) : {});						});					} else {						dfd.resolve(files.length? (isDataType? files[0][0] : files[0]) : {});					}					return dfd;				},				dfrd   = $.Deferred()					.fail(function(err) {						var error = self.parseError(err),							userAbort;						if (error === 'userabort') {							userAbort = true;							error = void 0;						}						if (files && (self.uploads.xhrUploading || userAbort)) {							// send request om fail							getFile(files).done(function(file) {								if (! file._cid) {									// send sync request									self.uploads.failSyncTm && clearTimeout(self.uploads.failSyncTm);									self.uploads.failSyncTm = setTimeout(function() {										self.sync(target);									}, 1000);								} else if (! self.uploads.chunkfailReq[file._cid]) {									// send chunkfail request									self.uploads.chunkfailReq[file._cid] = true;									setTimeout(function() {										fm.request({											data : {												cmd: 'upload',												target: target,												chunk: file._chunk,												cid: file._cid,												upload: ['chunkfail'],												mimes: 'chunkfail'											},											options : {												type: 'post',												url: self.uploadURL											},											preventDefault: true										}).always(function() {											delete self.uploads.chunkfailReq[file._chunk];										});									}, 1000);								}							});						}						!userAbort && self.sync();						self.uploads.xhrUploading = false;						files = null;						error && self.error(error);					})					.done(function(data) {						self.uploads.xhrUploading = false;						files = null;						if (data) {							self.currentReqCmd = 'upload';							data.warning && self.error(data.warning);							self.updateCache(data);							data.removed && data.removed.length && self.remove(data);							data.added   && data.added.length   && self.add(data);							data.changed && data.changed.length && self.change(data);							self.trigger('upload', data, false);							self.trigger('uploaddone');							if (data.toasts && Array.isArray(data.toasts)) {								$.each(data.toasts, function() {									this.msg && self.toast(this);								});							}							data.sync && self.sync();							data.debug && fm.debug('backend-debug', data);						}					})					.always(function() {						self.abortXHR(xhr);						// unregist fnAbort function						node.off('uploadabort', fnAbort);						$(window).off('unload', fnAbort);						notifyto && clearTimeout(notifyto);						notifyto2 && clearTimeout(notifyto2);						dataChecked && !data.multiupload && checkNotify() && self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});						chunkMerge && notifyElm.children('.elfinder-notify-chunkmerge').length && self.notify({type : 'chunkmerge', cnt : -1});					}),				formData    = new FormData(),				files       = data.input ? data.input.files : self.uploads.checkFile(data, self, target), 				cnt         = data.checked? (isDataType? files[0].length : files.length) : files.length,				loaded      = 0,				prev        = 0,				filesize    = 0,				notify      = false,				notifyElm   = self.ui.notify,				cancelBtn   = true,				abort       = false,				checkNotify = function() {					if (!notify && (ntfUpload = notifyElm.children('.elfinder-notify-upload')).length) {						notify = true;					}					return notify;				},				fnAbort     = function(e, error) {					abort = true;					self.abortXHR(xhr, { quiet: true, abort: true });					dfrd.reject(error);					if (checkNotify()) {						self.notify({type : 'upload', cnt : ntfUpload.data('cnt') * -1, progress : 0, size : 0});					}				},				cancelToggle = function(show) {					ntfUpload.children('.elfinder-notify-cancel')[show? 'show':'hide']();				},				startNotify = function(size) {					if (!size) size = filesize;					return setTimeout(function() {						notify = true;						self.notify({type : 'upload', cnt : cnt, progress : loaded - prev, size : size,							cancel: function() {								node.trigger('uploadabort', 'userabort');							}						});						ntfUpload = notifyElm.children('.elfinder-notify-upload');						prev = loaded;						if (data.multiupload) {							cancelBtn && cancelToggle(true);						} else {							cancelToggle(cancelBtn && loaded < size);						}					}, self.options.notifyDelay);				},				doRetry = function() {					if (retry++ <= retryMax) {						if (checkNotify() && prev) {							self.notify({type : 'upload', cnt : 0, progress : 0, size : prev});						}						self.abortXHR(xhr, { quiet: true });						prev = loaded = 0;						setTimeout(function() {							var reqId;							if (! abort) {								xhr.open('POST', self.uploadURL, true);								if (self.api >= 2.1029) {									reqId = (+ new Date()).toString(16) + Math.floor(1000 * Math.random()).toString(16);									(typeof formData['delete'] === 'function') && formData['delete']('reqid');									formData.append('reqid', reqId);									xhr._requestId = reqId;								}								xhr.send(formData);							}						}, retryWait);					} else {						node.trigger('uploadabort', ['errAbort', 'errTimeout']);					}				},				progress = function() {					var node;					if (notify) {						dfrd.notifyWith(ntfUpload, [{							cnt: ntfUpload.data('cnt'),							progress: ntfUpload.data('progress'),							total: ntfUpload.data('total')						}]);					}				},				renames = (data.renames || null),				hashes = (data.hashes || null),				chunkMerge = false,				ntfUpload = $();						// regist fnAbort function			node.one('uploadabort', fnAbort);			$(window).one('unload.' + fm.namespace, fnAbort);						!chunkMerge && (prev = loaded);						if (!isDataType && !cnt) {				return dfrd.reject(['errUploadNoFiles']);			}						xhr.addEventListener('error', function() {				if (xhr.status == 0) {					if (abort) {						dfrd.reject();					} else {						// ff bug while send zero sized file						// for safari - send directory						if (!isDataType && data.files && $.grep(data.files, function(f){return ! f.type && f.size === (self.UA.Safari? 1802 : 0)? true : false;}).length) {							errors.push('errFolderUpload');							dfrd.reject(['errAbort', 'errFolderUpload']);						} else if (data.input && $.grep(data.input.files, function(f){return ! f.type && f.size === (self.UA.Safari? 1802 : 0)? true : false;}).length) {							dfrd.reject(['errUploadNoFiles']);						} else {							doRetry();						}					}				} else {					node.trigger('uploadabort', 'errConnect');				}			}, false);						xhr.addEventListener('load', function(e) {				var status = xhr.status, res, curr = 0, error = '', errData, errObj;								if (status >= 400) {					if (status > 500) {						error = 'errResponse';					} else {						error = ['errResponse', 'errServerError'];					}				} else {					if (!xhr.responseText) {						error = ['errResponse', 'errDataEmpty'];					}				}								if (error) {					node.trigger('uploadabort');					getFile(files).done(function(file) {						return dfrd.reject(file._cid? null : error);					});				}								loaded = filesize;								if (checkNotify() && (curr = loaded - prev)) {					self.notify({type : 'upload', cnt : 0, progress : curr, size : 0});					progress();				}				res = self.parseUploadData(xhr.responseText);								// chunked upload commit				if (res._chunkmerged) {					formData = new FormData();					var _file = [{_chunkmerged: res._chunkmerged, _name: res._name, _mtime: res._mtime}];					chunkMerge = true;					node.off('uploadabort', fnAbort);					notifyto2 = setTimeout(function() {						self.notify({type : 'chunkmerge', cnt : 1});					}, self.options.notifyDelay);					isDataType? send(_file, files[1]) : send(_file);					return;				}								res._multiupload = data.multiupload? true : false;				if (res.error) {					errData = {						cmd: 'upload',						err: res,						xhr: xhr,						rc: xhr.status					};					self.trigger('uploadfail', res);					// trigger "requestError" event					self.trigger('requestError', errData);					if (errData._event && errData._event.isDefaultPrevented()) {						res.error = '';					}					if (res._chunkfailure || res._multiupload) {						abort = true;						self.uploads.xhrUploading = false;						notifyto && clearTimeout(notifyto);						if (ntfUpload.length) {							self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});							dfrd.reject(res);						} else {							// for multi connection							dfrd.reject();						}					} else {						dfrd.reject(res);					}				} else {					dfrd.resolve(res);				}			}, false);						xhr.upload.addEventListener('loadstart', function(e) {				if (!chunkMerge && e.lengthComputable) {					loaded = e.loaded;					retry && (loaded = 0);					filesize = e.total;					if (!loaded) {						loaded = parseInt(filesize * 0.05);					}					if (checkNotify()) {						self.notify({type : 'upload', cnt : 0, progress : loaded - prev, size : data.multiupload? 0 : filesize});						prev = loaded;						progress();					}				}			}, false);						xhr.upload.addEventListener('progress', function(e) {				var curr;				if (e.lengthComputable && !chunkMerge && xhr.readyState < 2) {										loaded = e.loaded;					// to avoid strange bug in safari (not in chrome) with drag&drop.					// bug: macos finder opened in any folder,					// reset safari cache (option+command+e), reload elfinder page,					// drop file from finder					// on first attempt request starts (progress callback called ones) but never ends.					// any next drop - successfull.					if (!data.checked && loaded > 0 && !notifyto) {						notifyto = startNotify(xhr._totalSize - loaded);					}										if (!filesize) {						filesize = e.total;						if (!loaded) {							loaded = parseInt(filesize * 0.05);						}					}										curr = loaded - prev;					if (checkNotify() && (curr/e.total) >= 0.05) {						self.notify({type : 'upload', cnt : 0, progress : curr, size : 0});						prev = loaded;						progress();					}										if (! data.multiupload && loaded >= filesize) {						cancelBtn = false;						cancelToggle(false);					}				}			}, false);						var send = function(files, paths){				var size = 0,				fcnt = 1,				sfiles = [],				c = 0,				total = cnt,				maxFileSize,				totalSize = 0,				chunked = [],				chunkID = new Date().getTime().toString().substr(-9), // for take care of the 32bit backend system				BYTES_PER_CHUNK = Math.min((fm.uplMaxSize? fm.uplMaxSize : 2097152) - 8190, fm.options.uploadMaxChunkSize), // uplMaxSize margin 8kb or options.uploadMaxChunkSize				blobSlice = chunkEnable? false : '',				blobSize, blobMtime, i, start, end, chunks, blob, chunk, added, done, last, failChunk,				multi = function(files, num){					var sfiles = [], cid, sfilesLen = 0, cancelChk;					if (!abort) {						while(files.length && sfiles.length < num) {							sfiles.push(files.shift());						}						sfilesLen = sfiles.length;						if (sfilesLen) {							cancelChk = sfilesLen;							for (var i=0; i < sfilesLen; i++) {								if (abort) {									break;								}								cid = isDataType? (sfiles[i][0][0]._cid || null) : (sfiles[i][0]._cid || null);								if (!!failChunk[cid]) {									last--;									continue;								}								fm.exec('upload', {									type: data.type,									isDataType: isDataType,									files: sfiles[i],									checked: true,									target: target,									dropEvt: dropEvt,									renames: renames,									hashes: hashes,									multiupload: true,									overwrite: data.overwrite === 0? 0 : void 0								}, void 0, target)								.fail(function(error) {									if (error && error === 'No such command') {										abort = true;										fm.error(['errUpload', 'errPerm']);									}									if (cid) {											failChunk[cid] = true;									}								})								.always(function(e) {									if (e && e.added) added = $.merge(added, e.added);									if (last <= ++done) {										fm.trigger('multiupload', {added: added});										notifyto && clearTimeout(notifyto);										if (checkNotify()) {											self.notify({type : 'upload', cnt : -cnt, progress : 0, size : 0});										}									}									if (files.length) {										multi(files, 1); // Next one									} else {										if (--cancelChk <= 1) {											cancelBtn = false;											cancelToggle(false);										}									}								});							}						}					}					if (sfiles.length < 1 || abort) {						if (abort) {							notifyto && clearTimeout(notifyto);							if (cid) {								failChunk[cid] = true;							}							dfrd.reject();						} else {							dfrd.resolve();							self.uploads.xhrUploading = false;						}					}				},				check = function(){					if (!self.uploads.xhrUploading) {						self.uploads.xhrUploading = true;						multi(sfiles, multiMax); // Max connection: 3					} else {						setTimeout(check, 100);					}				},				reqId;				if (! dataChecked && (isDataType || data.type == 'files')) {					if (! (maxFileSize = fm.option('uploadMaxSize', target))) {						maxFileSize = 0;					}					for (i=0; i < files.length; i++) {						try {							blob = files[i];							blobSize = blob.size;							if (blobSlice === false) {								blobSlice = '';								if (self.api >= 2.1) {									if ('slice' in blob) {										blobSlice = 'slice';									} else if ('mozSlice' in blob) {										blobSlice = 'mozSlice';									} else if ('webkitSlice' in blob) {										blobSlice = 'webkitSlice';									}								}							}						} catch(e) {							cnt--;							total--;							continue;						}												// file size check						if ((maxFileSize && blobSize > maxFileSize) || (!blobSlice && fm.uplMaxSize && blobSize > fm.uplMaxSize)) {							self.error(['errUploadFile', blob.name, 'errUploadFileSize']);							cnt--;							total--;							continue;						}												// file mime check						if (blob.type && ! self.uploadMimeCheck(blob.type, target)) {							self.error(['errUploadFile', blob.name, 'errUploadMime', '(' + blob.type + ')']);							cnt--;							total--;							continue;						}												if (blobSlice && blobSize > BYTES_PER_CHUNK) {							start = 0;							end = BYTES_PER_CHUNK;							chunks = -1;							total = Math.floor((blobSize - 1) / BYTES_PER_CHUNK);							blobMtime = blob.lastModified? Math.round(blob.lastModified/1000) : 0;							totalSize += blobSize;							chunked[chunkID] = 0;							while(start < blobSize) {								chunk = blob[blobSlice](start, end);								chunk._chunk = blob.name + '.' + (++chunks) + '_' + total + '.part';								chunk._cid   = chunkID;								chunk._range = start + ',' + chunk.size + ',' + blobSize;								chunk._mtime = blobMtime;								chunked[chunkID]++;																if (size) {									c++;								}								if (typeof sfiles[c] == 'undefined') {									sfiles[c] = [];									if (isDataType) {										sfiles[c][0] = [];										sfiles[c][1] = [];									}								}								size = BYTES_PER_CHUNK;								fcnt = 1;								if (isDataType) {									sfiles[c][0].push(chunk);									sfiles[c][1].push(paths[i]);								} else {									sfiles[c].push(chunk);								}								start = end;								end = start + BYTES_PER_CHUNK;							}							if (chunk == null) {								self.error(['errUploadFile', blob.name, 'errUploadFileSize']);								cnt--;								total--;							} else {								total += chunks;								size = 0;								fcnt = 1;								c++;							}							continue;						}						if ((fm.uplMaxSize && size + blobSize > fm.uplMaxSize) || fcnt > fm.uplMaxFile) {							size = 0;							fcnt = 1;							c++;						}						if (typeof sfiles[c] == 'undefined') {							sfiles[c] = [];							if (isDataType) {								sfiles[c][0] = [];								sfiles[c][1] = [];							}						}						if (isDataType) {							sfiles[c][0].push(blob);							sfiles[c][1].push(paths[i]);						} else {							sfiles[c].push(blob);						}						size += blobSize;						totalSize += blobSize;						fcnt++;					}										if (sfiles.length == 0) {						// no data						data.checked = true;						return false;					}										if (sfiles.length > 1) {						// multi upload						notifyto = startNotify(totalSize);						added = [];						done = 0;						last = sfiles.length;						failChunk = [];						check();						return true;					}										// single upload					if (isDataType) {						files = sfiles[0][0];						paths = sfiles[0][1];					} else {						files = sfiles[0];					}				}								if (!dataChecked) {					if (!fm.UA.Safari || !data.files) {						notifyto = startNotify(totalSize);					} else {						xhr._totalSize = totalSize;					}				}								dataChecked = true;								if (! files.length) {					dfrd.reject(['errUploadNoFiles']);				}								xhr.open('POST', self.uploadURL, true);								// set request headers				if (fm.customHeaders) {					$.each(fm.customHeaders, function(key) {						xhr.setRequestHeader(key, this);					});				}								// set xhrFields				if (fm.xhrFields) {					$.each(fm.xhrFields, function(key) {						if (key in xhr) {							xhr[key] = this;						}					});				}				if (self.api >= 2.1029) {					// request ID					reqId = (+ new Date()).toString(16) + Math.floor(1000 * Math.random()).toString(16);					formData.append('reqid', reqId);					xhr._requestId = reqId;				}				formData.append('cmd', 'upload');				formData.append(self.newAPI ? 'target' : 'current', target);				if (renames && renames.length) {					$.each(renames, function(i, v) {						formData.append('renames[]', v);					});					formData.append('suffix', fm.options.backupSuffix);				}				if (hashes) {					$.each(hashes, function(i, v) {						formData.append('hashes['+ i +']', v);					});				}				$.each(self.customData, function(key, val) {					formData.append(key, val);				});				$.each(self.options.onlyMimes, function(i, mime) {					formData.append('mimes[]', mime);				});								$.each(files, function(i, file) {					if (file._chunkmerged) {						formData.append('chunk', file._chunkmerged);						formData.append('upload[]', file._name);						formData.append('mtime[]', file._mtime);					} else {						if (file._chunkfail) {							formData.append('upload[]', 'chunkfail');							formData.append('mimes', 'chunkfail');						} else {							formData.append('upload[]', file);							if (data.clipdata) {								data.overwrite = 0;								formData.append('name[]', fm.date(fm.nonameDateFormat) + '.png');							}							if (file.name && fm.UA.iOS) {								if (file.name.match(/^image\.jpe?g$/i)) {									data.overwrite = 0;									formData.append('name[]', fm.date(fm.nonameDateFormat) + '.jpg');								} else if (file.name.match(/^capturedvideo\.mov$/i)) {									data.overwrite = 0;									formData.append('name[]', fm.date(fm.nonameDateFormat) + '.mov');								}							}						}						if (file._chunk) {							formData.append('chunk', file._chunk);							formData.append('cid'  , file._cid);							formData.append('range', file._range);							formData.append('mtime[]', file._mtime);						} else {							formData.append('mtime[]', file.lastModified? Math.round(file.lastModified/1000) : 0);						}					}				});								if (isDataType) {					$.each(paths, function(i, path) {						formData.append('upload_path[]', path);					});				}								if (data.overwrite === 0) {					formData.append('overwrite', 0);				}								// send int value that which meta key was pressed when dropped  as `dropWith`				if (dropEvt) {					formData.append('dropWith', parseInt(						(dropEvt.altKey  ? '1' : '0')+						(dropEvt.ctrlKey ? '1' : '0')+						(dropEvt.metaKey ? '1' : '0')+						(dropEvt.shiftKey? '1' : '0'), 2));				}								// set extraData on current request				if (extraData) {					$.each(extraData, function(key, val) {						formData.append(key, val);					});				}				xhr.send(formData);								return true;			};						if (! isDataType) {				if (files.length > 0) {					if (! data.clipdata && renames == null) {						var mkdirs = [],							paths = [],							excludes = fm.options.folderUploadExclude[fm.OS] || null;						$.each(files, function(i, file) {							var relPath = file.webkitRelativePath || file.relativePath || '',								idx, rootDir;							if (! relPath) {								return false;							}							if (excludes && file.name.match(excludes)) {								file._remove = true;								relPath = void(0);							} else {								// add '/' as prefix to make same to folder uploading with DnD, see #2607								relPath = '/' + relPath.replace(/\/[^\/]*$/, '').replace(/^\//, '');								if (relPath && $.inArray(relPath, mkdirs) === -1) {									mkdirs.push(relPath);									// checking the root directory to supports <input type="file" webkitdirectory> see #2378									idx = relPath.substr(1).indexOf('/');									if (idx !== -1 && (rootDir = relPath.substr(0, idx + 1)) && $.inArray(rootDir, mkdirs) === -1) {										mkdirs.unshift(rootDir);									}								}							}							paths.push(relPath);						});						renames = [];						hashes = {};						if (mkdirs.length) {							(function() {								var checkDirs = $.map(mkdirs, function(name) { return name.substr(1).indexOf('/') === -1 ? {name: name.substr(1)} : null;}),									cancelDirs = [];								fm.uploads.checkExists(checkDirs, target, fm, true).done(									function(res, res2) {										var dfds = [], dfd, bak, hash;										if (fm.options.overwriteUploadConfirm && fm.option('uploadOverwrite', target)) {											cancelDirs = $.map(checkDirs, function(dir) { return dir._remove? dir.name : null ;} );											checkDirs = $.grep(checkDirs, function(dir) { return !dir._remove? true : false ;} );										}										if (cancelDirs.length) {											$.each(paths.concat(), function(i, path) {												if ($.inArray(path, cancelDirs) === 0) {													files[i]._remove = true;													paths[i] = void(0);												}											});										}										files = $.grep(files, function(file) { return file._remove? false : true; });										paths = $.grep(paths, function(path) { return path === void 0 ? false : true; });										if (checkDirs.length) {											dfd = $.Deferred();											if (res.length) {												$.each(res, function(i, existName) {													// backup													bak = fm.uniqueName(existName + fm.options.backupSuffix , null, '');													$.each(res2, function(h, name) {														if (res[0] == name) {															hash = h;															return false;														}													});													if (! hash) {														hash = fm.fileByName(res[0], target).hash;													}													fm.lockfiles({files : [hash]});													dfds.push(														fm.request({															data   : {cmd : 'rename', target : hash, name : bak},															notify : {type : 'rename', cnt : 1}														})														.fail(function(error) {															dfrd.reject(error);															fm.sync();														})														.always(function() {															fm.unlockfiles({files : [hash]});														})													);												});											} else {												dfds.push(null);											}																						$.when.apply($, dfds).done(function() {												// ensure directories												fm.request({													data   : {cmd : 'mkdir', target : target, dirs : mkdirs},													notify : {type : 'mkdir', cnt : mkdirs.length},													preventFail: true												})												.fail(function(error) {													error = error || ['errUnknown'];													if (error[0] === 'errCmdParams') {														multiMax = 1;													} else {														multiMax = 0;														dfrd.reject(error);													}												})												.done(function(data) {													var rm = false;													if (!data.hashes) {														data.hashes = {};													}													paths = $.map(paths.concat(), function(p, i) {														if (p === '/') {															return target;														} else {															if (data.hashes[p]) {																return data.hashes[p];															} else {																rm = true;																files[i]._remove = true;																return null;															}														}													});													if (rm) {														files = $.grep(files, function(file) { return file._remove? false : true; });													}												})												.always(function(data) {													if (multiMax) {														isDataType = true;														if (! send(files, paths)) {															dfrd.reject();														}													}												});											});										} else {											dfrd.reject();										}									}								);							})();						} else {							fm.uploads.checkExists(files, target, fm).done(								function(res, res2){									if (fm.options.overwriteUploadConfirm && fm.option('uploadOverwrite', target)) {										hashes = res2;										if (res === null) {											data.overwrite = 0;										} else {											renames = res;										}										files = $.grep(files, function(file){return !file._remove? true : false ;});									}									cnt = files.length;									if (cnt > 0) {										if (! send(files)) {											dfrd.reject();										}									} else {										dfrd.reject();									}								}							);						}					} else {						if (! send(files)) {							dfrd.reject();						}					}				} else {					dfrd.reject();				}			} else {				if (dataChecked) {					send(files[0], files[1]);				} else {					files.done(function(result) { // result: [files, paths, renames, hashes, mkdirs]						renames = [];						cnt = result[0].length;						if (cnt) {							if (result[4] && result[4].length) {								// ensure directories								fm.request({									data   : {cmd : 'mkdir', target : target, dirs : result[4]},									notify : {type : 'mkdir', cnt : result[4].length},									preventFail: true								})								.fail(function(error) {									error = error || ['errUnknown'];									if (error[0] === 'errCmdParams') {										multiMax = 1;									} else {										multiMax = 0;										dfrd.reject(error);									}								})								.done(function(data) {									var rm = false;									if (!data.hashes) {										data.hashes = {};									}									result[1] = $.map(result[1], function(p, i) {										p = p.replace(/\/[^\/]*$/, '');										if (p === '') {											return target;										} else {											if (data.hashes[p]) {												return data.hashes[p];											} else {												rm = true;												result[0][i]._remove = true;												return null;											}										}									});									if (rm) {										result[0] = $.grep(result[0], function(file) { return file._remove? false : true; });									}								})								.always(function(data) {									if (multiMax) {										renames = result[2];										hashes = result[3];										send(result[0], result[1]);									}								});								return;							} else {								result[1] = $.map(result[1], function() { return target; });							}							renames = result[2];							hashes = result[3];							send(result[0], result[1]);						} else {							dfrd.reject(['errUploadNoFiles']);						}					}).fail(function(){						dfrd.reject();					});				}			}			return dfrd;		},				// upload transport using iframe		iframe : function(data, fm) { 			var self   = fm ? fm : this,				input  = data.input? data.input : false,				files  = !input ? self.uploads.checkFile(data, self) : false,				dfrd   = $.Deferred()					.fail(function(error) {						error && self.error(error);					}),				name = 'iframe-'+fm.namespace+(++self.iframeCnt),				form = $('<form action="'+self.uploadURL+'" method="post" enctype="multipart/form-data" encoding="multipart/form-data" target="'+name+'" style="display:none"><input type="hidden" name="cmd" value="upload" /></form>'),				msie = this.UA.IE,				// clear timeouts, close notification dialog, remove form/iframe				onload = function() {					abortto  && clearTimeout(abortto);					notifyto && clearTimeout(notifyto);					notify   && self.notify({type : 'upload', cnt : -cnt});										setTimeout(function() {						msie && $('<iframe src="javascript:false;"/>').appendTo(form);						form.remove();						iframe.remove();					}, 100);				},				iframe = $('<iframe src="'+(msie ? 'javascript:false;' : 'about:blank')+'" name="'+name+'" style="position:absolute;left:-1000px;top:-1000px" />')					.on('load', function() {						iframe.off('load')							.on('load', function() {								onload();								// data will be processed in callback response or window onmessage								dfrd.resolve();							});														// notify dialog							notifyto = setTimeout(function() {								notify = true;								self.notify({type : 'upload', cnt : cnt});							}, self.options.notifyDelay);														// emulate abort on timeout							if (self.options.iframeTimeout > 0) {								abortto = setTimeout(function() {									onload();									dfrd.reject([errors.connect, errors.timeout]);								}, self.options.iframeTimeout);							}														form.submit();					}),				target  = (data.target || self.cwd().hash),				names   = [],				dfds    = [],				renames = [],				hashes  = {},				cnt, notify, notifyto, abortto;			if (files && files.length) {				$.each(files, function(i, val) {					form.append('<input type="hidden" name="upload[]" value="'+val+'"/>');				});				cnt = 1;			} else if (input && $(input).is(':file') && $(input).val()) {				if (fm.options.overwriteUploadConfirm && fm.option('uploadOverwrite', target)) {					names = input.files? input.files : [{ name: $(input).val().replace(/^(?:.+[\\\/])?([^\\\/]+)$/, '$1') }];					//names = $.map(names, function(file){return file.name? { name: file.name } : null ;});					dfds.push(self.uploads.checkExists(names, target, self).done(						function(res, res2){							hashes = res2;							if (res === null) {								data.overwrite = 0;							} else{								renames = res;								cnt = $.grep(names, function(file){return !file._remove? true : false ;}).length;								if (cnt != names.length) {									cnt = 0;								}							}						}					));				}				cnt = input.files ? input.files.length : 1;				form.append(input);			} else {				return dfrd.reject();			}						$.when.apply($, dfds).done(function() {				if (cnt < 1) {					return dfrd.reject();				}				form.append('<input type="hidden" name="'+(self.newAPI ? 'target' : 'current')+'" value="'+target+'"/>')					.append('<input type="hidden" name="html" value="1"/>')					.append('<input type="hidden" name="node" value="'+self.id+'"/>')					.append($(input).attr('name', 'upload[]'));								if (renames.length > 0) {					$.each(renames, function(i, rename) {						form.append('<input type="hidden" name="renames[]" value="'+self.escape(rename)+'"/>');					});					form.append('<input type="hidden" name="suffix" value="'+fm.options.backupSuffix+'"/>');				}				if (hashes) {					$.each(renames, function(i, v) {						form.append('<input type="hidden" name="['+i+']" value="'+self.escape(v)+'"/>');					});				}								if (data.overwrite === 0) {					form.append('<input type="hidden" name="overwrite" value="0"/>');				}								$.each(self.options.onlyMimes||[], function(i, mime) {					form.append('<input type="hidden" name="mimes[]" value="'+self.escape(mime)+'"/>');				});								$.each(self.customData, function(key, val) {					form.append('<input type="hidden" name="'+key+'" value="'+self.escape(val)+'"/>');				});								form.appendTo('body');				iframe.appendTo('body');			});						return dfrd;		}	},			/**	 * Bind callback to event(s) The callback is executed at most once per event.	 * To bind to multiply events at once, separate events names by space	 *	 * @param  String    event name	 * @param  Function  callback	 * @param  Boolan    priority first	 * @return elFinder	 */	one : function(ev, callback, priorityFirst) {		var self  = this,			event = ev.toLowerCase(),			h     = function(e, f) {				if (!self.toUnbindEvents[event]) {					self.toUnbindEvents[event] = [];				}				self.toUnbindEvents[event].push({					type: event,					callback: h				});				return (callback.done? callback.done : callback).apply(this, arguments);			};		if (callback.done) {			h = {done: h};		}		return this.bind(event, h, priorityFirst);	},		/**	 * Set/get data into/from localStorage	 *	 * @param  String       key	 * @param  String|void  value	 * @return String|null	 */	localStorage : function(key, val) {		var self   = this,			s      = window.localStorage,			oldkey = 'elfinder-'+(key || '')+this.id, // old key of elFinder < 2.1.6			prefix = window.location.pathname+'-elfinder-',			suffix = this.id,			clrs   = [],			retval, oldval, t, precnt, sufcnt;		// reset this node data		if (typeof(key) === 'undefined') {			precnt = prefix.length;			sufcnt = suffix.length * -1;			$.each(s, function(key) {				if (key.substr(0, precnt) === prefix && key.substr(sufcnt) === suffix) {					clrs.push(key);				}			});			$.each(clrs, function(i, key) {				s.removeItem(key);			});			return true;		}				// new key of elFinder >= 2.1.6		key = prefix+key+suffix;				if (val === null) {			return s.removeItem(key);		}				if (val === void(0) && !(retval = s.getItem(key)) && (oldval = s.getItem(oldkey))) {			val = oldval;			s.removeItem(oldkey);		}				if (val !== void(0)) {			t = typeof val;			if (t !== 'string' && t !== 'number') {				val = JSON.stringify(val);			}			try {				s.setItem(key, val);			} catch (e) {				try {					s.clear();					s.setItem(key, val);				} catch (e) {					self.debug('error', e.toString());				}			}			retval = s.getItem(key);		}		if (retval && (retval.substr(0,1) === '{' || retval.substr(0,1) === '[')) {			try {				return JSON.parse(retval);			} catch(e) {}		}		return retval;	},		/**	 * Get/set cookie	 *	 * @param  String       cookie name	 * @param  String|void  cookie value	 * @return String|null	 */	cookie : function(name, value) {		var d, o, c, i, retval, t;		name = 'elfinder-'+name+this.id;		if (value === void(0)) {			if (document.cookie && document.cookie != '') {				c = document.cookie.split(';');				name += '=';				for (i=0; i<c.length; i++) {					c[i] = $.trim(c[i]);					if (c[i].substring(0, name.length) == name) {						retval = decodeURIComponent(c[i].substring(name.length));						if (retval.substr(0,1) === '{' || retval.substr(0,1) === '[') {							try {								return JSON.parse(retval);							} catch(e) {}						}						return retval;					}				}			}			return null;		}		o = Object.assign({}, this.options.cookie);		if (value === null) {			value = '';			o.expires = -1;		} else {			t = typeof value;			if (t !== 'string' && t !== 'number') {				value = JSON.stringify(value);			}		}		if (typeof(o.expires) == 'number') {			d = new Date();			d.setTime(d.getTime()+(o.expires * 86400000));			o.expires = d;		}		document.cookie = name+'='+encodeURIComponent(value)+'; expires='+o.expires.toUTCString()+(o.path ? '; path='+o.path : '')+(o.domain ? '; domain='+o.domain : '')+(o.secure ? '; secure' : '');		if (value && (value.substr(0,1) === '{' || value.substr(0,1) === '[')) {			try {				return JSON.parse(value);			} catch(e) {}		}		return value;	},		/**	 * Get start directory (by location.hash or last opened directory)	 * 	 * @return String	 */	startDir : function() {		var locHash = window.location.hash;		if (locHash && locHash.match(/^#elf_/)) {			return locHash.replace(/^#elf_/, '');		} else if (this.options.startPathHash) {			return this.options.startPathHash;		} else {			return this.lastDir();		}	},		/**	 * Get/set last opened directory	 * 	 * @param  String|undefined  dir hash	 * @return String	 */	lastDir : function(hash) { 		return this.options.rememberLastDir ? this.storage('lastdir', hash) : '';	},		/**	 * Node for escape html entities in texts	 * 	 * @type jQuery	 */	_node : $('<span/>'),		/**	 * Replace not html-safe symbols to html entities	 * 	 * @param  String  text to escape	 * @return String	 */	escape : function(name) {		return this._node.text(name).html().replace(/"/g, '"').replace(/'/g, ''');	},		/**	 * Cleanup ajax data.	 * For old api convert data into new api format	 * 	 * @param  String  command name	 * @param  Object  data from backend	 * @return Object	 */	normalize : function(data) {		var self   = this,			fileFilter = (function() {				var func, filter;				if (filter = self.options.fileFilter) {					if (typeof filter === 'function') {						func = function(file) {							return filter.call(self, file);						};					} else if (filter instanceof RegExp) {						func = function(file) {							return filter.test(file.name);						};					}				}				return func? func : null;			})(),			chkCmdMap = function(opts) {				// Disable command to replace with other command				var disabled;				if (opts.uiCmdMap) {					if ($.isPlainObject(opts.uiCmdMap) && Object.keys(opts.uiCmdMap).length) {						if (!opts.disabledFlip) {							opts.disabledFlip = {};						}						disabled = opts.disabledFlip;						$.each(opts.uiCmdMap, function(f, t) {							if (t === 'hidden' && !disabled[f]) {								opts.disabled.push(f);								opts.disabledFlip[f] = true;							}						});					} else {						delete opts.uiCmdMap;					}				}			},			normalizeOptions = function(opts) {				var getType = function(v) {					var type = typeof v;					if (type === 'object' && Array.isArray(v)) {						type = 'array';					}					return type;				};				$.each(self.optionProperties, function(k, empty) {					if (empty !== void(0)) {						if (opts[k] && getType(opts[k]) !== getType(empty)) {							opts[k] = empty;						}					}				});				if (opts['disabled']) {					opts['disabledFlip'] = self.arrayFlip(opts['disabled'], true);				} else {					opts['disabledFlip'] = {};				}				return opts;			},			filter = function(file, asMap, type) { 				var res = asMap? file : true,					ign = asMap? null : false,					vid, targetOptions, isRoot, rootNames;								if (file && file.hash && file.name && file.mime) {					if (file.mime === 'application/x-empty') {						file.mime = 'text/plain';					}										isRoot = self.isRoot(file);					if (isRoot && ! file.volumeid) {						self.debug('warning', 'The volume root statuses requires `volumeid` property.');					}					if (isRoot || file.mime === 'directory') {						// Prevention of circular reference						if (file.phash) {							if (file.phash === file.hash) {								error = error.concat(['Parent folder of "$1" is itself.', file.name]);								return ign;							}							if (isRoot && file.volumeid && file.phash.indexOf(file.volumeid) === 0) {								error = error.concat(['Parent folder of "$1" is inner itself.', file.name]);								return ign;							}						}												// set options, tmbUrls for each volume						if (file.volumeid) {							vid = file.volumeid;														if (isRoot) {								// make or update of leaf roots cache								if (file.phash) {									if (! self.leafRoots[file.phash]) {										self.leafRoots[file.phash] = [ file.hash ];									} else {										if ($.inArray(file.hash, self.leafRoots[file.phash]) === -1) {											self.leafRoots[file.phash].push(file.hash);										}									}								}								self.hasVolOptions = true;								if (! self.volOptions[vid]) {									self.volOptions[vid] = {										// set dispInlineRegex										dispInlineRegex: self.options.dispInlineRegex									};								}																targetOptions = self.volOptions[vid];																if (file.options) {									// >= v.2.1.14 has file.options									Object.assign(targetOptions, file.options);								}																// for compat <= v2.1.13								if (file.disabled) {									targetOptions.disabled = file.disabled;									targetOptions.disabledFlip = self.arrayFlip(file.disabled, true);								}								if (file.tmbUrl) {									targetOptions.tmbUrl = file.tmbUrl;								}																// '/' required at the end of url								if (targetOptions.url && targetOptions.url.substr(-1) !== '/') {									targetOptions.url += '/';								}								// check uiCmdMap								chkCmdMap(targetOptions);																// check trash bin hash								if (targetOptions.trashHash) {									if (self.trashes[targetOptions.trashHash] === false) {										delete targetOptions.trashHash;									} else {										self.trashes[targetOptions.trashHash] = file.hash;									}								}																// set immediate properties								$.each(self.optionProperties, function(k) {									if (targetOptions[k]) {										file[k] = targetOptions[k];									}								});								// regist fm.roots								if (type !== 'cwd') {									self.roots[vid] = file.hash;								}								// regist fm.volumeExpires								if (file.expires) {									self.volumeExpires[vid] = file.expires;								}							}														if (prevId !== vid) {								prevId = vid;								i18nFolderName = self.option('i18nFolderName', vid);							}						}												// volume root i18n name						if (isRoot && ! file.i18) {							name = 'volume_' + file.name,							i18 = self.i18n(false, name);								if (name !== i18) {								file.i18 = i18;							}						}												// i18nFolderName						if (i18nFolderName && ! file.i18) {							name = 'folder_' + file.name,							i18 = self.i18n(false, name);								if (name !== i18) {								file.i18 = i18;							}						}												if (isRoot) {							if (rootNames = self.storage('rootNames')) {								if (rootNames[file.hash]) {									file._name = file.name;									file._i18 = file.i18;									file.name = rootNames[file.hash] = rootNames[file.hash];									delete file.i18;								}								self.storage('rootNames', rootNames);							}						}						// lock trash bins holder						if (self.trashes[file.hash]) {							file.locked = true;						}					} else {						if (fileFilter) {							try {								if (! fileFilter(file)) {									return ign;								}							} catch(e) {								self.debug(e);							}						}						if (file.size == 0) {							file.mime = self.getMimetype(file.name, file.mime);						}					}										if (file.options) {						self.optionsByHashes[file.hash] = normalizeOptions(file.options);					}										delete file.options;										return res;				}				return ign;			},			getDescendants = function(hashes) {				var res = [];				$.each(self.files(), function(h, f) {					$.each(self.parents(h), function(i, ph) {						if ($.inArray(ph, hashes) !== -1 && $.inArray(h, hashes) === -1) {							res.push(h);							return false;						}					});				});				return res;			},			applyLeafRootStats = function(dataArr, type) {				$.each(dataArr, function(i, f) {					var pfile, done;					if (self.leafRoots[f.hash]) {						self.applyLeafRootStats(f);					}					// update leaf root parent stat					if (type !== 'change' && f.phash && self.isRoot(f) && (pfile = self.file(f.phash))) {						self.applyLeafRootStats(pfile);						// add to data.changed						if (!data.changed) {							data.changed = [pfile];						} else {							$.each(data.changed, function(i, f) {								if (f.hash === pfile.hash) {									data.changed[i] = pfile;									done = true;									return false;								}							});							if (!done) {								data.changed.push(pfile);							}						}					}				});			},			error = [],			name, i18, i18nFolderName, prevId, cData;				// set cunstom data		if (data.customData && data.customData !== self.prevCustomData) {			self.prevCustomData = data.customData;			try {				cData = JSON.parse(data.customData);				if ($.isPlainObject(cData)) {					self.prevCustomData = cData;					$.each(Object.keys(cData), function(i, key) {						if (cData[key] === null) {							delete cData[key];							delete self.optsCustomData[key];						}					});					self.customData = Object.assign({}, self.optsCustomData, cData);				}			} catch(e) {}		}		if (data.options) {			normalizeOptions(data.options);		}				if (data.cwd) {			if (data.cwd.volumeid && data.options && Object.keys(data.options).length && self.isRoot(data.cwd)) {				self.hasVolOptions = true;				self.volOptions[data.cwd.volumeid] = data.options;			}			data.cwd = filter(data.cwd, true, 'cwd');		}		if (data.files) {			data.files = $.grep(data.files, filter);		} 		if (data.tree) {			data.tree = $.grep(data.tree, filter);		}		if (data.added) {			data.added = $.grep(data.added, filter);		}		if (data.changed) {			data.changed = $.grep(data.changed, filter);		}		if (data.removed && data.removed.length && self.searchStatus.state === 2) {			data.removed = data.removed.concat(getDescendants(data.removed));		}		if (data.api) {			data.init = true;		}		if (Object.keys(self.leafRoots).length) {			data.files && applyLeafRootStats(data.files);			data.tree && applyLeafRootStats(data.tree);			data.added && applyLeafRootStats(data.added);			data.changed && applyLeafRootStats(data.changed, 'change');		}		// merge options that apply only to cwd		if (data.cwd && data.cwd.options && data.options) {			Object.assign(data.options, normalizeOptions(data.cwd.options));		}		// '/' required at the end of url		if (data.options && data.options.url && data.options.url.substr(-1) !== '/') {			data.options.url += '/';		}				// check error		if (error.length) {			data.norError = ['errResponse'].concat(error);		}				return data;	},		/**	 * Update sort options	 *	 * @param {String} sort type	 * @param {String} sort order	 * @param {Boolean} show folder first	 */	setSort : function(type, order, stickFolders, alsoTreeview) {		this.storage('sortType', (this.sortType = this.sortRules[type] ? type : 'name'));		this.storage('sortOrder', (this.sortOrder = /asc|desc/.test(order) ? order : 'asc'));		this.storage('sortStickFolders', (this.sortStickFolders = !!stickFolders) ? 1 : '');		this.storage('sortAlsoTreeview', (this.sortAlsoTreeview = !!alsoTreeview) ? 1 : '');		this.trigger('sortchange');	},		_sortRules : {		name : function(file1, file2) {			return elFinder.prototype.naturalCompare(file1.i18 || file1.name, file2.i18 || file2.name);		},		size : function(file1, file2) { 			var size1 = parseInt(file1.size) || 0,				size2 = parseInt(file2.size) || 0;							return size1 === size2 ? 0 : size1 > size2 ? 1 : -1;		},		kind : function(file1, file2) {			return elFinder.prototype.naturalCompare(file1.mime, file2.mime);		},		date : function(file1, file2) { 			var date1 = file1.ts || file1.date || 0,				date2 = file2.ts || file2.date || 0;			return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;		},		perm : function(file1, file2) { 			var val = function(file) { return (file.write? 2 : 0) + (file.read? 1 : 0); },				v1  = val(file1),				v2  = val(file2);			return v1 === v2 ? 0 : v1 > v2 ? 1 : -1;		},		mode : function(file1, file2) { 			var v1 = file1.mode || (file1.perm || ''),				v2 = file2.mode || (file2.perm || '');			return elFinder.prototype.naturalCompare(v1, v2);		},		owner : function(file1, file2) { 			var v1 = file1.owner || '',				v2 = file2.owner || '';			return elFinder.prototype.naturalCompare(v1, v2);		},		group : function(file1, file2) { 			var v1 = file1.group || '',				v2 = file2.group || '';			return elFinder.prototype.naturalCompare(v1, v2);		}	},		/**	 * Valid sort rule names	 * 	 * @type Object	 */	sorters : {},		/**	 * Compare strings for natural sort	 *	 * @param  String	 * @param  String	 * @return Number	 */	naturalCompare : function(a, b) {		var self = elFinder.prototype.naturalCompare;		if (typeof self.loc == 'undefined') {			self.loc = (navigator.userLanguage || navigator.browserLanguage || navigator.language || 'en-US');		}		if (typeof self.sort == 'undefined') {			if ('11'.localeCompare('2', self.loc, {numeric: true}) > 0) {				// Native support				if (window.Intl && window.Intl.Collator) {					self.sort = new Intl.Collator(self.loc, {numeric: true}).compare;				} else {					self.sort = function(a, b) {						return a.localeCompare(b, self.loc, {numeric: true});					};				}			} else {				/*				 * Edited for elFinder (emulates localeCompare() by numeric) by Naoki Sawada aka nao-pon				 */				/*				 * Huddle/javascript-natural-sort (https://github.com/Huddle/javascript-natural-sort)				 */				/*				 * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license				 * Author: Jim Palmer (based on chunking idea from Dave Koelle)				 * http://opensource.org/licenses/mit-license.php				 */				self.sort = function(a, b) {					var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,					sre = /(^[ ]*|[ ]*$)/g,					dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,					hre = /^0x[0-9a-f]+$/i,					ore = /^0/,					syre = /^[\x01\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\x7e]/, // symbol first - (Naoki Sawada)					i = function(s) { return self.sort.insensitive && (''+s).toLowerCase() || ''+s; },					// convert all to strings strip whitespace					// first character is "_", it's smallest - (Naoki Sawada)					x = i(a).replace(sre, '').replace(/^_/, "\x01") || '',					y = i(b).replace(sre, '').replace(/^_/, "\x01") || '',					// chunk/tokenize					xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),					yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),					// numeric, hex or date detection					xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),					yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null,					oFxNcL, oFyNcL,					locRes = 0;					// first try and sort Hex codes or Dates					if (yD) {						if ( xD < yD ) return -1;						else if ( xD > yD ) return 1;					}					// natural sorting through split numeric strings and default strings					for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {						// find floats not starting with '0', string or 0 if not defined (Clint Priest)						oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;						oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;						// handle numeric vs string comparison - number < string - (Kyle Adams)						// but symbol first < number - (Naoki Sawada)						if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {							if (isNaN(oFxNcL) && (typeof oFxNcL !== 'string' || ! oFxNcL.match(syre))) {								return 1;							} else if (typeof oFyNcL !== 'string' || ! oFyNcL.match(syre)) {								return -1;							}						}						// use decimal number comparison if either value is string zero						if (parseInt(oFxNcL, 10) === 0) oFxNcL = 0;						if (parseInt(oFyNcL, 10) === 0) oFyNcL = 0;						// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'						if (typeof oFxNcL !== typeof oFyNcL) {							oFxNcL += '';							oFyNcL += '';						}						// use locale sensitive sort for strings when case insensitive						// note: localeCompare interleaves uppercase with lowercase (e.g. A,a,B,b)						if (self.sort.insensitive && typeof oFxNcL === 'string' && typeof oFyNcL === 'string') {							locRes = oFxNcL.localeCompare(oFyNcL, self.loc);							if (locRes !== 0) return locRes;						}						if (oFxNcL < oFyNcL) return -1;						if (oFxNcL > oFyNcL) return 1;					}					return 0;				};				self.sort.insensitive = true;			}		}		return self.sort(a, b);	},		/**	 * Compare files based on elFinder.sort	 *	 * @param  Object  file	 * @param  Object  file	 * @return Number	 */	compare : function(file1, file2) {		var self  = this,			type  = self.sortType,			asc   = self.sortOrder == 'asc',			stick = self.sortStickFolders,			rules = self.sortRules,			sort  = rules[type],			d1    = file1.mime == 'directory',			d2    = file2.mime == 'directory',			res;					if (stick) {			if (d1 && !d2) {				return -1;			} else if (!d1 && d2) {				return 1;			}		}				res = asc ? sort(file1, file2) : sort(file2, file1);				return type !== 'name' && res === 0			? res = asc ? rules.name(file1, file2) : rules.name(file2, file1)			: res;	},		/**	 * Sort files based on config	 *	 * @param  Array  files	 * @return Array	 */	sortFiles : function(files) {		return files.sort(this.compare);	},		/**	 * Open notification dialog 	 * and append/update message for required notification type.	 *	 * @param  Object  options	 * @example  	 * this.notify({	 *    type : 'copy',	 *    msg : 'Copy files', // not required for known types @see this.notifyType	 *    cnt : 3,	 *    hideCnt  : false,   // true for not show count	 *    progress : 10,      // progress bar percents (use cnt : 0 to update progress bar)	 *    cancel   : callback // callback function for cancel button	 * })	 * @return elFinder	 */	notify : function(opts) {		var type     = opts.type,			id       = opts.id? 'elfinder-notify-'+opts.id : '',			msg      = this.i18n((typeof opts.msg !== 'undefined')? opts.msg : (this.messages['ntf'+type] ? 'ntf'+type : 'ntfsmth')),			ndialog  = this.ui.notify,			notify   = ndialog.children('.elfinder-notify-'+type+(id? ('.'+id) : '')),			button   = notify.children('div.elfinder-notify-cancel').children('button'),			ntpl     = '<div class="elfinder-notify elfinder-notify-{type}'+(id? (' '+id) : '')+'"><span class="elfinder-dialog-icon elfinder-dialog-icon-{type}"/><span class="elfinder-notify-msg">{msg}</span> <span class="elfinder-notify-cnt"/><div class="elfinder-notify-progressbar"><div class="elfinder-notify-progress"/></div><div class="elfinder-notify-cancel"/></div>',			delta    = opts.cnt,			size     = (typeof opts.size != 'undefined')? parseInt(opts.size) : null,			progress = (typeof opts.progress != 'undefined' && opts.progress >= 0) ? opts.progress : null,			cancel   = opts.cancel,			clhover  = 'ui-state-hover',			close    = function() {				notify._esc && $(document).off('keydown', notify._esc);				notify.remove();				!ndialog.children().length && ndialog.elfinderdialog('close');			},			cnt, total, prc;		if (!type) {			return this;		}				if (!notify.length) {			notify = $(ntpl.replace(/\{type\}/g, type).replace(/\{msg\}/g, msg))				.appendTo(ndialog)				.data('cnt', 0);			if (progress != null) {				notify.data({progress : 0, total : 0});			}			if (cancel) {				button = $('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">'+this.i18n('btnCancel')+'</span></button>')					.on('mouseenter mouseleave', function(e) { 						$(this).toggleClass(clhover, e.type === 'mouseenter');					});				notify.children('div.elfinder-notify-cancel').append(button);			}		} else if (typeof opts.msg !== 'undefined') {			notify.children('span.elfinder-notify-msg').html(msg);		}		cnt = delta + parseInt(notify.data('cnt'));				if (cnt > 0) {			if (cancel && button.length) {				if ($.isFunction(cancel) || (typeof cancel === 'object' && cancel.promise)) {					notify._esc = function(e) {						if (e.type == 'keydown' && e.keyCode != $.ui.keyCode.ESCAPE) {							return;						}						e.preventDefault();						e.stopPropagation();						close();						if (cancel.promise) {							cancel.reject(0); // 0 is canceling flag						} else {							cancel(e);						}					};					button.on('click', function(e) {						notify._esc(e);					});					$(document).on('keydown.' + this.namespace, notify._esc);				}			}						!opts.hideCnt && notify.children('.elfinder-notify-cnt').text('('+cnt+')');			ndialog.is(':hidden') && ndialog.elfinderdialog('open', this).height('auto');			notify.data('cnt', cnt);						if ((progress != null)			&& (total = notify.data('total')) >= 0			&& (prc = notify.data('progress')) >= 0) {				total += size != null? size : delta;				prc   += progress;				(size == null && delta < 0) && (prc += delta * 100);				notify.data({progress : prc, total : total});				if (size != null) {					prc *= 100;					total = Math.max(1, total);				}				progress = parseInt(prc/total);								notify.find('.elfinder-notify-progress')					.animate({						width : (progress < 100 ? progress : 100)+'%'					}, 20);			}					} else {			close();		}				return this;	},		/**	 * Open confirmation dialog 	 *	 * @param  Object  options	 * @example  	 * this.confirm({	 *    cssClass : 'elfinder-confirm-mydialog',	 *    title : 'Remove files',	 *    text  : 'Here is question text',	 *    accept : {  // accept callback - required	 *      label : 'Continue',	 *      callback : function(applyToAll) { fm.log('Ok') }	 *    },	 *    cancel : { // cancel callback - required	 *      label : 'Cancel',	 *      callback : function() { fm.log('Cancel')}	 *    },	 *    reject : { // reject callback - optionally	 *      label : 'No',	 *      callback : function(applyToAll) { fm.log('No')}	 *    },	 *    buttons : [ // additional buttons callback - optionally	 *      {	 *        label : 'Btn1',	 *        callback : function(applyToAll) { fm.log('Btn1')}	 *      }	 *    ],	 *    all : true  // display checkbox "Apply to all"	 * })	 * @return elFinder	 */	confirm : function(opts) {		var self     = this,			complete = false,			options = {				cssClass  : 'elfinder-dialog-confirm',				modal     : true,				resizable : false,				title     : this.i18n(opts.title || 'confirmReq'),				buttons   : {},				close     : function() { 					!complete && opts.cancel.callback();					$(this).elfinderdialog('destroy');				}			},			apply = this.i18n('apllyAll'),			label, checkbox, btnNum;		if (opts.cssClass) {			options.cssClass += ' ' + opts.cssClass;		}		options.buttons[this.i18n(opts.accept.label)] = function() {			opts.accept.callback(!!(checkbox && checkbox.prop('checked')));			complete = true;			$(this).elfinderdialog('close');		};		options.buttons[this.i18n(opts.accept.label)]._cssClass = 'elfinder-confirm-accept';				if (opts.reject) {			options.buttons[this.i18n(opts.reject.label)] = function() {				opts.reject.callback(!!(checkbox && checkbox.prop('checked')));				complete = true;				$(this).elfinderdialog('close');			};			options.buttons[this.i18n(opts.reject.label)]._cssClass = 'elfinder-confirm-reject';		}				if (opts.buttons && opts.buttons.length > 0) {			btnNum = 1;			$.each(opts.buttons, function(i, v){				options.buttons[self.i18n(v.label)] = function() {					v.callback(!!(checkbox && checkbox.prop('checked')));					complete = true;					$(this).elfinderdialog('close');				};				options.buttons[self.i18n(v.label)]._cssClass = 'elfinder-confirm-extbtn' + (btnNum++);				if (v.cssClass) {					options.buttons[self.i18n(v.label)]._cssClass += ' ' + v.cssClass;				}			});		}				options.buttons[this.i18n(opts.cancel.label)] = function() {			$(this).elfinderdialog('close');		};		options.buttons[this.i18n(opts.cancel.label)]._cssClass = 'elfinder-confirm-cancel';				if (opts.all) {			options.create = function() {				var base = $('<div class="elfinder-dialog-confirm-applyall"/>');				checkbox = $('<input type="checkbox" />');				$(this).next().find('.ui-dialog-buttonset')					.prepend(base.append($('<label>'+apply+'</label>').prepend(checkbox)));			};		}				if (opts.optionsCallback && $.isFunction(opts.optionsCallback)) {			opts.optionsCallback(options);		}				return this.dialog('<span class="elfinder-dialog-icon elfinder-dialog-icon-confirm"/>' + this.i18n(opts.text), options);	},		/**	 * Create unique file name in required dir	 * 	 * @param  String  file name	 * @param  String  parent dir hash	 * @param  String  glue	 * @return String	 */	uniqueName : function(prefix, phash, glue) {		var i = 0, ext = '', p, name;				prefix = this.i18n(false, prefix);		phash = phash || this.cwd().hash;		glue = (typeof glue === 'undefined')? ' ' : glue;		if (p = prefix.match(/^(.+)(\.[^.]+)$/)) {			ext    = p[2];			prefix = p[1];		}				name   = prefix+ext;				if (!this.fileByName(name, phash)) {			return name;		}		while (i < 10000) {			name = prefix + glue + (++i) + ext;			if (!this.fileByName(name, phash)) {				return name;			}		}		return prefix + Math.random() + ext;	},		/**	 * Return message translated onto current language	 * Allowed accept HTML element that was wrapped in jQuery object	 * To be careful to XSS vulnerability of HTML element Ex. You should use `fm.escape(file.name)`	 *	 * @param  String|Array  message[s]|Object jQuery	 * @return String	 **/	i18n : function() {		var self = this,			messages = this.messages, 			input    = [],			ignore   = [], 			message = function(m) {				var file;				if (m.indexOf('#') === 0) {					if ((file = self.file(m.substr(1)))) {						return file.name;					}				}				return m;			},			i, j, m, escFunc, start = 0, isErr;				if (arguments.length && arguments[0] === false) {			escFunc = function(m){ return m; };			start = 1;		}		for (i = start; i< arguments.length; i++) {			m = arguments[i];						if (Array.isArray(m)) {				for (j = 0; j < m.length; j++) {					if (m[j] instanceof jQuery) {						// jQuery object is HTML element						input.push(m[j]);					} else if (typeof m[j] !== 'undefined'){						input.push(message('' + m[j]));					}				}			} else if (m instanceof jQuery) {				// jQuery object is HTML element				input.push(m[j]);			} else if (typeof m !== 'undefined'){				input.push(message('' + m));			}		}				for (i = 0; i < input.length; i++) {			// dont translate placeholders			if ($.inArray(i, ignore) !== -1) {				continue;			}			m = input[i];			if (typeof m == 'string') {				isErr = !!(messages[m] && m.match(/^err/));				// translate message				m = messages[m] || (escFunc? escFunc(m) : self.escape(m));				// replace placeholders in message				m = m.replace(/\$(\d+)/g, function(match, placeholder) {					var res;					placeholder = i + parseInt(placeholder);					if (placeholder > 0 && input[placeholder]) {						ignore.push(placeholder);					}					res = escFunc? escFunc(input[placeholder]) : self.escape(input[placeholder]);					if (isErr) {						res = '<span class="elfinder-err-var elfinder-err-var' + placeholder + '">' + res + '</span>';					}					return res;				});			} else {				// get HTML from jQuery object				m = m.get(0).outerHTML;			}			input[i] = m;		}		return $.grep(input, function(m, i) { return $.inArray(i, ignore) === -1 ? true : false; }).join('<br>');	},		/**	 * Get icon style from file.icon	 * 	 * @param  Object  elFinder file object	 * @return String|Object	 */	getIconStyle : function(file, asObject) {		var self = this,			template = {				'background' : 'url(\'{url}\') 0 0 no-repeat',				'background-size' : 'contain'			},			style = '',			cssObj = {},			i = 0;		if (file.icon) {			style = 'style="';			$.each(template, function(k, v) {				if (i++ === 0) {					v = v.replace('{url}', self.escape(file.icon));				}				if (asObject) {					cssObj[k] = v;				} else {					style += k+':'+v+';';				}			});			style += '"';		}		return asObject? cssObj : style;	},		/**	 * Convert mimetype into css classes	 * 	 * @param  String  file mimetype	 * @return String	 */	mime2class : function(mimeType) {		var prefix = 'elfinder-cwd-icon-',			mime   = mimeType.toLowerCase(),			isText = this.textMimes[mime];				mime = mime.split('/');		if (isText) {			mime[0] += ' ' + prefix + 'text';		} else if (mime[1] && mime[1].match(/\+xml$/)) {			mime[0] += ' ' + prefix + 'xml';		}				return prefix + mime[0] + (mime[1] ? ' ' + prefix + mime[1].replace(/(\.|\+)/g, '-') : '');	},		/**	 * Return localized kind of file	 * 	 * @param  Object|String  file or file mimetype	 * @return String	 */	mime2kind : function(f) {		var isObj = typeof(f) == 'object' ? true : false,			mime  = isObj ? f.mime : f,			kind;				if (isObj && f.alias && mime != 'symlink-broken') {			kind = 'Alias';		} else if (this.kinds[mime]) {			if (isObj && mime === 'directory' && (! f.phash || f.isroot)) {				kind = 'Root';			} else {				kind = this.kinds[mime];			}		}		if (! kind) {			if (mime.indexOf('text') === 0) {				kind = 'Text';			} else if (mime.indexOf('image') === 0) {				kind = 'Image';			} else if (mime.indexOf('audio') === 0) {				kind = 'Audio';			} else if (mime.indexOf('video') === 0) {				kind = 'Video';			} else if (mime.indexOf('application') === 0) {				kind = 'App';			} else {				kind = mime;			}		}				return this.messages['kind'+kind] ? this.i18n('kind'+kind) : mime;	},		/**	 * Return boolean Is mime-type text file	 * 	 * @param  String  mime-type	 * @return Boolean	 */	mimeIsText : function(mime) {		return (this.textMimes[mime.toLowerCase()] || (mime.indexOf('text/') === 0 && mime.substr(5, 3) !== 'rtf') || mime.match(/^application\/.+\+xml$/))? true : false;	},		/**	 * Returns a date string formatted according to the given format string	 * 	 * @param  String  format string	 * @param  Object  Date object	 * @return String	 */	date : function(format, date) {		var self = this,			output, d, dw, m, y, h, g, i, s;				if (! date) {			date = new Date();		}				h  = date[self.getHours]();		g  = h > 12 ? h - 12 : h;		i  = date[self.getMinutes]();		s  = date[self.getSeconds]();		d  = date[self.getDate]();		dw = date[self.getDay]();		m  = date[self.getMonth]() + 1;		y  = date[self.getFullYear]();				output = format.replace(/[a-z]/gi, function(val) {			switch (val) {				case 'd': return d > 9 ? d : '0'+d;				case 'j': return d;				case 'D': return self.i18n(self.i18.daysShort[dw]);				case 'l': return self.i18n(self.i18.days[dw]);				case 'm': return m > 9 ? m : '0'+m;				case 'n': return m;				case 'M': return self.i18n(self.i18.monthsShort[m-1]);				case 'F': return self.i18n(self.i18.months[m-1]);				case 'Y': return y;				case 'y': return (''+y).substr(2);				case 'H': return h > 9 ? h : '0'+h;				case 'G': return h;				case 'g': return g;				case 'h': return g > 9 ? g : '0'+g;				case 'a': return h >= 12 ? 'pm' : 'am';				case 'A': return h >= 12 ? 'PM' : 'AM';				case 'i': return i > 9 ? i : '0'+i;				case 's': return s > 9 ? s : '0'+s;			}			return val;		});				return output;	},		/**	 * Return localized date	 * 	 * @param  Object  file object	 * @return String	 */	formatDate : function(file, t) {		var self = this, 			ts   = t || file.ts, 			i18  = self.i18,			date, format, output, d, dw, m, y, h, g, i, s;		if (self.options.clientFormatDate && ts > 0) {			date = new Date(ts*1000);			format = ts >= this.yesterday 				? this.fancyFormat 				: this.dateFormat;			output = self.date(format, date);						return ts >= this.yesterday				? output.replace('$1', this.i18n(ts >= this.today ? 'Today' : 'Yesterday'))				: output;		} else if (file.date) {			return file.date.replace(/([a-z]+)\s/i, function(a1, a2) { return self.i18n(a2)+' '; });		}				return self.i18n('dateUnknown');	},		/**	 * Return localized number string	 * 	 * @param  Number	 * @return String	 */	toLocaleString : function(num) {		var v = new Number(num);		if (v) {			if (v.toLocaleString) {				return v.toLocaleString();			} else {				return String(num).replace( /(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');			}		}		return num;	},		/**	 * Return css class marks file permissions	 * 	 * @param  Object  file 	 * @return String	 */	perms2class : function(o) {		var c = '';				if (!o.read && !o.write) {			c = 'elfinder-na';		} else if (!o.read) {			c = 'elfinder-wo';		} else if (!o.write) {			c = 'elfinder-ro';		}				if (o.type) {			c += ' elfinder-' + this.escape(o.type);		}				return c;	},		/**	 * Return localized string with file permissions	 * 	 * @param  Object  file	 * @return String	 */	formatPermissions : function(f) {		var p  = [];					f.read && p.push(this.i18n('read'));		f.write && p.push(this.i18n('write'));			return p.length ? p.join(' '+this.i18n('and')+' ') : this.i18n('noaccess');	},		/**	 * Return formated file size	 * 	 * @param  Number  file size	 * @return String	 */	formatSize : function(s) {		var n = 1, u = 'b';				if (s == 'unknown') {			return this.i18n('unknown');		}				if (s > 1073741824) {			n = 1073741824;			u = 'GB';		} else if (s > 1048576) {			n = 1048576;			u = 'MB';		} else if (s > 1024) {			n = 1024;			u = 'KB';		}		s = s/n;		return (s > 0 ? n >= 1048576 ? s.toFixed(2) : Math.round(s) : 0) +' '+u;	},		/**	 * Return formated file mode by options.fileModeStyle	 * 	 * @param  String  file mode	 * @param  String  format style	 * @return String	 */	formatFileMode : function(p, style) {		var i, o, s, b, sticy, suid, sgid, str, oct;				if (!style) {			style = this.options.fileModeStyle.toLowerCase();		}		p = $.trim(p);		if (p.match(/[rwxs-]{9}$/i)) {			str = p = p.substr(-9);			if (style == 'string') {				return str;			}			oct = '';			s = 0;			for (i=0; i<7; i=i+3) {				o = p.substr(i, 3);				b = 0;				if (o.match(/[r]/i)) {					b += 4;				}				if (o.match(/[w]/i)) {					b += 2;				}				if (o.match(/[xs]/i)) {					if (o.match(/[xs]/)) {						b += 1;					}					if (o.match(/[s]/i)) {						if (i == 0) {							s += 4;						} else if (i == 3) {							s += 2;						}					}				}				oct += b.toString(8);			}			if (s) {				oct = s.toString(8) + oct;			}		} else {			p = parseInt(p, 8);			oct = p? p.toString(8) : '';			if (!p || style == 'octal') {				return oct;			}			o = p.toString(8);			s = 0;			if (o.length > 3) {				o = o.substr(-4);				s = parseInt(o.substr(0, 1), 8);				o = o.substr(1);			}			sticy = ((s & 1) == 1); // not support			sgid = ((s & 2) == 2);			suid = ((s & 4) == 4);			str = '';			for(i=0; i<3; i++) {				if ((parseInt(o.substr(i, 1), 8) & 4) == 4) {					str += 'r';				} else {					str += '-';				}				if ((parseInt(o.substr(i, 1), 8) & 2) == 2) {					str += 'w';				} else {					str += '-';				}				if ((parseInt(o.substr(i, 1), 8) & 1) == 1) {					str += ((i==0 && suid)||(i==1 && sgid))? 's' : 'x';				} else {					str += '-';				}			}		}		if (style == 'both') {			return str + ' (' + oct + ')';		} else if (style == 'string') {			return str;		} else {			return oct;		}	},		/**	 * Regist this.decodeRawString function	 * 	 * @return void	 */	registRawStringDecoder : function(rawStringDecoder) {		if ($.isFunction(rawStringDecoder)) {			this.decodeRawString = this.options.rawStringDecoder = rawStringDecoder;		}	},		/**	 * Return boolean that uploadable MIME type into target folder	 * 	 * @param  String  mime    MIME type	 * @param  String  target  target folder hash	 * @return Bool	 */	uploadMimeCheck : function(mime, target) {		target = target || this.cwd().hash;		var res   = true, // default is allow			mimeChecker = this.option('uploadMime', target),			allow,			deny,			check = function(checker) {				var ret = false;				if (typeof checker === 'string' && checker.toLowerCase() === 'all') {					ret = true;				} else if (Array.isArray(checker) && checker.length) {					$.each(checker, function(i, v) {						v = v.toLowerCase();						if (v === 'all' || mime.indexOf(v) === 0) {							ret = true;							return false;						}					});				}				return ret;			};		if (mime && $.isPlainObject(mimeChecker)) {			mime = mime.toLowerCase();			allow = check(mimeChecker.allow);			deny = check(mimeChecker.deny);			if (mimeChecker.firstOrder === 'allow') {				res = false; // default is deny				if (! deny && allow === true) { // match only allow					res = true;				}			} else {				res = true; // default is allow				if (deny === true && ! allow) { // match only deny					res = false;				}			}		}		return res;	},		/**	 * call chained sequence of async deferred functions	 * 	 * @param  Array   tasks async functions	 * @return Object  jQuery.Deferred	 */	sequence : function(tasks) {		var l = tasks.length,			chain = function(task, idx) {				++idx;				if (tasks[idx]) {					return chain(task.then(tasks[idx]), idx);				} else {					return task;				}			};		if (l > 1) {			return chain(tasks[0](), 0);		} else {			return tasks[0]();		}	},		/**	 * Reload contents of target URL for clear browser cache	 * 	 * @param  String  url target URL	 * @return Object  jQuery.Deferred	 */	reloadContents : function(url) {		var dfd = $.Deferred(),			ifm;		try {			ifm = $('<iframe width="1" height="1" scrolling="no" frameborder="no" style="position:absolute; top:-1px; left:-1px" crossorigin="use-credentials">')				.attr('src', url)				.one('load', function() {					var ifm = $(this);					try {						this.contentDocument.location.reload(true);						ifm.one('load', function() {							ifm.remove();							dfd.resolve();						});					} catch(e) {						ifm.attr('src', '').attr('src', url).one('load', function() {							ifm.remove();							dfd.resolve();						});					}				})				.appendTo('body');		} catch(e) {			ifm && ifm.remove();			dfd.reject();		}		return dfd;	},		/**	 * Make netmount option for OAuth2	 * 	 * @param  String   protocol	 * @param  String   name	 * @param  String   host	 * @param  Object   opts  Default {noOffline: false, root: 'root', pathI18n: 'folderId', folders: true}			}	 * 	 * @return Object	 */	makeNetmountOptionOauth : function(protocol, name, host, opt) {		var noOffline = typeof opt === 'boolean'? opt : null, // for backward compat			opts = Object.assign({				noOffline : false,				root      : 'root',				pathI18n  : 'folderId',				folders   : true			}, (noOffline === null? (opt || {}) : {noOffline : noOffline})),			addFolders = function(fm, bro, folders) {				var self = this,					cnt  = Object.keys($.isPlainObject(folders)? folders : {}).length,					select;								bro.next().remove();				if (cnt) {					select = $('<select class="ui-corner-all elfinder-tabstop" style="max-width:200px;">').append(						$($.map(folders, function(n,i){return '<option value="'+fm.escape((i+'').trim())+'">'+fm.escape(n)+'</option>';}).join(''))					).on('change click', function(e){						var node = $(this),							path = node.val(),							spn;						self.inputs.path.val(path);						if (opts.folders && (e.type === 'change' || node.data('current') !== path)) {							node.next().remove();							node.data('current', path);							if (path != opts.root) {								spn = spinner();								if (xhr && xhr.state() === 'pending') {									fm.abortXHR(xhr, { quiet: true , abort: true });								}								node.after(spn);								xhr = fm.request({									data : {cmd : 'netmount', protocol: protocol, host: host, user: 'init', path: path, pass: 'folders'},									preventDefault : true								}).done(function(data){									addFolders.call(self, fm, node, data.folders);								}).always(function() {									fm.abortXHR(xhr, { quiet: true });									spn.remove();								}).xhr;							}						}					});					bro.after($('<div/>').append(select))						.closest('.ui-dialog').trigger('tabstopsInit');					select.trigger('focus');				}			},			spinner = function() {				return $('<div class="elfinder-netmount-spinner"/>').append('<span class="elfinder-spinner"/>');			},			xhr;		return {			vars : {},			name : name,			inputs: {				offline  : $('<input type="checkbox"/>').on('change', function() {					$(this).parents('table.elfinder-netmount-tb').find('select:first').trigger('change', 'reset');				}),				host     : $('<span><span class="elfinder-spinner"/></span><input type="hidden"/>'),				path     : $('<input type="text" value="'+opts.root+'"/>'),				user     : $('<input type="hidden"/>'),				pass     : $('<input type="hidden"/>')			},			select: function(fm, ev, d){				var f = this.inputs,					oline = f.offline,					f0 = $(f.host[0]),					data = d || null;				this.vars.mbtn = f.host.closest('.ui-dialog').children('.ui-dialog-buttonpane:first').find('button.elfinder-btncnt-0');				if (! f0.data('inrequest')						&& (f0.find('span.elfinder-spinner').length							|| data === 'reset'							|| (data === 'winfocus' && ! f0.siblings('span.elfinder-button-icon-reload').length))							)				{					if (oline.parent().children().length === 1) {						f.path.parent().prev().html(fm.i18n(opts.pathI18n));						oline.attr('title', fm.i18n('offlineAccess'));						oline.uniqueId().after($('<label/>').attr('for', oline.attr('id')).html(' '+fm.i18n('offlineAccess')));					}					f0.data('inrequest', true).empty().addClass('elfinder-spinner')						.parent().find('span.elfinder-button-icon').remove();					fm.request({						data : {cmd : 'netmount', protocol: protocol, host: host, user: 'init', options: {id: fm.id, offline: oline.prop('checked')? 1:0, pass: f.host[1].value}},						preventDefault : true					}).done(function(data){						f0.removeClass("elfinder-spinner").html(data.body.replace(/\{msg:([^}]+)\}/g, function(whole,s1){return fm.i18n(s1, host);}));					});					opts.noOffline && oline.closest('tr').hide();				} else {					oline.closest('tr')[(opts.noOffline || f.user.val())? 'hide':'show']();					f0.data('funcexpup') && f0.data('funcexpup')();				}				this.vars.mbtn[$(f.host[1]).val()? 'show':'hide']();			},			done: function(fm, data){				var f = this.inputs,					p = this.protocol,					f0 = $(f.host[0]),					f1 = $(f.host[1]),					expires = ' ';								opts.noOffline && f.offline.closest('tr').hide();				if (data.mode == 'makebtn') {					f0.removeClass('elfinder-spinner').removeData('expires').removeData('funcexpup');					f.host.find('input').on('mouseenter mouseleave', function(){$(this).toggleClass('ui-state-hover');});					f1.val('');					f.path.val(opts.root).next().remove();					f.user.val('');					f.pass.val('');					! opts.noOffline && f.offline.closest('tr').show();					this.vars.mbtn.hide();				} else if (data.mode == 'folders') {					if (data.folders) {						addFolders.call(this, fm, f.path.nextAll(':last'), data.folders);					}				} else {					if (data.expires) {						expires = '()';						f0.data('expires', data.expires);					}					f0.html(host + expires).removeClass('elfinder-spinner');					if (data.expires) {						f0.data('funcexpup', function() {							var rem = Math.floor((f0.data('expires') - (+new Date()) / 1000) / 60);							if (rem < 3) {								f0.parent().children('.elfinder-button-icon-reload').click();							} else {								f0.text(f0.text().replace(/\(.*\)/, '('+fm.i18n(['minsLeft', rem])+')'));								setTimeout(function() {									if (f0.is(':visible')) {										f0.data('funcexpup')();									}								}, 60000);							}						});						f0.data('funcexpup')();					}					if (data.reset) {						p.trigger('change', 'reset');						return;					}					f0.parent().append($('<span class="elfinder-button-icon elfinder-button-icon-reload" title="'+fm.i18n('reAuth')+'">')						.on('click', function() {							f1.val('reauth');							p.trigger('change', 'reset');						}));					f1.val(protocol);					this.vars.mbtn.show();					if (data.folders) {						addFolders.call(this, fm, f.path, data.folders);					}					f.user.val('done');					f.pass.val('done');					f.offline.closest('tr').hide();				}				f0.removeData('inrequest');			},			fail: function(fm, err){				$(this.inputs.host[0]).removeData('inrequest');				this.protocol.trigger('change', 'reset');			},			integrateInfo: opts.integrate		};	},		/**	 * Find cwd's nodes from files	 * 	 * @param  Array    files	 * @param  Object   opts   {firstOnly: true|false}	 */	findCwdNodes : function(files, opts) {		var self    = this,			cwd     = this.getUI('cwd'),			cwdHash = this.cwd().hash,			newItem = $();				opts = opts || {};				$.each(files, function(i, f) {			if (f.phash === cwdHash || self.searchStatus.state > 1) {				newItem = newItem.add(cwd.find('#'+self.cwdHash2Id(f.hash)));				if (opts.firstOnly) {					return false;				}			}		});				return newItem;	},		/**	 * Convert from relative URL to abstract URL based on current URL	 * 	 * @param  String  URL	 * @return String	 */	convAbsUrl : function(url) {		if (url.match(/^http/i)) {			return url;		}		if (url.substr(0,2) === '//') {			return window.location.protocol + url;		}		var root = window.location.protocol + '//' + window.location.host,			reg  = /[^\/]+\/\.\.\//,			ret;		if (url.substr(0, 1) === '/') {			ret = root + url;		} else {			ret = root + window.location.pathname.replace(/\/[^\/]+$/, '/') + url;		}		ret = ret.replace('/./', '/');		while(reg.test(ret)) {			ret = ret.replace(reg, '');		}		return ret;	},		/**	 * Is same origin to current site	 * 	 * @param  String  check url	 * @return Boolean	 */	isSameOrigin : function (checkUrl) {		var url;		checkUrl = this.convAbsUrl(checkUrl);		if (location.origin && window.URL) {			try {				url = new URL(checkUrl);				return location.origin === url.origin;			} catch(e) {}		}		url = document.createElement('a');		url.href = checkUrl;		return location.protocol === url.protocol && location.host === url.host && location.port && url.port;	},		navHash2Id : function(hash) {		return this.navPrefix + hash;	},		navId2Hash : function(id) {		return typeof(id) == 'string' ? id.substr(this.navPrefix.length) : false;	},		cwdHash2Id : function(hash) {		return this.cwdPrefix + hash;	},		cwdId2Hash : function(id) {		return typeof(id) == 'string' ? id.substr(this.cwdPrefix.length) : false;	},		isInWindow : function(elem, nochkHide) {		var elm, rect;		if (! (elm = elem.get(0))) {			return false;		}		if (! nochkHide && elm.offsetParent === null) {			return false;		}		rect = elm.getBoundingClientRect();		return document.elementFromPoint(rect.left, rect.top)? true : false;	},		/**	 * calculate elFinder node z-index	 * 	 * @return void	 */	zIndexCalc : function() {		var self = this,			node = this.getUI(),			ni = node.css('z-index');		if (ni && ni !== 'auto' && ni !== 'inherit') {			self.zIndex = ni;		} else {			node.parents().each(function(i, n) {				var z = $(n).css('z-index');				if (z !== 'auto' && z !== 'inherit' && (z = parseInt(z))) {					self.zIndex = z;					return false;				}			});		}	},		/**	 * Load JavaScript files	 * 	 * @param  Array    urls      to load JavaScript file URLs	 * @param  Function callback  call back function on script loaded	 * @param  Object   opts      Additional options to $.ajax OR {loadType: 'tag'} to load by script tag	 * @param  Object   check     { obj: (Object)ParentObject, name: (String)"Attribute name", timeout: (Integer)milliseconds }	 * @return elFinder	 */	loadScript : function(urls, callback, opts, check) {		var defOpts = {				dataType : 'script',				cache    : true			},			success, cnt, scripts = {}, results = {};				opts = opts || {};		if (opts.tryRequire && this.hasRequire) {			require(urls, callback, opts.error);		} else {			success = function() {				var cnt, fi, hasError;				$.each(results, function(i, status) {					if (status !== 'success' && status !== 'notmodified') {						hasError = true;						return false;					}				});				if (!hasError) {					if ($.isFunction(callback)) {						if (check) {							if (typeof check.obj[check.name] === 'undefined') {								cnt = check.timeout? (check.timeout / 10) : 1;								fi = setInterval(function() {									if (--cnt < 0 || typeof check.obj[check.name] !== 'undefined') {										clearInterval(fi);										callback();									}								}, 10);							} else {								callback();							}						} else {							callback();						}					}				} else {					if (opts.error && $.isFunction(opts.error)) {						opts.error({ loadResults: results });					}				}			};			if (opts.loadType === 'tag') {				$('head > script').each(function() {					scripts[this.src] = this;				});				cnt = urls.length;				$.each(urls, function(i, url) {					var done = false,						script;										if (scripts[url]) {						results[i] = scripts[url]._error || 'success';						(--cnt < 1) && success();					} else {						script = document.createElement('script');						script.charset = opts.charset || 'UTF-8';						$('head').append(script);						script.onload = script.onreadystatechange = function() {							if ( !done && (!this.readyState ||									this.readyState === 'loaded' || this.readyState === 'complete') ) {								done = true;								results[i] = 'success';								(--cnt < 1) && success();							}						};						script.onerror = function(err) {							results[i] = script._error = (err && err.type)? err.type : 'error';							(--cnt < 1) && success();						};						script.src = url;					}				});			} else {				opts = $.isPlainObject(opts)? Object.assign(defOpts, opts) : defOpts;				cnt = 0;				(function appendScript(d, status) {					if (d !== void(0)) {						results[cnt++] = status;					}					if (urls.length) {						$.ajax(Object.assign({}, opts, {							url: urls.shift(),							success: appendScript,							error: appendScript						}));					} else {						success();					}				})();			}		}		return this;	},		/**	 * Load CSS files	 * 	 * @param  Array    to load CSS file URLs	 * @param  Object   options	 * @return elFinder	 */	loadCss : function(urls, opts) {		var self = this,			clName, dfds;		if (typeof urls === 'string') {			urls = [ urls ];		}		if (opts) {			if (opts.className) {				clName = opts.className;			}			if (opts.dfd && opts.dfd.promise) {				dfds = [];			}		}		$.each(urls, function(i, url) {			var link, df;			url = self.convAbsUrl(url).replace(/^https?:/i, '');			if (dfds) {				dfds[i] = $.Deferred();			}			if (! $("head > link[href='+url+']").length) {				link = document.createElement('link');				link.type = 'text/css';				link.rel = 'stylesheet';				link.href = url;				if (clName) {					link.className = clName;				}				if (dfds) {					link.onload = function() {						dfds[i].resolve();					};					link.onerror = function() {						dfds[i].reject();					};				}				$('head').append(link);			} else {				dfds && dfds[i].resolve();			}		});		if (dfds) {			$.when.apply(null, dfds).done(function() {				opts.dfd.resolve();			}).fail(function() {				opts.dfd.reject();			});		}		return this;	},		/**	 * Abortable async job performer	 * 	 * @param func Function	 * @param arr  Array	 * @param opts Object	 * 	 * @return Object $.Deferred that has an extended method _abort()	 */	asyncJob : function(func, arr, opts) {		var dfrd = $.Deferred(),			abortFlg = false,			parms = Object.assign({				interval : 0,				numPerOnce : 1			}, opts || {}),			resArr = [],			vars =[],			curVars = [],			exec,			tm;				dfrd._abort = function(resolve) {			tm && clearTimeout(tm);			vars = [];			abortFlg = true;			if (dfrd.state() === 'pending') {				dfrd[resolve? 'resolve' : 'reject'](resArr);			}		};				dfrd.fail(function() {			dfrd._abort();		}).always(function() {			dfrd._abort = function() {};		});		if (typeof func === 'function' && Array.isArray(arr)) {			vars = arr.concat();			exec = function() {				var i, len, res;				if (abortFlg) {					return;				}				curVars = vars.splice(0, parms.numPerOnce);				len = curVars.length;				for (i = 0; i < len; i++) {					if (abortFlg) {						break;					}					res = func(curVars[i]);					(res !== null) && resArr.push(res);				}				if (abortFlg) {					return;				}				if (vars.length) {					tm = setTimeout(exec, parms.interval);				} else {					dfrd.resolve(resArr);				}			};			if (vars.length) {				tm = setTimeout(exec, 0);			} else {				dfrd.resolve(resArr);			}		} else {			dfrd.reject();		}		return dfrd;	},		getSize : function(targets) {		var self = this,			reqs = [],			tgtlen = targets.length,			dfrd = $.Deferred().fail(function() {				$.each(reqs, function(i, req) {					if (req) {						req.syncOnFail && req.syncOnFail(false);						req.reject();					}				});			}),			getLeafRoots = function(file) {				var targets = [];				if (file.mime === 'directory') {					$.each(self.leafRoots, function(hash, roots) {						var phash;						if (hash === file.hash) {							targets.push.apply(targets, roots);						} else {							phash = (self.file(hash) || {}).phash;							while(phash) {								if (phash === file.hash) {									targets.push.apply(targets, roots);								}								phash = (self.file(phash) || {}).phash;							}						}					});				}				return targets;			},			checkPhash = function(hash) {				var dfd = $.Deferred(),					dir = self.file(hash),					target = dir? dir.phash : hash;				if (target && ! self.file(target)) {					self.request({						data : {							cmd    : 'parents',							target : target						},						preventFail : true					}).done(function() {						self.one('parentsdone', function() {							dfd.resolve();						});					}).fail(function() {						dfd.resolve();					});				} else {					dfd.resolve();				}				return dfd;			},			cache = function() {				var dfd = $.Deferred(),					cnt = Object.keys(self.leafRoots).length;								if (cnt > 0) {					$.each(self.leafRoots, function(hash) {						checkPhash(hash).done(function() {							--cnt;							if (cnt < 1) {								dfd.resolve();							}						});					});				} else {					dfd.resolve();				}				return dfd;			};		self.autoSync('stop');		cache().done(function() {			var files = [], grps = {}, dfds = [], cache = [], singles = {};						$.each(targets, function() {				files.push.apply(files, getLeafRoots(self.file(this)));			});			targets.push.apply(targets, files);						$.each(targets, function() {				var root = self.root(this),					file = self.file(this);				if (file && (file.sizeInfo || file.mime !== 'directory')) {					cache.push($.Deferred().resolve(file.sizeInfo? file.sizeInfo : {size: file.size, dirCnt: 0, fileCnt : 1}));				} else {					if (! grps[root]) {						grps[root] = [ this ];					} else {						grps[root].push(this);					}				}			});						$.each(grps, function() {				var idx = dfds.length;				if (this.length === 1) {					singles[idx] = this[0];				}				dfds.push(self.request({					data : {cmd : 'size', targets : this},					preventDefault : true				}));			});			reqs.push.apply(reqs, dfds);			dfds.push.apply(dfds, cache);						$.when.apply($, dfds).fail(function() {				dfrd.reject();			}).done(function() {				var cache = function(h, data) {						var file;						if (file = self.file(h)) {							file.sizeInfo = { isCache: true };							$.each(['size', 'dirCnt', 'fileCnt'], function() {								file.sizeInfo[this] = data[this] || 0;							});							file.size = parseInt(file.sizeInfo.size);							changed.push(file);						}					},					size = 0,					fileCnt = 0,					dirCnt = 0,					argLen = arguments.length,					cnts = [],					cntsTxt = '',					changed = [],					i, file, data;								for (i = 0; i < argLen; i++) {					data = arguments[i];					file = null;					if (!data.isCache) {						if (singles[i] && (file = self.file(singles[i]))) {							cache(singles[i], data);						} else if (data.sizes && $.isPlainObject(data.sizes)) {							$.each(data.sizes, function(h, sizeInfo) {								cache(h, sizeInfo);							});						}					}					size += parseInt(data.size);					if (fileCnt !== false) {						if (typeof data.fileCnt === 'undefined') {							fileCnt = false;						}						fileCnt += parseInt(data.fileCnt || 0);					}					if (dirCnt !== false) {						if (typeof data.dirCnt === 'undefined') {							dirCnt = false;						}						dirCnt += parseInt(data.dirCnt || 0);					}				}				changed.length && self.change({changed: changed});								if (dirCnt !== false){					cnts.push(self.i18n('folders') + ': ' + (dirCnt - (tgtlen > 1? 0 : 1)));				}				if (fileCnt !== false){					cnts.push(self.i18n('files') + ': ' + fileCnt);				}				if (cnts.length) {					cntsTxt = '<br>' + cnts.join(', ');				}				dfrd.resolve({					size: size,					fileCnt: fileCnt,					dirCnt: dirCnt,					formated: (size >= 0 ? self.formatSize(size) : self.i18n('unknown')) + cntsTxt				});			});						self.autoSync();		});				return dfrd;	},		/**	 * Gets the theme object by settings of options.themes	 *	 * @param  String  themeid  The themeid	 * @return Object  jQuery.Deferred	 */	getTheme : function(themeid) {		var self = this,			dfd = $.Deferred(),			absUrl = function(url, base) {				if (Array.isArray(url)) {					return $.map(url, function(v) {						return absUrl(v, base);					});				} else {					return url.match(/^(?:http|\/\/)/i)? url : (base || self.baseUrl) + url.replace(/^(?:\.\/|\/)/, '');				}			},			themeObj, m;		if (themeid && (themeObj = self.options.themes[themeid])) {			if (typeof themeObj === 'string') {				url = absUrl(themeObj);				if (m = url.match(/^(.+\/)[^/]+\.json$/i)) {					$.getJSON(url).done(function(data) {						themeObj = data;						themeObj.id = themeid;						if (themeObj.cssurls) {							themeObj.cssurls = absUrl(themeObj.cssurls, m[1]);						}						dfd.resolve(themeObj);					}).fail(function() {						dfd.reject();					});				} else {					dfd.resolve({						id: themeid,						name: themeid,						cssurls: [url]					});				}			} else if ($.isPlainObject(themeObj) && themeObj.cssurls) {				themeObj.id = themeid;				themeObj.cssurls = absUrl(themeObj.cssurls);				if (!Array.isArray(themeObj.cssurls)) {					themeObj.cssurls = [themeObj.cssurls];				}				if (!themeObj.name) {					themeObj.name = themeid;				}				dfd.resolve(themeObj);			} else {				dfd.reject();			}		} else {			dfd.reject();		}		return dfd;	},	/**	 * Change current theme	 *	 * @param  String  themeid  The themeid	 * @return Object  this elFinder instance	 */	changeTheme : function(themeid) {		var self = this;		if (themeid) {			if (self.options.themes[themeid] && (!self.theme || self.theme.id !== themeid)) {				self.getTheme(themeid).done(function(themeObj) {					if (themeObj.cssurls) {						$('head>link.elfinder-theme-ext').remove();						self.loadCss(themeObj.cssurls, {							className: 'elfinder-theme-ext',							dfd: $.Deferred().done(function() {								self.theme = themeObj;								self.trigger && self.trigger('themechange');							})						});					}				});			} else if (themeid === 'default' && self.theme) {				$('head>link.elfinder-theme-ext').remove();				self.theme = null;				self.trigger && self.trigger('themechange');			}		}		return this;	},	/**	 * Apply leaf root stats to target directory	 *	 * @param      object     dir     object of target directory	 * @param      boolean    update  is force update	 * 	 * @return     boolean    dir object was chenged 	 */	applyLeafRootStats : function(dir, update) {		var self = this,			prev = update? dir : (self.file(dir.hash) || dir),			prevTs = prev.ts,			change = false;		// backup original stats		if (update || !dir._realStats) {			dir._realStats = {				locked: dir.locked || 0,				dirs: dir.dirs || 0,				ts: dir.ts			};		}		// set lock		dir.locked = 1;		if (!prev.locked) {			change = true;		}		// has leaf root to `dirs: 1`		dir.dirs = 1;		if (!prev.dirs) {			change = true;		}		// set ts		$.each(self.leafRoots[dir.hash], function() {			var f = self.file(this);			if (f && f.ts && (dir.ts || 0) < f.ts) {				dir.ts = f.ts;			}		});		if (prevTs !== dir.ts) {			change = true;		}		return change;	},	/**	 * To aborted XHR object	 * 	 * @param Object xhr	 * @param Object opts	 * 	 * @return void	 */	abortXHR : function(xhr, o) {		var opts = o || {};				if (xhr) {			opts.quiet && (xhr.quiet = true);			if (opts.abort && xhr._requestId) {				this.request({					data: {						cmd: 'abort',						id: xhr._requestId					},					preventDefault: true				});			}			xhr.abort();			xhr = void 0;		}	},	/**	 * Gets the request identifier	 *	 * @return  String  The request identifier.	 */	getRequestId : function() {		return (+ new Date()).toString(16) + Math.floor(1000 * Math.random()).toString(16);	},		/**	 * Flip key and value of array or object	 * 	 * @param  Array | Object  { a: 1, b: 1, c: 2 }	 * @param  Mixed           Static value	 * @return Object          { 1: "b", 2: "c" }	 */	arrayFlip : function (trans, val) {		var key,			tmpArr = {},			isArr = $.isArray(trans);		for (key in trans) {			if (isArr || trans.hasOwnProperty(key)) {				tmpArr[trans[key]] = val || key;			}		}		return tmpArr;	},		/**	 * Return array ["name without extention", "extention"]	 * 	 * @param String name	 * 	 * @return Array	 * 	 */	splitFileExtention : function(name) {		var m;		if (m = name.match(/^(.+?)?\.((?:tar\.(?:gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(?:gz|bz2)|[a-z0-9]{1,10})$/i)) {			if (typeof m[1] === 'undefined') {				m[1] = '';			}			return [m[1], m[2]];		} else {			return [name, ''];		}	},		/**	 * Slice the ArrayBuffer by sliceSize	 *	 * @param      arraybuffer  arrayBuffer  The array buffer	 * @param      Number       sliceSize    The slice size	 * @return     Array   Array of sleced arraybuffer	 */	sliceArrayBuffer : function(arrayBuffer, sliceSize) {		var segments= [],			fi = 0;		while(fi * sliceSize < arrayBuffer.byteLength){			segments.push(arrayBuffer.slice(fi * sliceSize, (fi + 1) * sliceSize));			fi++;		}		return segments;	},	arrayBufferToBase64 : function(ab) {		if (!window.btoa) {			return '';		}		var dView = new Uint8Array(ab), // Get a byte view			arr = Array.prototype.slice.call(dView), // Create a normal array			arr1 = arr.map(function(item) {				return String.fromCharCode(item); // Convert			});	    return window.btoa(arr1.join('')); // Form a string	},	log : function(m) { window.console && window.console.log && window.console.log(m); return this; },		debug : function(type, m) {		var d = this.options.debug;		if (d && (d === 'all' || d[type])) {			window.console && window.console.log && window.console.log('elfinder debug: ['+type+'] ['+this.id+']', m);		} 				if (type === 'backend-error') {			if (! this.cwd().hash || (d && (d === 'all' || d['backend-error']))) {				m = Array.isArray(m)? m : [ m ];				this.error(m);			}		} else if (type === 'backend-debug') {			this.trigger('backenddebug', m);		}				return this;	},	time : function(l) { window.console && window.console.time && window.console.time(l); },	timeEnd : function(l) { window.console && window.console.timeEnd && window.console.timeEnd(l); }	};/** * for conpat ex. ie8... * * Object.keys() - JavaScript | MDN * https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys */if (!Object.keys) {	Object.keys = (function () {		var hasOwnProperty = Object.prototype.hasOwnProperty,				hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),				dontEnums = [					'toString',					'toLocaleString',					'valueOf',					'hasOwnProperty',					'isPrototypeOf',					'propertyIsEnumerable',					'constructor'				],				dontEnumsLength = dontEnums.length;		return function (obj) {			if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');			var result = [];			for (var prop in obj) {				if (hasOwnProperty.call(obj, prop)) result.push(prop);			}			if (hasDontEnumBug) {				for (var i=0; i < dontEnumsLength; i++) {					if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);				}			}			return result;		};	})();}// Array.isArrayif (!Array.isArray) {	Array.isArray = function(arr) {		return jQuery.isArray(arr);	};}// Object.assignif (!Object.assign) {	Object.assign = function() {		return jQuery.extend.apply(null, arguments);	};}// String.repeatif (!String.prototype.repeat) {	String.prototype.repeat = function(count) {		'use strict';		if (this == null) {			throw new TypeError('can\'t convert ' + this + ' to object');		}		var str = '' + this;		count = +count;		if (count != count) {			count = 0;		}		if (count < 0) {			throw new RangeError('repeat count must be non-negative');		}		if (count == Infinity) {			throw new RangeError('repeat count must be less than infinity');		}		count = Math.floor(count);		if (str.length == 0 || count == 0) {			return '';		}		// Ensuring count is a 31-bit integer allows us to heavily optimize the		// main part. But anyway, most current (August 2014) browsers can't handle		// strings 1 << 28 chars or longer, so:		if (str.length * count >= 1 << 28) {			throw new RangeError('repeat count must not overflow maximum string size');		}		var rpt = '';		for (var i = 0; i < count; i++) {			rpt += str;		}		return rpt;	};}// String.trimif (!String.prototype.trim) {	String.prototype.trim = function() {		return this.replace(/^\s+|\s+$/g, '');	};}// Array.apply(function () {	try {		Array.apply(null, {});		return;	} catch (e) { }	var toString = Object.prototype.toString,		arrayType = '[object Array]',		_apply = Function.prototype.apply,		slice = /*@cc_on @if (@_jscript_version <= 5.8)			function () {				var a = [], i = this.length;				while (i-- > 0) a[i] = this[i];				return a;			}@else@*/Array.prototype.slice/*@end@*/;	Function.prototype.apply = function apply(thisArg, argArray) {		return _apply.call(this, thisArg,			toString.call(argArray) === arrayType ? argArray : slice.call(argArray));	};})();// Array.fromif (!Array.from) {	Array.from = function(obj) {		return obj.length === 1 ? [obj[0]] : Array.apply(null, obj);	};}// window.requestAnimationFrame and window.cancelAnimationFrameif (!window.cancelAnimationFrame) {// http://paulirish.com/2011/requestanimationframe-for-smart-animating/// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel// MIT license(function() {    var lastTime = 0;    var vendors = ['ms', 'moz', 'webkit', 'o'];    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']                                    || window[vendors[x]+'CancelRequestAnimationFrame'];    }     if (!window.requestAnimationFrame)        window.requestAnimationFrame = function(callback, element) {            var currTime = new Date().getTime();            var timeToCall = Math.max(0, 16 - (currTime - lastTime));            var id = window.setTimeout(function() { callback(currTime + timeToCall); },               timeToCall);            lastTime = currTime + timeToCall;            return id;        };     if (!window.cancelAnimationFrame)        window.cancelAnimationFrame = function(id) {            clearTimeout(id);        };}());}/* * File: /js/elFinder.version.js *//** * Application version * * @type String **/elFinder.prototype.version = '2.1.43';/* * File: /js/jquery.elfinder.js *//*** jQuery UI droppable performance tune for elFinder ***/(function(){if ($.ui) {	if ($.ui.ddmanager) {		var origin = $.ui.ddmanager.prepareOffsets;		$.ui.ddmanager.prepareOffsets = function( t, event ) {			var isOutView = function(elem) {				if (elem.is(':hidden')) {					return true;				}				var rect = elem[0].getBoundingClientRect();				return document.elementFromPoint(rect.left, rect.top)? false : true;			};						if (event.type === 'mousedown' || t.options.elfRefresh) {				var i, d,				m = $.ui.ddmanager.droppables[ t.options.scope ] || [],				l = m.length;				for ( i = 0; i < l; i++ ) {					d = m[ i ];					if (d.options.autoDisable && (!d.options.disabled || d.options.autoDisable > 1)) {						d.options.disabled = isOutView(d.element);						d.options.autoDisable = d.options.disabled? 2 : 1;					}				}			}						// call origin function			return origin( t, event );		};	}}})(); /** * * jquery.binarytransport.js * * @description. jQuery ajax transport for making binary data type requests. * @version 1.0  * @author Henry Algus <henryalgus@gmail.com> * */// use this transport for "binary" data type$.ajaxTransport('+binary', function(options, originalOptions, jqXHR) {	// check for conditions and support for blob / arraybuffer response type	if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))	{		var xhr;		return {			// create new XMLHttpRequest			send: function(headers, callback){				// setup all variables				xhr = new XMLHttpRequest();				var url = options.url,					type = options.type,					async = options.async || true,					// blob or arraybuffer. Default is blob					dataType = options.responseType || 'blob',					data = options.data || null,					username = options.username,					password = options.password;									xhr.addEventListener('load', function(){					var data = {};					data[options.dataType] = xhr.response;					// make callback and send data					callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());				});				xhr.open(type, url, async, username, password);								// setup custom headers				for (var i in headers ) {					xhr.setRequestHeader(i, headers[i] );				}				// setuo xhrFields				if (options.xhrFields) {					for (var key in options.xhrFields) {						if (key in xhr) {							xhr[key] = options.xhrFields[key];						}					}				}				xhr.responseType = dataType;				xhr.send(data);			},			abort: function(){				xhr.abort();			}		};	}});/*! * jQuery UI Touch Punch 0.2.3 * * Copyright 2011–2014, Dave Furfero * Dual licensed under the MIT or GPL Version 2 licenses. * * Depends: *	jquery.ui.widget.js *	jquery.ui.mouse.js */(function ($) {  // Detect touch support  $.support.touch = 'ontouchend' in document;  // Ignore browsers without touch support  if (!$.support.touch) {	return;  }  var mouseProto = $.ui.mouse.prototype,	  _mouseInit = mouseProto._mouseInit,	  _mouseDestroy = mouseProto._mouseDestroy,	  touchHandled,	  posX, posY;  /**   * Simulate a mouse event based on a corresponding touch event   * @param {Object} event A touch event   * @param {String} simulatedType The corresponding mouse event   */  function simulateMouseEvent (event, simulatedType) {	// Ignore multi-touch events	if (event.originalEvent.touches.length > 1) {	  return;	}	if (! $(event.currentTarget).hasClass('touch-punch-keep-default')) {		event.preventDefault();	}	var touch = event.originalEvent.changedTouches[0],		simulatedEvent = document.createEvent('MouseEvents');		// Initialize the simulated mouse event using the touch event's coordinates	simulatedEvent.initMouseEvent(	  simulatedType,	// type	  true,				// bubbles					  	  true,				// cancelable				  	  window,			// view						  	  1,				// detail					  	  touch.screenX,	// screenX					  	  touch.screenY,	// screenY					  	  touch.clientX,	// clientX					  	  touch.clientY,	// clientY					  	  false,			// ctrlKey					  	  false,			// altKey					  	  false,			// shiftKey					  	  false,			// metaKey					  	  0,				// button					  	  null				// relatedTarget			  	);	// Dispatch the simulated event to the target element	event.target.dispatchEvent(simulatedEvent);  }  /**   * Handle the jQuery UI widget's touchstart events   * @param {Object} event The widget element's touchstart event   */  mouseProto._touchStart = function (event) {	var self = this;	// Ignore the event if another widget is already being handled	if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {	  return;	}	// Track element position to avoid "false" move	posX = event.originalEvent.changedTouches[0].screenX.toFixed(0);	posY = event.originalEvent.changedTouches[0].screenY.toFixed(0);	// Set the flag to prevent other widgets from inheriting the touch event	touchHandled = true;	// Track movement to determine if interaction was a click	self._touchMoved = false;	// Simulate the mouseover event	simulateMouseEvent(event, 'mouseover');	// Simulate the mousemove event	simulateMouseEvent(event, 'mousemove');	// Simulate the mousedown event	simulateMouseEvent(event, 'mousedown');  };  /**   * Handle the jQuery UI widget's touchmove events   * @param {Object} event The document's touchmove event   */  mouseProto._touchMove = function (event) {	// Ignore event if not handled	if (!touchHandled) {	  return;	}	// Ignore if it's a "false" move (position not changed)	var x = event.originalEvent.changedTouches[0].screenX.toFixed(0);	var y = event.originalEvent.changedTouches[0].screenY.toFixed(0);	// Ignore if it's a "false" move (position not changed)	if (Math.abs(posX - x) <= 4 && Math.abs(posY - y) <= 4) {		return;	}	// Interaction was not a click	this._touchMoved = true;	// Simulate the mousemove event	simulateMouseEvent(event, 'mousemove');  };  /**   * Handle the jQuery UI widget's touchend events   * @param {Object} event The document's touchend event   */  mouseProto._touchEnd = function (event) {	// Ignore event if not handled	if (!touchHandled) {	  return;	}	// Simulate the mouseup event	simulateMouseEvent(event, 'mouseup');	// Simulate the mouseout event	simulateMouseEvent(event, 'mouseout');	// If the touch interaction did not move, it should trigger a click	if (!this._touchMoved) {	  // Simulate the click event	  simulateMouseEvent(event, 'click');	}	// Unset the flag to allow other widgets to inherit the touch event	touchHandled = false;	this._touchMoved = false;  };  /**   * A duck punch of the $.ui.mouse _mouseInit method to support touch events.   * This method extends the widget with bound touch event handlers that   * translate touch events to mouse events and pass them to the widget's   * original mouse event handling methods.   */  mouseProto._mouseInit = function () {		var self = this;	if (self.element.hasClass('touch-punch')) {		// Delegate the touch handlers to the widget's element		self.element.on({		  touchstart: $.proxy(self, '_touchStart'),		  touchmove: $.proxy(self, '_touchMove'),		  touchend: $.proxy(self, '_touchEnd')		});	}	// Call the original $.ui.mouse init method	_mouseInit.call(self);  };  /**   * Remove the touch event handlers   */  mouseProto._mouseDestroy = function () {		var self = this;	if (self.element.hasClass('touch-punch')) {		// Delegate the touch handlers to the widget's element		self.element.off({		  touchstart: $.proxy(self, '_touchStart'),		  touchmove: $.proxy(self, '_touchMove'),		  touchend: $.proxy(self, '_touchEnd')		});	}	// Call the original $.ui.mouse destroy method	_mouseDestroy.call(self);  };})(jQuery);$.fn.elfinder = function(o, o2) {		if (o === 'instance') {		return this.getElFinder();	}		return this.each(function() {				var cmd          = typeof o  === 'string'  ? o  : '',			bootCallback = typeof o2 === 'function'? o2 : void(0),			opts;				if (!this.elfinder) {			if ($.isPlainObject(o)) {				new elFinder(this, o, bootCallback);			}		} else {			switch(cmd) {				case 'close':				case 'hide':					this.elfinder.hide();					break;									case 'open':				case 'show':					this.elfinder.show();					break;									case 'destroy':					this.elfinder.destroy();					break;								case 'reload':				case 'restart':					if (this.elfinder) {						opts = this.elfinder.options;						bootCallback = this.elfinder.bootCallback;						this.elfinder.destroy();						new elFinder(this, $.extend(true, opts, $.isPlainObject(o2)? o2 : {}), bootCallback);					}					break;			}		}	});};$.fn.getElFinder = function() {	var instance;		this.each(function() {		if (this.elfinder) {			instance = this.elfinder;			return false;		}	});		return instance;};$.fn.elfUiWidgetInstance = function(name) {	try {		return this[name]('instance');	} catch(e) {		// fallback for jQuery UI < 1.11		var data = this.data('ui-' + name);		if (data && typeof data === 'object' && data.widgetFullName === 'ui-' + name) {			return data;		}		return null;	}};// function scrollRightif (! $.fn.scrollRight) {	$.fn.extend({		scrollRight: function (val) {			var node = this.get(0);			if (val === undefined) {				return Math.max(0, node.scrollWidth - (node.scrollLeft + node.clientWidth));			}			return this.scrollLeft(node.scrollWidth - node.clientWidth - val);		}	});}// function scrollBottomif (! $.fn.scrollBottom) {	$.fn.extend({		scrollBottom: function(val) { 			var node = this.get(0);			if (val === undefined) {				return Math.max(0, node.scrollHeight - (node.scrollTop + node.clientHeight));			}			return this.scrollTop(node.scrollHeight - node.clientHeight - val);		}	});}/* * File: /js/elFinder.mimetypes.js */elFinder.prototype.mimeTypes = {"application\/x-executable":"exe","application\/x-jar":"jar","application\/x-gzip":"gz","application\/x-bzip2":"tbz","application\/x-rar":"rar","text\/x-php":"php","text\/javascript":"js","application\/rtfd":"rtfd","text\/x-python":"py","text\/x-ruby":"rb","text\/x-shellscript":"sh","text\/x-perl":"pl","text\/xml":"xml","text\/x-csrc":"c","text\/x-chdr":"h","text\/x-c++src":"cpp","text\/x-c++hdr":"hh","text\/x-markdown":"md","text\/x-yaml":"yml","image\/x-ms-bmp":"bmp","image\/x-targa":"tga","image\/xbm":"xbm","image\/pxm":"pxm","audio\/wav":"wav","video\/x-dv":"dv","video\/x-ms-wmv":"wm","video\/ogg":"ogm","video\/MP2T":"m2ts","application\/x-mpegURL":"m3u8","application\/dash+xml":"mpd","application\/andrew-inset":"ez","application\/applixware":"aw","application\/atom+xml":"atom","application\/atomcat+xml":"atomcat","application\/atomsvc+xml":"atomsvc","application\/ccxml+xml":"ccxml","application\/cdmi-capability":"cdmia","application\/cdmi-container":"cdmic","application\/cdmi-domain":"cdmid","application\/cdmi-object":"cdmio","application\/cdmi-queue":"cdmiq","application\/cu-seeme":"cu","application\/davmount+xml":"davmount","application\/docbook+xml":"dbk","application\/dssc+der":"dssc","application\/dssc+xml":"xdssc","application\/ecmascript":"ecma","application\/emma+xml":"emma","application\/epub+zip":"epub","application\/exi":"exi","application\/font-tdpfr":"pfr","application\/gml+xml":"gml","application\/gpx+xml":"gpx","application\/gxf":"gxf","application\/hyperstudio":"stk","application\/inkml+xml":"ink","application\/ipfix":"ipfix","application\/java-serialized-object":"ser","application\/java-vm":"class","application\/json":"json","application\/jsonml+json":"jsonml","application\/lost+xml":"lostxml","application\/mac-binhex40":"hqx","application\/mac-compactpro":"cpt","application\/mads+xml":"mads","application\/marc":"mrc","application\/marcxml+xml":"mrcx","application\/mathematica":"ma","application\/mathml+xml":"mathml","application\/mbox":"mbox","application\/mediaservercontrol+xml":"mscml","application\/metalink+xml":"metalink","application\/metalink4+xml":"meta4","application\/mets+xml":"mets","application\/mods+xml":"mods","application\/mp21":"m21","application\/mp4":"mp4s","application\/msword":"doc","application\/mxf":"mxf","application\/octet-stream":"bin","application\/oda":"oda","application\/oebps-package+xml":"opf","application\/ogg":"ogx","application\/omdoc+xml":"omdoc","application\/onenote":"onetoc","application\/oxps":"oxps","application\/patch-ops-error+xml":"xer","application\/pdf":"pdf","application\/pgp-encrypted":"pgp","application\/pgp-signature":"asc","application\/pics-rules":"prf","application\/pkcs10":"p10","application\/pkcs7-mime":"p7m","application\/pkcs7-signature":"p7s","application\/pkcs8":"p8","application\/pkix-attr-cert":"ac","application\/pkix-cert":"cer","application\/pkix-crl":"crl","application\/pkix-pkipath":"pkipath","application\/pkixcmp":"pki","application\/pls+xml":"pls","application\/postscript":"ai","application\/prs.cww":"cww","application\/pskc+xml":"pskcxml","application\/rdf+xml":"rdf","application\/reginfo+xml":"rif","application\/relax-ng-compact-syntax":"rnc","application\/resource-lists+xml":"rl","application\/resource-lists-diff+xml":"rld","application\/rls-services+xml":"rs","application\/rpki-ghostbusters":"gbr","application\/rpki-manifest":"mft","application\/rpki-roa":"roa","application\/rsd+xml":"rsd","application\/rss+xml":"rss","application\/rtf":"rtf","application\/sbml+xml":"sbml","application\/scvp-cv-request":"scq","application\/scvp-cv-response":"scs","application\/scvp-vp-request":"spq","application\/scvp-vp-response":"spp","application\/sdp":"sdp","application\/set-payment-initiation":"setpay","application\/set-registration-initiation":"setreg","application\/shf+xml":"shf","application\/smil+xml":"smi","application\/sparql-query":"rq","application\/sparql-results+xml":"srx","application\/srgs":"gram","application\/srgs+xml":"grxml","application\/sru+xml":"sru","application\/ssdl+xml":"ssdl","application\/ssml+xml":"ssml","application\/tei+xml":"tei","application\/thraud+xml":"tfi","application\/timestamped-data":"tsd","application\/vnd.3gpp.pic-bw-large":"plb","application\/vnd.3gpp.pic-bw-small":"psb","application\/vnd.3gpp.pic-bw-var":"pvb","application\/vnd.3gpp2.tcap":"tcap","application\/vnd.3m.post-it-notes":"pwn","application\/vnd.accpac.simply.aso":"aso","application\/vnd.accpac.simply.imp":"imp","application\/vnd.acucobol":"acu","application\/vnd.acucorp":"atc","application\/vnd.adobe.air-application-installer-package+zip":"air","application\/vnd.adobe.formscentral.fcdt":"fcdt","application\/vnd.adobe.fxp":"fxp","application\/vnd.adobe.xdp+xml":"xdp","application\/vnd.adobe.xfdf":"xfdf","application\/vnd.ahead.space":"ahead","application\/vnd.airzip.filesecure.azf":"azf","application\/vnd.airzip.filesecure.azs":"azs","application\/vnd.amazon.ebook":"azw","application\/vnd.americandynamics.acc":"acc","application\/vnd.amiga.ami":"ami","application\/vnd.android.package-archive":"apk","application\/vnd.anser-web-certificate-issue-initiation":"cii","application\/vnd.anser-web-funds-transfer-initiation":"fti","application\/vnd.antix.game-component":"atx","application\/vnd.apple.installer+xml":"mpkg","application\/vnd.aristanetworks.swi":"swi","application\/vnd.astraea-software.iota":"iota","application\/vnd.audiograph":"aep","application\/vnd.blueice.multipass":"mpm","application\/vnd.bmi":"bmi","application\/vnd.businessobjects":"rep","application\/vnd.chemdraw+xml":"cdxml","application\/vnd.chipnuts.karaoke-mmd":"mmd","application\/vnd.cinderella":"cdy","application\/vnd.claymore":"cla","application\/vnd.cloanto.rp9":"rp9","application\/vnd.clonk.c4group":"c4g","application\/vnd.cluetrust.cartomobile-config":"c11amc","application\/vnd.cluetrust.cartomobile-config-pkg":"c11amz","application\/vnd.commonspace":"csp","application\/vnd.contact.cmsg":"cdbcmsg","application\/vnd.cosmocaller":"cmc","application\/vnd.crick.clicker":"clkx","application\/vnd.crick.clicker.keyboard":"clkk","application\/vnd.crick.clicker.palette":"clkp","application\/vnd.crick.clicker.template":"clkt","application\/vnd.crick.clicker.wordbank":"clkw","application\/vnd.criticaltools.wbs+xml":"wbs","application\/vnd.ctc-posml":"pml","application\/vnd.cups-ppd":"ppd","application\/vnd.curl.car":"car","application\/vnd.curl.pcurl":"pcurl","application\/vnd.dart":"dart","application\/vnd.data-vision.rdz":"rdz","application\/vnd.dece.data":"uvf","application\/vnd.dece.ttml+xml":"uvt","application\/vnd.dece.unspecified":"uvx","application\/vnd.dece.zip":"uvz","application\/vnd.denovo.fcselayout-link":"fe_launch","application\/vnd.dna":"dna","application\/vnd.dolby.mlp":"mlp","application\/vnd.dpgraph":"dpg","application\/vnd.dreamfactory":"dfac","application\/vnd.ds-keypoint":"kpxx","application\/vnd.dvb.ait":"ait","application\/vnd.dvb.service":"svc","application\/vnd.dynageo":"geo","application\/vnd.ecowin.chart":"mag","application\/vnd.enliven":"nml","application\/vnd.epson.esf":"esf","application\/vnd.epson.msf":"msf","application\/vnd.epson.quickanime":"qam","application\/vnd.epson.salt":"slt","application\/vnd.epson.ssf":"ssf","application\/vnd.eszigno3+xml":"es3","application\/vnd.ezpix-album":"ez2","application\/vnd.ezpix-package":"ez3","application\/vnd.fdf":"fdf","application\/vnd.fdsn.mseed":"mseed","application\/vnd.fdsn.seed":"seed","application\/vnd.flographit":"gph","application\/vnd.fluxtime.clip":"ftc","application\/vnd.framemaker":"fm","application\/vnd.frogans.fnc":"fnc","application\/vnd.frogans.ltf":"ltf","application\/vnd.fsc.weblaunch":"fsc","application\/vnd.fujitsu.oasys":"oas","application\/vnd.fujitsu.oasys2":"oa2","application\/vnd.fujitsu.oasys3":"oa3","application\/vnd.fujitsu.oasysgp":"fg5","application\/vnd.fujitsu.oasysprs":"bh2","application\/vnd.fujixerox.ddd":"ddd","application\/vnd.fujixerox.docuworks":"xdw","application\/vnd.fujixerox.docuworks.binder":"xbd","application\/vnd.fuzzysheet":"fzs","application\/vnd.genomatix.tuxedo":"txd","application\/vnd.geogebra.file":"ggb","application\/vnd.geogebra.tool":"ggt","application\/vnd.geometry-explorer":"gex","application\/vnd.geonext":"gxt","application\/vnd.geoplan":"g2w","application\/vnd.geospace":"g3w","application\/vnd.gmx":"gmx","application\/vnd.google-earth.kml+xml":"kml","application\/vnd.google-earth.kmz":"kmz","application\/vnd.grafeq":"gqf","application\/vnd.groove-account":"gac","application\/vnd.groove-help":"ghf","application\/vnd.groove-identity-message":"gim","application\/vnd.groove-injector":"grv","application\/vnd.groove-tool-message":"gtm","application\/vnd.groove-tool-template":"tpl","application\/vnd.groove-vcard":"vcg","application\/vnd.hal+xml":"hal","application\/vnd.handheld-entertainment+xml":"zmm","application\/vnd.hbci":"hbci","application\/vnd.hhe.lesson-player":"les","application\/vnd.hp-hpgl":"hpgl","application\/vnd.hp-hpid":"hpid","application\/vnd.hp-hps":"hps","application\/vnd.hp-jlyt":"jlt","application\/vnd.hp-pcl":"pcl","application\/vnd.hp-pclxl":"pclxl","application\/vnd.hydrostatix.sof-data":"sfd-hdstx","application\/vnd.ibm.minipay":"mpy","application\/vnd.ibm.modcap":"afp","application\/vnd.ibm.rights-management":"irm","application\/vnd.ibm.secure-container":"sc","application\/vnd.iccprofile":"icc","application\/vnd.igloader":"igl","application\/vnd.immervision-ivp":"ivp","application\/vnd.immervision-ivu":"ivu","application\/vnd.insors.igm":"igm","application\/vnd.intercon.formnet":"xpw","application\/vnd.intergeo":"i2g","application\/vnd.intu.qbo":"qbo","application\/vnd.intu.qfx":"qfx","application\/vnd.ipunplugged.rcprofile":"rcprofile","application\/vnd.irepository.package+xml":"irp","application\/vnd.is-xpr":"xpr","application\/vnd.isac.fcs":"fcs","application\/vnd.jam":"jam","application\/vnd.jcp.javame.midlet-rms":"rms","application\/vnd.jisp":"jisp","application\/vnd.joost.joda-archive":"joda","application\/vnd.kahootz":"ktz","application\/vnd.kde.karbon":"karbon","application\/vnd.kde.kchart":"chrt","application\/vnd.kde.kformula":"kfo","application\/vnd.kde.kivio":"flw","application\/vnd.kde.kontour":"kon","application\/vnd.kde.kpresenter":"kpr","application\/vnd.kde.kspread":"ksp","application\/vnd.kde.kword":"kwd","application\/vnd.kenameaapp":"htke","application\/vnd.kidspiration":"kia","application\/vnd.kinar":"kne","application\/vnd.koan":"skp","application\/vnd.kodak-descriptor":"sse","application\/vnd.las.las+xml":"lasxml","application\/vnd.llamagraphics.life-balance.desktop":"lbd","application\/vnd.llamagraphics.life-balance.exchange+xml":"lbe","application\/vnd.lotus-1-2-3":123,"application\/vnd.lotus-approach":"apr","application\/vnd.lotus-freelance":"pre","application\/vnd.lotus-notes":"nsf","application\/vnd.lotus-organizer":"org","application\/vnd.lotus-screencam":"scm","application\/vnd.lotus-wordpro":"lwp","application\/vnd.macports.portpkg":"portpkg","application\/vnd.mcd":"mcd","application\/vnd.medcalcdata":"mc1","application\/vnd.mediastation.cdkey":"cdkey","application\/vnd.mfer":"mwf","application\/vnd.mfmp":"mfm","application\/vnd.micrografx.flo":"flo","application\/vnd.micrografx.igx":"igx","application\/vnd.mif":"mif","application\/vnd.mobius.daf":"daf","application\/vnd.mobius.dis":"dis","application\/vnd.mobius.mbk":"mbk","application\/vnd.mobius.mqy":"mqy","application\/vnd.mobius.msl":"msl","application\/vnd.mobius.plc":"plc","application\/vnd.mobius.txf":"txf","application\/vnd.mophun.application":"mpn","application\/vnd.mophun.certificate":"mpc","application\/vnd.mozilla.xul+xml":"xul","application\/vnd.ms-artgalry":"cil","application\/vnd.ms-cab-compressed":"cab","application\/vnd.ms-excel":"xls","application\/vnd.ms-excel.addin.macroenabled.12":"xlam","application\/vnd.ms-excel.sheet.binary.macroenabled.12":"xlsb","application\/vnd.ms-excel.sheet.macroenabled.12":"xlsm","application\/vnd.ms-excel.template.macroenabled.12":"xltm","application\/vnd.ms-fontobject":"eot","application\/vnd.ms-htmlhelp":"chm","application\/vnd.ms-ims":"ims","application\/vnd.ms-lrm":"lrm","application\/vnd.ms-officetheme":"thmx","application\/vnd.ms-pki.seccat":"cat","application\/vnd.ms-pki.stl":"stl","application\/vnd.ms-powerpoint":"ppt","application\/vnd.ms-powerpoint.addin.macroenabled.12":"ppam","application\/vnd.ms-powerpoint.presentation.macroenabled.12":"pptm","application\/vnd.ms-powerpoint.slide.macroenabled.12":"sldm","application\/vnd.ms-powerpoint.slideshow.macroenabled.12":"ppsm","application\/vnd.ms-powerpoint.template.macroenabled.12":"potm","application\/vnd.ms-project":"mpp","application\/vnd.ms-word.document.macroenabled.12":"docm","application\/vnd.ms-word.template.macroenabled.12":"dotm","application\/vnd.ms-works":"wps","application\/vnd.ms-wpl":"wpl","application\/vnd.ms-xpsdocument":"xps","application\/vnd.mseq":"mseq","application\/vnd.musician":"mus","application\/vnd.muvee.style":"msty","application\/vnd.mynfc":"taglet","application\/vnd.neurolanguage.nlu":"nlu","application\/vnd.nitf":"ntf","application\/vnd.noblenet-directory":"nnd","application\/vnd.noblenet-sealer":"nns","application\/vnd.noblenet-web":"nnw","application\/vnd.nokia.n-gage.data":"ngdat","application\/vnd.nokia.n-gage.symbian.install":"n-gage","application\/vnd.nokia.radio-preset":"rpst","application\/vnd.nokia.radio-presets":"rpss","application\/vnd.novadigm.edm":"edm","application\/vnd.novadigm.edx":"edx","application\/vnd.novadigm.ext":"ext","application\/vnd.oasis.opendocument.chart":"odc","application\/vnd.oasis.opendocument.chart-template":"otc","application\/vnd.oasis.opendocument.database":"odb","application\/vnd.oasis.opendocument.formula":"odf","application\/vnd.oasis.opendocument.formula-template":"odft","application\/vnd.oasis.opendocument.graphics":"odg","application\/vnd.oasis.opendocument.graphics-template":"otg","application\/vnd.oasis.opendocument.image":"odi","application\/vnd.oasis.opendocument.image-template":"oti","application\/vnd.oasis.opendocument.presentation":"odp","application\/vnd.oasis.opendocument.presentation-template":"otp","application\/vnd.oasis.opendocument.spreadsheet":"ods","application\/vnd.oasis.opendocument.spreadsheet-template":"ots","application\/vnd.oasis.opendocument.text":"odt","application\/vnd.oasis.opendocument.text-master":"odm","application\/vnd.oasis.opendocument.text-template":"ott","application\/vnd.oasis.opendocument.text-web":"oth","application\/vnd.olpc-sugar":"xo","application\/vnd.oma.dd2+xml":"dd2","application\/vnd.openofficeorg.extension":"oxt","application\/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","application\/vnd.openxmlformats-officedocument.presentationml.slide":"sldx","application\/vnd.openxmlformats-officedocument.presentationml.slideshow":"ppsx","application\/vnd.openxmlformats-officedocument.presentationml.template":"potx","application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","application\/vnd.openxmlformats-officedocument.spreadsheetml.template":"xltx","application\/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application\/vnd.openxmlformats-officedocument.wordprocessingml.template":"dotx","application\/vnd.osgeo.mapguide.package":"mgp","application\/vnd.osgi.dp":"dp","application\/vnd.osgi.subsystem":"esa","application\/vnd.palm":"pdb","application\/vnd.pawaafile":"paw","application\/vnd.pg.format":"str","application\/vnd.pg.osasli":"ei6","application\/vnd.picsel":"efif","application\/vnd.pmi.widget":"wg","application\/vnd.pocketlearn":"plf","application\/vnd.powerbuilder6":"pbd","application\/vnd.previewsystems.box":"box","application\/vnd.proteus.magazine":"mgz","application\/vnd.publishare-delta-tree":"qps","application\/vnd.pvi.ptid1":"ptid","application\/vnd.quark.quarkxpress":"qxd","application\/vnd.realvnc.bed":"bed","application\/vnd.recordare.musicxml":"mxl","application\/vnd.recordare.musicxml+xml":"musicxml","application\/vnd.rig.cryptonote":"cryptonote","application\/vnd.rim.cod":"cod","application\/vnd.rn-realmedia":"rm","application\/vnd.rn-realmedia-vbr":"rmvb","application\/vnd.route66.link66+xml":"link66","application\/vnd.sailingtracker.track":"st","application\/vnd.seemail":"see","application\/vnd.sema":"sema","application\/vnd.semd":"semd","application\/vnd.semf":"semf","application\/vnd.shana.informed.formdata":"ifm","application\/vnd.shana.informed.formtemplate":"itp","application\/vnd.shana.informed.interchange":"iif","application\/vnd.shana.informed.package":"ipk","application\/vnd.simtech-mindmapper":"twd","application\/vnd.smaf":"mmf","application\/vnd.smart.teacher":"teacher","application\/vnd.solent.sdkm+xml":"sdkm","application\/vnd.spotfire.dxp":"dxp","application\/vnd.spotfire.sfs":"sfs","application\/vnd.stardivision.calc":"sdc","application\/vnd.stardivision.draw":"sda","application\/vnd.stardivision.impress":"sdd","application\/vnd.stardivision.math":"smf","application\/vnd.stardivision.writer":"sdw","application\/vnd.stardivision.writer-global":"sgl","application\/vnd.stepmania.package":"smzip","application\/vnd.stepmania.stepchart":"sm","application\/vnd.sun.xml.calc":"sxc","application\/vnd.sun.xml.calc.template":"stc","application\/vnd.sun.xml.draw":"sxd","application\/vnd.sun.xml.draw.template":"std","application\/vnd.sun.xml.impress":"sxi","application\/vnd.sun.xml.impress.template":"sti","application\/vnd.sun.xml.math":"sxm","application\/vnd.sun.xml.writer":"sxw","application\/vnd.sun.xml.writer.global":"sxg","application\/vnd.sun.xml.writer.template":"stw","application\/vnd.sus-calendar":"sus","application\/vnd.svd":"svd","application\/vnd.symbian.install":"sis","application\/vnd.syncml+xml":"xsm","application\/vnd.syncml.dm+wbxml":"bdm","application\/vnd.syncml.dm+xml":"xdm","application\/vnd.tao.intent-module-archive":"tao","application\/vnd.tcpdump.pcap":"pcap","application\/vnd.tmobile-livetv":"tmo","application\/vnd.trid.tpt":"tpt","application\/vnd.triscape.mxs":"mxs","application\/vnd.trueapp":"tra","application\/vnd.ufdl":"ufd","application\/vnd.uiq.theme":"utz","application\/vnd.umajin":"umj","application\/vnd.unity":"unityweb","application\/vnd.uoml+xml":"uoml","application\/vnd.vcx":"vcx","application\/vnd.visio":"vsd","application\/vnd.visionary":"vis","application\/vnd.vsf":"vsf","application\/vnd.wap.wbxml":"wbxml","application\/vnd.wap.wmlc":"wmlc","application\/vnd.wap.wmlscriptc":"wmlsc","application\/vnd.webturbo":"wtb","application\/vnd.wolfram.player":"nbp","application\/vnd.wordperfect":"wpd","application\/vnd.wqd":"wqd","application\/vnd.wt.stf":"stf","application\/vnd.xara":"xar","application\/vnd.xfdl":"xfdl","application\/vnd.yamaha.hv-dic":"hvd","application\/vnd.yamaha.hv-script":"hvs","application\/vnd.yamaha.hv-voice":"hvp","application\/vnd.yamaha.openscoreformat":"osf","application\/vnd.yamaha.openscoreformat.osfpvg+xml":"osfpvg","application\/vnd.yamaha.smaf-audio":"saf","application\/vnd.yamaha.smaf-phrase":"spf","application\/vnd.yellowriver-custom-menu":"cmp","application\/vnd.zul":"zir","application\/vnd.zzazz.deck+xml":"zaz","application\/voicexml+xml":"vxml","application\/widget":"wgt","application\/winhlp":"hlp","application\/wsdl+xml":"wsdl","application\/wspolicy+xml":"wspolicy","application\/x-7z-compressed":"7z","application\/x-abiword":"abw","application\/x-ace-compressed":"ace","application\/x-apple-diskimage":"dmg","application\/x-authorware-bin":"aab","application\/x-authorware-map":"aam","application\/x-authorware-seg":"aas","application\/x-bcpio":"bcpio","application\/x-bittorrent":"torrent","application\/x-blorb":"blb","application\/x-bzip":"bz","application\/x-cbr":"cbr","application\/x-cdlink":"vcd","application\/x-cfs-compressed":"cfs","application\/x-chat":"chat","application\/x-chess-pgn":"pgn","application\/x-conference":"nsc","application\/x-cpio":"cpio","application\/x-csh":"csh","application\/x-debian-package":"deb","application\/x-dgc-compressed":"dgc","application\/x-director":"dir","application\/x-doom":"wad","application\/x-dtbncx+xml":"ncx","application\/x-dtbook+xml":"dtb","application\/x-dtbresource+xml":"res","application\/x-dvi":"dvi","application\/x-envoy":"evy","application\/x-eva":"eva","application\/x-font-bdf":"bdf","application\/x-font-ghostscript":"gsf","application\/x-font-linux-psf":"psf","application\/x-font-pcf":"pcf","application\/x-font-snf":"snf","application\/x-font-type1":"pfa","application\/x-freearc":"arc","application\/x-futuresplash":"spl","application\/x-gca-compressed":"gca","application\/x-glulx":"ulx","application\/x-gnumeric":"gnumeric","application\/x-gramps-xml":"gramps","application\/x-gtar":"gtar","application\/x-hdf":"hdf","application\/x-install-instructions":"install","application\/x-iso9660-image":"iso","application\/x-java-jnlp-file":"jnlp","application\/x-latex":"latex","application\/x-lzh-compressed":"lzh","application\/x-mie":"mie","application\/x-mobipocket-ebook":"prc","application\/x-ms-application":"application","application\/x-ms-shortcut":"lnk","application\/x-ms-wmd":"wmd","application\/x-ms-wmz":"wmz","application\/x-ms-xbap":"xbap","application\/x-msaccess":"mdb","application\/x-msbinder":"obd","application\/x-mscardfile":"crd","application\/x-msclip":"clp","application\/x-msdownload":"dll","application\/x-msmediaview":"mvb","application\/x-msmetafile":"wmf","application\/x-msmoney":"mny","application\/x-mspublisher":"pub","application\/x-msschedule":"scd","application\/x-msterminal":"trm","application\/x-mswrite":"wri","application\/x-netcdf":"nc","application\/x-nzb":"nzb","application\/x-pkcs12":"p12","application\/x-pkcs7-certificates":"p7b","application\/x-pkcs7-certreqresp":"p7r","application\/x-research-info-systems":"ris","application\/x-shar":"shar","application\/x-shockwave-flash":"swf","application\/x-silverlight-app":"xap","application\/x-sql":"sql","application\/x-stuffit":"sit","application\/x-stuffitx":"sitx","application\/x-subrip":"srt","application\/x-sv4cpio":"sv4cpio","application\/x-sv4crc":"sv4crc","application\/x-t3vm-image":"t3","application\/x-tads":"gam","application\/x-tar":"tar","application\/x-tcl":"tcl","application\/x-tex":"tex","application\/x-tex-tfm":"tfm","application\/x-texinfo":"texinfo","application\/x-tgif":"obj","application\/x-ustar":"ustar","application\/x-wais-source":"src","application\/x-x509-ca-cert":"der","application\/x-xfig":"fig","application\/x-xliff+xml":"xlf","application\/x-xpinstall":"xpi","application\/x-xz":"xz","application\/x-zmachine":"z1","application\/xaml+xml":"xaml","application\/xcap-diff+xml":"xdf","application\/xenc+xml":"xenc","application\/xhtml+xml":"xhtml","application\/xml":"xsl","application\/xml-dtd":"dtd","application\/xop+xml":"xop","application\/xproc+xml":"xpl","application\/xslt+xml":"xslt","application\/xspf+xml":"xspf","application\/xv+xml":"mxml","application\/yang":"yang","application\/yin+xml":"yin","application\/zip":"zip","audio\/adpcm":"adp","audio\/basic":"au","audio\/midi":"mid","audio\/mp4":"m4a","audio\/mpeg":"mpga","audio\/ogg":"oga","audio\/s3m":"s3m","audio\/silk":"sil","audio\/vnd.dece.audio":"uva","audio\/vnd.digital-winds":"eol","audio\/vnd.dra":"dra","audio\/vnd.dts":"dts","audio\/vnd.dts.hd":"dtshd","audio\/vnd.lucent.voice":"lvp","audio\/vnd.ms-playready.media.pya":"pya","audio\/vnd.nuera.ecelp4800":"ecelp4800","audio\/vnd.nuera.ecelp7470":"ecelp7470","audio\/vnd.nuera.ecelp9600":"ecelp9600","audio\/vnd.rip":"rip","audio\/webm":"weba","audio\/x-aac":"aac","audio\/x-aiff":"aif","audio\/x-caf":"caf","audio\/x-flac":"flac","audio\/x-matroska":"mka","audio\/x-mpegurl":"m3u","audio\/x-ms-wax":"wax","audio\/x-ms-wma":"wma","audio\/x-pn-realaudio":"ram","audio\/x-pn-realaudio-plugin":"rmp","audio\/xm":"xm","chemical\/x-cdx":"cdx","chemical\/x-cif":"cif","chemical\/x-cmdf":"cmdf","chemical\/x-cml":"cml","chemical\/x-csml":"csml","chemical\/x-xyz":"xyz","font\/collection":"ttc","font\/otf":"otf","font\/ttf":"ttf","font\/woff":"woff","font\/woff2":"woff2","image\/cgm":"cgm","image\/g3fax":"g3","image\/gif":"gif","image\/ief":"ief","image\/jpeg":"jpeg","image\/ktx":"ktx","image\/png":"png","image\/prs.btif":"btif","image\/sgi":"sgi","image\/svg+xml":"svg","image\/tiff":"tiff","image\/vnd.adobe.photoshop":"psd","image\/vnd.dece.graphic":"uvi","image\/vnd.djvu":"djvu","image\/vnd.dvb.subtitle":"sub","image\/vnd.dwg":"dwg","image\/vnd.dxf":"dxf","image\/vnd.fastbidsheet":"fbs","image\/vnd.fpx":"fpx","image\/vnd.fst":"fst","image\/vnd.fujixerox.edmics-mmr":"mmr","image\/vnd.fujixerox.edmics-rlc":"rlc","image\/vnd.ms-modi":"mdi","image\/vnd.ms-photo":"wdp","image\/vnd.net-fpx":"npx","image\/vnd.wap.wbmp":"wbmp","image\/vnd.xiff":"xif","image\/webp":"webp","image\/x-3ds":"3ds","image\/x-cmu-raster":"ras","image\/x-cmx":"cmx","image\/x-freehand":"fh","image\/x-icon":"ico","image\/x-mrsid-image":"sid","image\/x-pcx":"pcx","image\/x-pict":"pic","image\/x-portable-anymap":"pnm","image\/x-portable-bitmap":"pbm","image\/x-portable-graymap":"pgm","image\/x-portable-pixmap":"ppm","image\/x-rgb":"rgb","image\/x-xpixmap":"xpm","image\/x-xwindowdump":"xwd","message\/rfc822":"eml","model\/iges":"igs","model\/mesh":"msh","model\/vnd.collada+xml":"dae","model\/vnd.dwf":"dwf","model\/vnd.gdl":"gdl","model\/vnd.gtw":"gtw","model\/vnd.vtu":"vtu","model\/vrml":"wrl","model\/x3d+binary":"x3db","model\/x3d+vrml":"x3dv","model\/x3d+xml":"x3d","text\/cache-manifest":"appcache","text\/calendar":"ics","text\/css":"css","text\/csv":"csv","text\/html":"html","text\/n3":"n3","text\/plain":"txt","text\/prs.lines.tag":"dsc","text\/richtext":"rtx","text\/sgml":"sgml","text\/tab-separated-values":"tsv","text\/troff":"t","text\/turtle":"ttl","text\/uri-list":"uri","text\/vcard":"vcard","text\/vnd.curl":"curl","text\/vnd.curl.dcurl":"dcurl","text\/vnd.curl.mcurl":"mcurl","text\/vnd.curl.scurl":"scurl","text\/vnd.fly":"fly","text\/vnd.fmi.flexstor":"flx","text\/vnd.graphviz":"gv","text\/vnd.in3d.3dml":"3dml","text\/vnd.in3d.spot":"spot","text\/vnd.sun.j2me.app-descriptor":"jad","text\/vnd.wap.wml":"wml","text\/vnd.wap.wmlscript":"wmls","text\/x-asm":"s","text\/x-c":"cc","text\/x-fortran":"f","text\/x-java-source":"java","text\/x-nfo":"nfo","text\/x-opml":"opml","text\/x-pascal":"p","text\/x-setext":"etx","text\/x-sfv":"sfv","text\/x-uuencode":"uu","text\/x-vcalendar":"vcs","text\/x-vcard":"vcf","video\/3gpp":"3gp","video\/3gpp2":"3g2","video\/h261":"h261","video\/h263":"h263","video\/h264":"h264","video\/jpeg":"jpgv","video\/jpm":"jpm","video\/mj2":"mj2","video\/mp4":"mp4","video\/mpeg":"mpeg","video\/quicktime":"qt","video\/vnd.dece.hd":"uvh","video\/vnd.dece.mobile":"uvm","video\/vnd.dece.pd":"uvp","video\/vnd.dece.sd":"uvs","video\/vnd.dece.video":"uvv","video\/vnd.dvb.file":"dvb","video\/vnd.fvt":"fvt","video\/vnd.mpegurl":"mxu","video\/vnd.ms-playready.media.pyv":"pyv","video\/vnd.uvvu.mp4":"uvu","video\/vnd.vivo":"viv","video\/webm":"webm","video\/x-f4v":"f4v","video\/x-fli":"fli","video\/x-flv":"flv","video\/x-m4v":"m4v","video\/x-matroska":"mkv","video\/x-mng":"mng","video\/x-ms-asf":"asf","video\/x-ms-vob":"vob","video\/x-ms-wmx":"wmx","video\/x-ms-wvx":"wvx","video\/x-msvideo":"avi","video\/x-sgi-movie":"movie","video\/x-smv":"smv","x-conference\/x-cooltalk":"ice","text\/x-sql":"sql","image\/x-pixlr-data":"pxd","image\/x-adobe-dng":"dng","image\/x-sketch":"sketch","image\/x-xcf":"xcf","audio\/amr":"amr","application\/plt":"plt","application\/sat":"sat","application\/step":"step","text\/x-httpd-cgi":"cgi","text\/x-asap":"asp","text\/x-jsp":"jsp"};/* * File: /js/elFinder.options.js *//** * Default elFinder config * * @type  Object * @autor Dmitry (dio) Levashov */elFinder.prototype._options = {	/**	 * URLs of 3rd party libraries CDN	 * 	 * @type Object	 */	cdns : {		// for editor etc.		ace        : 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1',		codemirror : 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.40.2',		ckeditor   : 'https://cdnjs.cloudflare.com/ajax/libs/ckeditor/4.10.0',		ckeditor5  : 'https://cdn.ckeditor.com/ckeditor5/11.1.1',		tinymce    : 'https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.8.3',		simplemde  : 'https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2',		fabric16   : 'https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.7',		tui        : 'https://uicdn.toast.com',		// for quicklook etc.		hls        : 'https://cdnjs.cloudflare.com/ajax/libs/hls.js/0.10.1/hls.min.js',		dash       : 'https://cdnjs.cloudflare.com/ajax/libs/dashjs/2.9.1/dash.all.min.js',		flv        : 'https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.4.2/flv.min.js',		prettify   : 'https://cdn.jsdelivr.net/gh/google/code-prettify@453bd5f51e61245339b738b1bbdd42d7848722ba/loader/run_prettify.js',		psd        : 'https://cdnjs.cloudflare.com/ajax/libs/psd.js/3.2.0/psd.min.js',		rar        : 'https://cdn.jsdelivr.net/gh/nao-pon/rar.js@6cef13ec66dd67992fc7f3ea22f132d770ebaf8b/rar.min.js',		zlibUnzip  : 'https://cdn.jsdelivr.net/gh/imaya/zlib.js@0.3.1/bin/unzip.min.js', // need check unzipFiles() in quicklook.plugins.js when update		zlibGunzip : 'https://cdn.jsdelivr.net/gh/imaya/zlib.js@0.3.1/bin/gunzip.min.js',		marked     : 'https://cdnjs.cloudflare.com/ajax/libs/marked/0.5.1/marked.min.js',		sparkmd5   : 'https://cdnjs.cloudflare.com/ajax/libs/spark-md5/3.0.0/spark-md5.min.js',		jssha      : 'https://cdnjs.cloudflare.com/ajax/libs/jsSHA/2.3.1/sha.js',		amr        : 'https://cdn.jsdelivr.net/gh/yxl/opencore-amr-js@dcf3d2b5f384a1d9ded2a54e4c137a81747b222b/js/amrnb.js'	},		/**	 * Connector url. Required!	 *	 * @type String	 */	url : '',	/**	 * Ajax request type.	 *	 * @type String	 * @default "get"	 */	requestType : 'get',		/**	 * Use CORS to connector url	 * 	 * @type Boolean|null  true|false|null(Auto detect)	 */	cors : null,	/**	 * Maximum number of concurrent connections on request	 * 	 * @type Number	 * @default 3	 */	requestMaxConn : 3,	/**	 * Transport to send request to backend.	 * Required for future extensions using websockets/webdav etc.	 * Must be an object with "send" method.	 * transport.send must return $.Deferred() object	 *	 * @type Object	 * @default null	 * @example	 *  transport : {	 *    init : function(elfinderInstance) { },	 *    send : function(options) {	 *      var dfrd = $.Deferred();	 *      // connect to backend ...	 *      return dfrd;	 *    },	 *    upload : function(data) {	 *      var dfrd = $.Deferred();	 *      // upload ...	 *      return dfrd;	 *    }	 *    	 *  }	 **/	transport : {},	/**	 * URL to upload file to.	 * If not set - connector URL will be used	 *	 * @type String	 * @default  ''	 */	urlUpload : '',	/**	 * Allow to drag and drop to upload files	 *	 * @type Boolean|String	 * @default  'auto'	 */	dragUploadAllow : 'auto',		/**	 * Confirmation dialog displayed at the time of overwriting upload	 * 	 * @type Boolean	 * @default true	 */	overwriteUploadConfirm : true,		/**	 * Max size of chunked data of file upload	 * 	 * @type Number	 * @default  10485760(10MB)	 */	uploadMaxChunkSize : 10485760,		/**	 * Regular expression of file name to exclude when uploading folder	 * 	 * @type Object	 * @default { win: /^(?:desktop\.ini|thumbs\.db)$/i, mac: /^\.ds_store$/i }	 */	folderUploadExclude : {		win: /^(?:desktop\.ini|thumbs\.db)$/i,		mac: /^\.ds_store$/i	},		/**	 * Timeout for upload using iframe	 *	 * @type Number	 * @default  0 - no timeout	 */	iframeTimeout : 0,		/**	 * Data to append to all requests and to upload files	 *	 * @type Object	 * @default  {}	 */	customData : {},		/**	 * Event listeners to bind on elFinder init	 *	 * @type Object	 * @default  {}	 */	handlers : {},	/**	 * Any custom headers to send across every ajax request	 *	 * @type Object	 * @default {}	 */	customHeaders : {},	/**	 * Any custom xhrFields to send across every ajax request	 *	 * @type Object	 * @default {}	 */	xhrFields : {},	/**	 * Interface language	 *	 * @type String	 * @default "en"	 */	lang : 'en',	/**	 * Base URL of elfFinder library starting from Manager HTML	 * Auto detect when empty value	 * 	 * @type String	 * @default ""	 */	baseUrl : '',	/**	 * Base URL of i18n js files	 * baseUrl + "js/i18n/" when empty value	 * 	 * @type String	 * @default ""	 */	i18nBaseUrl : '',		/**	 * Auto load required CSS	 * `false` to disable this function or	 * CSS URL Array to load additional CSS files	 * 	 * @type Boolean|Array	 * @default true	 */	cssAutoLoad : true,	/**	 * Theme to load	 * {"themeid" : "Theme CSS URL"} or	 * {"themeid" : "Theme manifesto.json URL"} or	 * Theme manifesto.json Object	 * {	 *   "themeid" : {	 *     "name":"Theme Name",	 *     "cssurls":"Theme CSS URL",	 *     "author":"Author Name",	 *     "email":"Author Email",	 *     "license":"License",	 *     "link":"Web Site URL",	 *     "image":"Screen Shot URL",	 *     "description":"Description"	 *   }	 * }	 * 	 * @type Object	 */	themes : {},	/**	 * Theme id to initial theme	 * 	 * @type String|Null	 */	theme : null,		/**	 * Additional css class for filemanager node.	 *	 * @type String	 */	cssClass : '',	/**	 * Active commands list. '*' means all of the commands that have been load.	 * If some required commands will be missed here, elFinder will add its	 *	 * @type Array	 */	commands : ['*'],	// Available commands list	//commands : [	//	'archive', 'back', 'chmod', 'colwidth', 'copy', 'cut', 'download', 'duplicate', 'edit', 'extract',	//	'forward', 'fullscreen', 'getfile', 'help', 'home', 'info', 'mkdir', 'mkfile', 'netmount', 'netunmount',	//	'open', 'opendir', 'paste', 'places', 'quicklook', 'reload', 'rename', 'resize', 'restore', 'rm',	//	'search', 'sort', 'up', 'upload', 'view', 'zipdl'	//],		/**	 * Commands options.	 *	 * @type Object	 **/	commandsOptions : {		// // configure shortcuts of any command		// // add `shortcuts` property into each command		// any_command_name : {		// 	shortcuts : [] // for disable this command's shortcuts		// },		// any_command_name : {		// 	shortcuts : function(fm, shortcuts) {		// 		// for add `CTRL + E` for this command action		// 		shortcuts[0]['pattern'] += ' ctrl+e';		// 		return shortcuts;		// 	}		// },		// any_command_name : {		// 	shortcuts : function(fm, shortcuts) {		// 		// for full customize of this command's shortcuts		// 		return [ { pattern: 'ctrl+e ctrl+down numpad_enter' + (fm.OS != 'mac' && ' enter') } ];		// 	}		// },		// "getfile" command options.		getfile : {			onlyURL  : false,			// allow to return multiple files info			multiple : false,			// allow to return filers info			folders  : false,			// action after callback (""/"close"/"destroy")			oncomplete : '',			// action when callback is fail (""/"close"/"destroy")			onerror : '',			// get path before callback call			getPath    : true, 			// get image sizes before callback call			getImgSize : false		},		open : {			// HTTP method that request to the connector when item URL is not valid URL.			// If you set to "get" will be displayed request parameter in the browser's location field			// so if you want to conceal its parameters should be given "post".			// Nevertheless, please specify "get" if you want to enable the partial request by HTTP Range header.			method : 'post',			// Where to open into : 'window'(default), 'tab' or 'tabs'			// 'tabs' opens in each tabs			into   : 'window',			// Default command list of action when select file			// String value that is 'Command Name' or 'Command Name1/CommandName2...'			selectAction : 'open'		},		opennew : {			// URL of to open elFinder manager			// Default '' : Origin URL			url : '',			// Use search query of origin URL			useOriginQuery : true		},		// "upload" command options.		upload : {			// Open elFinder upload dialog: 'button' OR Open system OS upload dialog: 'uploadbutton'			ui : 'button'		},		// "download" command options.		download : {			// max request to download files when zipdl disabled			maxRequests : 10,			// minimum count of files to use zipdl			minFilesZipdl : 2		},		// "quicklook" command options.		quicklook : {			autoplay : true,			width    : 450,			height   : 300,			// ControlsList of HTML5 audio/video preview			// see https://googlechrome.github.io/samples/media/controlslist.html			mediaControlsList : '', // e.g. 'nodownload nofullscreen noremoteplayback'			// Show toolbar of PDF preview (with <embed> tag)			pdfToolbar : true,			// Maximum characters length to preview			textMaxlen : 2000,			// quicklook window must be contained in elFinder node on window open (true|false)			contain : false,			// preview window into NavDock (0 : undocked | 1 : docked(show) | 2 : docked(hide))			docked   : 0,			// Docked preview height ('auto' or Number of pixel) 'auto' is setted to the Navbar width			dockHeight : 'auto',			// media auto play when docked			dockAutoplay : false,			// Google Maps API key (Require Maps JavaScript API)			googleMapsApiKey : '',			// Google Maps API Options			googleMapsOpts : {				maps : {},				kml : {					suppressInfoWindows : false,					preserveViewport : false				}			},			// ViewerJS (https://viewerjs.org/) Options			// To enable this you need to place ViewerJS on the same server as elFinder and specify that URL in `url`.			viewerjs : {				url: '', // Example '/ViewerJS/index.html'				mimes: ['application/pdf', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.oasis.opendocument.presentation']			},			// MIME types to CAD-Files and 3D-Models online viewer on sharecad.org			// Example ['image/vnd.dwg', 'image/vnd.dxf', 'model/vnd.dwf', 'application/vnd.hp-hpgl', 'application/plt', 'application/step', 'model/iges', 'application/vnd.ms-pki.stl', 'application/sat', 'image/cgm', 'application/x-msmetafile']			sharecadMimes : [],			// MIME types to use Google Docs online viewer			// Example ['application/pdf', 'image/tiff', 'application/vnd.ms-office', 'application/msword', 'application/vnd.ms-word', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/postscript', 'application/rtf']			googleDocsMimes : [],			// MIME types to use Microsoft Office Online viewer			// Example ['application/msword', 'application/vnd.ms-word', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.oasis.opendocument.presentation']			// These MIME types override "googleDocsMimes"			officeOnlineMimes : [],			// File size (byte) threshold when using the dim command for obtain the image size necessary to image preview			getDimThreshold : 200000,			// MIME-Type regular expression that does not check empty files			mimeRegexNotEmptyCheck : /^application\/vnd\.google-apps\./		},		// "quicklook" command options.		edit : {			// dialog width, integer(px) or integer+'%' (example: 650, '80%' ...)			dialogWidth : void(0),			// list of allowed mimetypes to edit of text files			// if empty - any text files can be edited			mimes : [],			// MIME-types of text file to make as empty files			makeTextMimes : ['text/plain', 'text/css', 'text/html'],			// Use the editor stored in the browser			// This value allowd overwrite with user preferences			useStoredEditor : false,			// Open the maximized editor window			// This value allowd overwrite with user preferences			editorMaximized : false,			// edit files in wysisyg's			editors : [				// {				// 	/**				// 	 * editor info				// 	 * @type  Object				// 	 */				// 	info : { name: 'Editor Name' },				// 	/**				// 	 * files mimetypes allowed to edit in current wysisyg				// 	 * @type  Array				// 	 */				// 	mimes : ['text/html'], 				// 	/**				// 	 * HTML element for editing area (optional for text editor)				// 	 * @type  String				// 	 */				// 	html : '<textarea></textarea>', 				// 	/**				// 	 * Initialize editing area node (optional for text editor)				// 	 * 				// 	 * @param  String  dialog DOM id				// 	 * @param  Object  target file object				// 	 * @param  String  target file content (text or Data URI Scheme(binary file))				// 	 * @param  Object  elFinder instance				// 	 * @type  Function				// 	 */				// 	init : function(id, file, content, fm) {				// 		$(this).attr('id', id + '-text').val(content);				// 	},				// 	/**				// 	 * Get edited contents (optional for text editor)				// 	 * @type  Function				// 	 */				// 	getContent : function() {				// 		return $(this).val();				// 	},				// 	/**				// 	 * Called when "edit" dialog loaded.				// 	 * Place to init wysisyg.				// 	 * Can return wysisyg instance				// 	 *				// 	 * @param  DOMElement  textarea node				// 	 * @return Object      editor instance|jQuery.Deferred(return instance on resolve())				// 	 */				// 	load : function(textarea) { },				// 	/**				// 	 * Called before "edit" dialog closed.				// 	 * Place to destroy wysisyg instance.				// 	 *				// 	 * @param  DOMElement  textarea node				// 	 * @param  Object      wysisyg instance (if was returned by "load" callback)				// 	 * @return void				// 	 */				// 	close : function(textarea, instance) { },				// 	/**				// 	 * Called before file content send to backend.				// 	 * Place to update textarea content if needed.				// 	 *				// 	 * @param  DOMElement  textarea node				// 	 * @param  Object      wysisyg instance (if was returned by "load" callback)				// 	 * @return void				// 	 */				// 	save : function(textarea, instance) {},				// 	/**				// 	 * Called after load() or save().				// 	 * Set focus to wysisyg editor.				// 	 *				// 	 * @param  DOMElement  textarea node				// 	 * @param  Object      wysisyg instance (if was returned by "load" callback)				// 	 * @return void				// 	 */				// 	focus : function(textarea, instance) {}				// 	/**				// 	 * Called after dialog resized..				// 	 *				// 	 * @param  DOMElement  textarea node				// 	 * @param  Object      wysisyg instance (if was returned by "load" callback)				// 	 * @param  Object      resize event object				// 	 * @param  Object      data object				// 	 * @return void				// 	 */				// 	resize : function(textarea, instance, event, data) {}				// 				// }			],			// Character encodings of select box			encodings : ['Big5', 'Big5-HKSCS', 'Cp437', 'Cp737', 'Cp775', 'Cp850', 'Cp852', 'Cp855', 'Cp857', 'Cp858', 				'Cp862', 'Cp866', 'Cp874', 'EUC-CN', 'EUC-JP', 'EUC-KR', 'GB18030', 'ISO-2022-CN', 'ISO-2022-JP', 'ISO-2022-KR', 				'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 				'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-13', 'ISO-8859-15', 'KOI8-R', 'KOI8-U', 'Shift-JIS', 				'Windows-1250', 'Windows-1251', 'Windows-1252', 'Windows-1253', 'Windows-1254', 'Windows-1257'],			// options for extra editors			extraOptions : {				// TUI Image Editor's options				tuiImgEditOpts : {					// Path prefix of icon-a.svg, icon-b.svg, icon-c.svg and icon-d.svg in the Theme. 					// `iconsPath` MUST follow the same origin policy.					iconsPath : void(0), // default is "./img/tui-"					// Theme object					theme : {}				},				// Specify the Creative Cloud API key when using Creative SDK image editor of Creative Cloud.				// You can get the API key at https://console.adobe.io/.				creativeCloudApiKey : '',				// Browsing manager URL for CKEditor, TinyMCE				// Uses self location with the empty value or not defined.				//managerUrl : 'elfinder.html'				managerUrl : null,				// CKEditor5' builds mode - 'classic', 'inline' or 'balloon' 				ckeditor5Mode : 'balloon',				// Setting for Online-Convert.com				onlineConvert : {					maxSize  : 100, // (MB) Max 100MB on free account					showLink : true // It must be enabled with free account				}			}		},		search : {			// Incremental search from the current view			incsearch : {				enable : true, // is enable true or false				minlen : 1,    // minimum number of characters				wait   : 500   // wait milliseconds			},			// Additional search types			searchTypes : {				// "SearchMime" is implemented in default				SearchMime : {           // The key is search type that send to the connector					name : 'btnMime',    // Button text to be processed in i18n()					title : 'searchMime' // Button title to be processed in i18n()				}			}		},		// "info" command options.		info : {			// If the URL of the Directory is null,			// it is assumed that the link destination is a URL to open the folder in elFinder			nullUrlDirLinkSelf : true,			// Information items to be hidden by default			// These name are 'size', 'aliasfor', 'path', 'link', 'dim', 'modify', 'perms', 'locked', 'owner', 'group', 'perm' and your custom info items label			hideItems : [],			// Maximum file size (byte) to get file contents hash (md5, sha256 ...)			showHashMaxsize : 104857600, // 100 MB			// Array of hash algorisms to show on info dialog			// These name are 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha3-224', 'sha3-256', 'sha3-384', 'sha3-512', 'shake128' and 'shake256'			showHashAlgorisms : ['md5', 'sha256'],			custom : {				// /**				//  * Example of custom info `desc`				//  */				// desc : {				// 	/**				// 	 * Lable (require)				// 	 * It is filtered by the `fm.i18n()`				// 	 * 				// 	 * @type String				// 	 */				// 	label : 'Description',				// 					// 	/**				// 	 * Template (require)				// 	 * `{id}` is replaced in dialog.id				// 	 * 				// 	 * @type String				// 	 */				// 	tpl : '<div class="elfinder-info-desc"><span class="elfinder-spinner"></span></div>',				// 					// 	/**				// 	 * Restricts to mimetypes (optional)				// 	 * Exact match or category match				// 	 * 				// 	 * @type Array				// 	 */				// 	mimes : ['text', 'image/jpeg', 'directory'],				// 					// 	/**				// 	 * Restricts to file.hash (optional)				// 	 * 				// 	 * @ type Regex				// 	 */				// 	hashRegex : /^l\d+_/,				// 				// 	/**				// 	 * Request that asks for the description and sets the field (optional)				// 	 * 				// 	 * @type Function				// 	 */				// 	action : function(file, fm, dialog) {				// 		fm.request({				// 		data : { cmd : 'desc', target: file.hash },				// 			preventDefault: true,				// 		})				// 		.fail(function() {				// 			dialog.find('div.elfinder-info-desc').html(fm.i18n('unknown'));				// 		})				// 		.done(function(data) {				// 			dialog.find('div.elfinder-info-desc').html(data.desc);				// 		});				// 	}				// }			}		},		mkdir: {			// Enable automatic switching function ["New Folder" / "Into New Folder"] of toolbar buttton			intoNewFolderToolbtn: false		},		resize: {			// defalt status of snap to 8px grid of the jpeg image ("enable" or "disable")			grid8px : 'disable',			// Preset size array [width, height]			presetSize : [[320, 240], [400, 400], [640, 480], [800,600]],			// File size (bytes) threshold when using the `dim` command for obtain the image size necessary to start editing			getDimThreshold : 204800,			// File size (bytes) to request to get substitute image (400px) with the `dim` command			dimSubImgSize : 307200		},		rm: {			// If trash is valid, items moves immediately to the trash holder without confirm.			quickTrash : true,			// Maximum wait seconds when checking the number of items to into the trash			infoCheckWait : 10,			// Maximum number of items that can be placed into the Trash at one time			toTrashMaxItems : 1000		},		help : {			// Tabs to show			view : ['about', 'shortcuts', 'help', 'integrations', 'debug'],			// HTML source URL of the heip tab			helpSource : ''		},		preference : {			// dialog width			width: 600,			// dialog height			height: 400,			// tabs setting see preference.js : build()			categories: null,			// preference setting see preference.js : build()			prefs: null,			// language setting  see preference.js : build()			langs: null,			// Command list of action when select file			// Array value are 'Command Name' or 'Command Name1/CommandName2...'			selectActions : ['open', 'edit/download', 'resize/edit/download', 'download', 'quicklook']		}	},		/**	 * Callback for prepare boot up	 * 	 * - The this object in the function is an elFinder node	 * - The first parameter is elFinder Instance	 * - The second parameter is an object of other parameters	 *   For now it can use `dfrdsBeforeBootup` Array	 * 	 * @type Function	 * @default null	 * @return void	 */	bootCallback : null,		/**	 * Callback for "getfile" commands.	 * Required to use elFinder with WYSIWYG editors etc..	 *	 * @type Function	 * @default null (command not active)	 */	getFileCallback : null,		/**	 * Default directory view. icons/list	 *	 * @type String	 * @default "icons"	 */	defaultView : 'icons',		/**	 * Hash of default directory path to open	 * 	 * NOTE: This setting will be disabled if the target folder is specified in location.hash.	 * 	 * If you want to find the hash in Javascript	 * can be obtained with the following code. (In the case of a standard hashing method)	 * 	 * var volumeId = 'l1_'; // volume id	 * var path = 'path/to/target'; // without root path	 * //var path = 'path\\to\\target'; // use \ on windows server	 * var hash = volumeId + btoa(path).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '.').replace(/\.+$/, '');	 * 	 * @type String	 * @default ""	 */	startPathHash : '',	/**	 * Emit a sound when a file is deleted	 * Sounds are in sounds/ folder	 * 	 * @type Boolean	 * @default true	 */	sound : true,		/**	 * UI plugins to load.	 * Current dir ui and dialogs loads always.	 * Here set not required plugins as folders tree/toolbar/statusbar etc.	 *	 * @type Array	 * @default ['toolbar', 'tree', 'path', 'stat']	 * @full ['toolbar', 'places', 'tree', 'path', 'stat']	 */	ui : ['toolbar', 'tree', 'path', 'stat'],		/**	 * Some UI plugins options.	 * @type Object	 */	uiOptions : {		// toolbar configuration		toolbar : [			['home', 'back', 'forward', 'up', 'reload'],			['netmount'],			['mkdir', 'mkfile', 'upload'],			['open', 'download', 'getfile'],			['undo', 'redo'],			['copy', 'cut', 'paste', 'rm', 'empty', 'hide'],			['duplicate', 'rename', 'edit', 'resize', 'chmod'],			['selectall', 'selectnone', 'selectinvert'],			['quicklook', 'info'],			['extract', 'archive'],			['search'],			['view', 'sort'],			['preference', 'help'],			['fullscreen']		],		// toolbar extra options		toolbarExtra : {			// also displays the text label on the button (true / false / 'none')			displayTextLabel: false,			// Exclude `displayTextLabel` setting UA type			labelExcludeUA: ['Mobile'],			// auto hide on initial open			autoHideUA: ['Mobile'],			// Initial setting value of hide button in toolbar setting			defaultHides: ['home', 'reload'],			// show Preference button ('none', 'auto', 'always')			// If you do not include 'preference' in the context menu you should specify 'auto' or 'always'			showPreferenceButton: 'none',			// show Preference button into contextmenu of the toolbar (true / false)			preferenceInContextmenu: true		},		// directories tree options		tree : {			// expand current root on init			openRootOnLoad : true,			// expand current work directory on open			openCwdOnOpen  : true,			// auto loading current directory parents and do expand their node.			syncTree : true,			// Maximum number of display of each child trees			// The tree of directories with children exceeding this number will be split			subTreeMax : 100,			// Numbar of max connctions of subdirs request			subdirsMaxConn : 2,			// Number of max simultaneous processing directory of subdirs			subdirsAtOnce : 5,			// Durations of each animations			durations : {				slideUpDown : 'fast',				autoScroll : 'fast'			}			// ,			// /**			//  * Add CSS class name to navbar directories (optional)			//  * see: https://github.com/Studio-42/elFinder/pull/1061,			//  *      https://github.com/Studio-42/elFinder/issues/1231			//  * 			//  * @type Function			//  */			// getClass: function(dir) {			// 	// e.g. This adds the directory's name (lowercase) with prefix as a CSS class			// 	return 'elfinder-tree-' + dir.name.replace(/[ "]/g, '').toLowerCase();			// }		},		// navbar options		navbar : {			minWidth : 150,			maxWidth : 500,			// auto hide on initial open			autoHideUA: [] // e.g. ['Mobile']		},		navdock : {			// disabled navdock ui			disabled : false,			// percentage of initial maximum height to work zone			initMaxHeight : '50%',			// percentage of maximum height to work zone by user resize action			maxHeight : '90%'		},		cwd : {			// display parent folder with ".." name :)			oldSchool : false,						// fm.UA types array to show item select checkboxes e.g. ['All'] or ['Mobile'] etc. default: ['Touch']			showSelectCheckboxUA : ['Touch'],						// file info columns displayed			listView : {				// name is always displayed, cols are ordered				// e.g. ['perm', 'date', 'size', 'kind', 'owner', 'group', 'mode']				// mode: 'mode'(by `fileModeStyle` setting), 'modestr'(rwxr-xr-x) , 'modeoct'(755), 'modeboth'(rwxr-xr-x (755))				// 'owner', 'group' and 'mode', It's necessary set volume driver option "statOwner" to `true`				// for custom, characters that can be used in the name is `a-z0-9_`				columns : ['perm', 'date', 'size', 'kind'],				// override this if you want custom columns name				// example				// columnsCustomName : {				//		date : 'Last modification',				// 		kind : 'Mime type'				// }				columnsCustomName : {},				// fixed list header colmun				fixedHeader : true			},			// icons view setting			iconsView : {				// default icon size (0-3 in default CSS (cwd.css - elfinder-cwd-size[number]))				size: 0,				// number of maximum size (3 in default CSS (cwd.css - elfinder-cwd-size[number]))				// uses in preference.js				sizeMax: 3,				// Name of each size				sizeNames: {					0: 'viewSmall',					1: 'viewMedium',					2: 'viewLarge',					3: 'viewExtraLarge' 				}			},			// /**			//  * Add CSS class name to cwd directories (optional)			//  * see: https://github.com/Studio-42/elFinder/pull/1061,			//  *      https://github.com/Studio-42/elFinder/issues/1231			//  * 			//  * @type Function			//  */			// ,			// getClass: function(file) {			// 	// e.g. This adds the directory's name (lowercase) with prefix as a CSS class			// 	return 'elfinder-cwd-' + file.name.replace(/[ "]/g, '').toLowerCase();			//}						//,			//// Template placeholders replacement rules for overwrite. see ui/cwd.js replacement			//replacement : {			//	tooltip : function(f, fm) {			//		var list = fm.viewType == 'list', // current view type			//			query = fm.searchStatus.state == 2, // is in search results			//			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, '
') : '';			//		}			//		if (list) {			//			info += (info? '
' : '') + fm.escape(f.name);			//		}			//		return info? info + '
' + title : title;			//	}			//}		},		path : {			// Move to head of work zone without UI navbar			toWorkzoneWithoutNavbar : true		},		dialog : {			// Enable to auto focusing on mouse over in the target form element			focusOnMouseOver : true		},		toast : {			animate : {				// to show				showMethod: 'fadeIn', // fadeIn, slideDown, and show are built into jQuery				showDuration: 300,    // milliseconds				showEasing: 'swing',  // swing and linear are built into jQuery				// timeout to hide				timeOut: 3000,				// to hide				hideMethod: 'fadeOut',				hideDuration: 1500,				hideEasing: 'swing'			}		}	},	/**	 * MIME regex of send HTTP header "Content-Disposition: inline" or allow preview in quicklook	 * This option will overwrite by connector configuration	 * 	 * @type String	 * @default '^(?:(?:image|video|audio)|text/plain|application/pdf$)'	 * @example	 *  dispInlineRegex : '.',  // is allow inline of all of MIME types	 *  dispInlineRegex : '$^', // is not allow inline of all of MIME types	 */	dispInlineRegex : '^(?:(?:image|video|audio)|application/(?:x-mpegURL|dash\+xml)|(?:text/plain|application/pdf)$)',	/**	 * Display only required files by types	 *	 * @type Array	 * @default []	 * @example	 *  onlyMimes : ["image"] - display all images	 *  onlyMimes : ["image/png", "application/x-shockwave-flash"] - display png and flash	 */	onlyMimes : [],	/**	 * Custom files sort rules.	 * All default rules (name/size/kind/date/perm/mode/owner/group) set in elFinder._sortRules	 *	 * @type {Object}	 * @example	 * sortRules : {	 *   name : function(file1, file2) { return file1.name.toLowerCase().localeCompare(file2.name.toLowerCase()); }	 * }	 */	sortRules : {},	/**	 * Default sort type.	 *	 * @type {String}	 */	sortType : 'name',		/**	 * Default sort order.	 *	 * @type {String}	 * @default "asc"	 */	sortOrder : 'asc',		/**	 * Display folders first?	 *	 * @type {Boolean}	 * @default true	 */	sortStickFolders : true,		/**	 * Sort also applies to the treeview	 *	 * @type {Boolean}	 * @default false	 */	sortAlsoTreeview : false,		/**	 * If true - elFinder will formating dates itself, 	 * otherwise - backend date will be used.	 *	 * @type Boolean	 */	clientFormatDate : true,		/**	 * Show UTC dates.	 * Required set clientFormatDate to true	 *	 * @type Boolean	 */	UTCDate : false,		/**	 * File modification datetime format.	 * Value from selected language data  is used by default.	 * Set format here to overwrite it.	 *	 * @type String	 * @default  ""	 */	dateFormat : '',		/**	 * File modification datetime format in form "Yesterday 12:23:01".	 * Value from selected language data is used by default.	 * Set format here to overwrite it.	 * Use $1 for "Today"/"Yesterday" placeholder	 *	 * @type String	 * @default  ""	 * @example "$1 H:m:i"	 */	fancyDateFormat : '',		/**	 * Style of file mode at cwd-list, info dialog	 * 'string' (ex. rwxr-xr-x) or 'octal' (ex. 755) or 'both' (ex. rwxr-xr-x (755))	 * 	 * @type {String}	 * @default 'both'	 */	fileModeStyle : 'both',		/**	 * elFinder width	 *	 * @type String|Number	 * @default  "auto"	 */	width : 'auto',		/**	 * elFinder node height	 * Number: pixcel or String: Number + "%"	 *	 * @type Number | String	 * @default  400	 */	height : 400,		/**	 * Base node object or selector	 * Element which is the reference of the height percentage	 *	 * @type Object|String	 * @default null | $(window) (if height is percentage)	 **/	heightBase : null,		/**	 * Make elFinder resizable if jquery ui resizable available	 *	 * @type Boolean	 * @default  true	 */	resizable : true,		/**	 * Timeout before open notifications dialogs	 *	 * @type Number	 * @default  500 (.5 sec)	 */	notifyDelay : 500,		/**	 * Position CSS, Width of notifications dialogs	 *	 * @type Object	 * @default {position: {}, width : null} - Apply CSS definition	 * position: CSS object | null (null: position center & middle)	 */	notifyDialog : {position: {}, width : null},		/**	 * Dialog contained in the elFinder node	 * 	 * @type Boolean	 * @default false	 */	dialogContained : false,		/**	 * Allow shortcuts	 *	 * @type Boolean	 * @default  true	 */	allowShortcuts : true,		/**	 * Remeber last opened dir to open it after reload or in next session	 *	 * @type Boolean	 * @default  true	 */	rememberLastDir : true,		/**	 * Clear historys(elFinder) on reload(not browser) function	 * Historys was cleared on Reload function on elFinder 2.0 (value is true)	 * 	 * @type Boolean	 * @default  false	 */	reloadClearHistory : false,		/**	 * Use browser native history with supported browsers	 *	 * @type Boolean	 * @default  true	 */	useBrowserHistory : true,		/**	 * Lazy load config.	 * How many files display at once?	 *	 * @type Number	 * @default  50	 */	showFiles : 50,		/**	 * Lazy load config.	 * Distance in px to cwd bottom edge to start display files	 *	 * @type Number	 * @default  50	 */	showThreshold : 50,		/**	 * Additional rule to valid new file name.	 * By default not allowed empty names or '..'	 * This setting does not have a sense of security.	 *	 * @type false|RegExp|function	 * @default  false	 * @example	 *  disable names with spaces:	 *  validName : /^[^\s]+$/,	 */	validName : false,		/**	 * Additional rule to filtering for browsing.	 * This setting does not have a sense of security.	 * 	 * The object `this` is elFinder instance object in this function	 *	 * @type false|RegExp|function	 * @default  false	 * @example	 *  show only png and jpg files:	 *  fileFilter : /.*\.(png|jpg)$/i,	 *  	 *  show only image type files:	 *  fileFilter : function(file) { return file.mime && file.mime.match(/^image\//i); },	 */	fileFilter : false,		/**	 * Backup name suffix.	 *	 * @type String	 * @default  "~"	 */	backupSuffix : '~',		/**	 * Sync content interval	 *	 * @type Number	 * @default  0 (do not sync)	 */	sync : 0,		/**	 * Sync start on load if sync value >= 1000	 *	 * @type     Bool	 * @default  true	 */	syncStart : true,		/**	 * How many thumbnails create in one request	 *	 * @type Number	 * @default  5	 */	loadTmbs : 5,		/**	 * Cookie option for browsersdoes not suppot localStorage	 *	 * @type Object	 */	cookie         : {		expires : 30,		domain  : '',		path    : '/',		secure  : false	},		/**	 * Contextmenu config	 *	 * @type Object	 */	contextmenu : {		// navbarfolder menu		navbar : ['open', 'opennew', 'download', '|', 'upload', 'mkdir', '|', 'copy', 'cut', 'paste', 'duplicate', '|', 'rm', 'empty', 'hide', '|', 'rename', '|', 'archive', '|', 'places', 'info', 'chmod', 'netunmount'],		// current directory menu		cwd    : ['undo', 'redo', '|', 'back', 'up', 'reload', '|', 'upload', 'mkdir', 'mkfile', 'paste', '|', 'empty', 'hide', '|', 'view', 'sort', 'selectall', 'colwidth', '|', 'places', 'info', 'chmod', 'netunmount', '|', 'fullscreen', '|', 'preference'],		// current directory file menu		files  : ['getfile', '|' ,'open', 'opennew', 'download', 'opendir', 'quicklook', '|', 'upload', 'mkdir', '|', 'copy', 'cut', 'paste', 'duplicate', '|', 'rm', 'empty', 'hide', '|', 'rename', 'edit', 'resize', '|', 'archive', 'extract', '|', 'selectall', 'selectinvert', '|', 'places', 'info', 'chmod', 'netunmount']	},	/**	 * elFinder node enable always	 * This value will set to `true` if <body> has elFinder node only	 * 	 * @type     Bool	 * @default  false	 */	enableAlways : false,		/**	 * elFinder node enable by mouse over	 * 	 * @type     Bool	 * @default  true	 */	enableByMouseOver : true,	/**	 * Show window close confirm dialog	 * Value is which state to show	 * 'hasNotifyDialog', 'editingFile', 'hasSelectedItem' and 'hasClipboardData'	 * 	 * @type     Array	 * @default  ['hasNotifyDialog', 'editingFile']	 */	windowCloseConfirm : ['hasNotifyDialog', 'editingFile'],	/**	 * Function decoding 'raw' string converted to unicode	 * It is used instead of fm.decodeRawString(str)	 * 	 * @type Null|Function	 */	rawStringDecoder : typeof Encoding === 'object' && $.isFunction(Encoding.convert)? function(str) {		return Encoding.convert(str, {			to: 'UNICODE',			type: 'string'		});	} : null,	/**	 * Debug config	 *	 * @type Array|String('auto')|Boolean(true|false)	 */	// debug : true	debug : ['error', 'warning', 'event-destroy']};/* * File: /js/elFinder.options.netmount.js *//** * Default elFinder config of commandsOptions.netmount * * @type  Object */elFinder.prototype._options.commandsOptions.netmount = {	ftp: {		name : 'FTP',		inputs: {			host     : $('<input type="text"/>'),			port     : $('<input type="number" placeholder="21" class="elfinder-input-optional"/>'),			path     : $('<input type="text" value="/"/>'),			user     : $('<input type="text"/>'),			pass     : $('<input type="password" autocomplete="new-password"/>'),			FTPS     : $('<input type="checkbox" value="1" title="File Transfer Protocol over SSL/TLS"/>'),			encoding : $('<input type="text" placeholder="Optional" class="elfinder-input-optional"/>'),			locale   : $('<input type="text" placeholder="Optional" class="elfinder-input-optional"/>')		}	},	dropbox2: elFinder.prototype.makeNetmountOptionOauth('dropbox2', 'Dropbox', 'Dropbox', {noOffline : true,		root : '/',		pathI18n : 'path',		integrate : {			title: 'Dropbox.com',			link: 'https://www.dropbox.com'		}	}),	googledrive: elFinder.prototype.makeNetmountOptionOauth('googledrive', 'Google Drive', 'Google', {		integrate : {			title: 'Google Drive',			link: 'https://www.google.com/drive/'		}	}),	onedrive: elFinder.prototype.makeNetmountOptionOauth('onedrive', 'One Drive', 'OneDrive', {		integrate : {			title: 'Microsoft OneDrive',			link: 'https://onedrive.live.com'		}	}),	box: elFinder.prototype.makeNetmountOptionOauth('box', 'Box', 'Box', {		noOffline : true,		integrate : {			title: 'Box.com',			link: 'https://www.box.com'		}	})};/* * File: /js/elFinder.history.js *//** * @class elFinder.history * Store visited folders * and provide "back" and "forward" methods * * @author Dmitry (dio) Levashov */elFinder.prototype.history = function(fm) {		var self = this,		/**		 * Update history on "open" event?		 *		 * @type Boolean		 */		update = true,		/**		 * Directories hashes storage		 *		 * @type Array		 */		history = [],		/**		 * Current directory index in history		 *		 * @type Number		 */		current,		/**		 * Clear history		 *		 * @return void		 */		reset = function() {			history = [fm.cwd().hash];			current = 0;			update  = true;		},		/**		 * Browser native history object		 */		nativeHistory = (fm.options.useBrowserHistory && window.history && window.history.pushState)? window.history : null,		/**		 * Open prev/next folder		 *		 * @Boolen  open next folder?		 * @return jQuery.Deferred		 */		go = function(fwd) {			if ((fwd && self.canForward()) || (!fwd && self.canBack())) {				update = false;				return fm.exec('open', history[fwd ? ++current : --current]).fail(reset);			}			return $.Deferred().reject();		},		/**		 * Sets the native history.		 *		 * @param String thash target hash		 */		setNativeHistory = function(thash) {			if (nativeHistory && (! nativeHistory.state || nativeHistory.state.thash !== thash)) {				nativeHistory.pushState({thash: thash}, null, location.pathname + location.search + (thash? '#elf_' + thash : ''));			}		};		/**	 * Return true if there is previous visited directories	 *	 * @return Boolen	 */	this.canBack = function() {		return current > 0;	};		/**	 * Return true if can go forward	 *	 * @return Boolen	 */	this.canForward = function() {		return current < history.length - 1;	};		/**	 * Go back	 *	 * @return void	 */	this.back = go;		/**	 * Go forward	 *	 * @return void	 */	this.forward = function() {		return go(true);	};		// bind to elfinder events	fm.bind('init', function() {		if (nativeHistory && !nativeHistory.state) {			setNativeHistory(fm.startDir());		}	})	.open(function() {		var l = history.length,			cwd = fm.cwd().hash;		if (update) {			current >= 0 && l > current + 1 && history.splice(current+1);			history[history.length-1] != cwd && history.push(cwd);			current = history.length - 1;		}		update = true;		setNativeHistory(cwd);	})	.reload(fm.options.reloadClearHistory && reset);	};/* * File: /js/elFinder.command.js *//** * elFinder command prototype * * @type  elFinder.command * @author  Dmitry (dio) Levashov */elFinder.prototype.command = function(fm) {		/**	 * elFinder instance	 *	 * @type  elFinder	 */	this.fm = fm;		/**	 * Command name, same as class name	 *	 * @type  String	 */	this.name = '';		/**	 * Dialog class name	 *	 * @type  String	 */	this.dialogClass = '';	/**	 * Command icon class name with out 'elfinder-button-icon-'	 * Use this.name if it is empty	 *	 * @type  String	 */	this.className = '';	/**	 * Short command description	 *	 * @type  String	 */	this.title = '';		/**	 * Linked(Child) commands name	 * They are loaded together when tthis command is loaded.	 * 	 * @type  Array	 */	this.linkedCmds = [];		/**	 * Current command state	 *	 * @example	 * this.state = -1; // command disabled	 * this.state = 0;  // command enabled	 * this.state = 1;  // command active (for example "fullscreen" command while elfinder in fullscreen mode)	 * @default -1	 * @type  Number	 */	this.state = -1;		/**	 * If true, command can not be disabled by connector.	 * @see this.update()	 *	 * @type  Boolen	 */	this.alwaysEnabled = false;		/**	 * Do not change dirctory on removed current work directory	 * 	 * @type  Boolen	 */	this.noChangeDirOnRemovedCwd = false;		/**	 * If true, this means command was disabled by connector.	 * @see this.update()	 *	 * @type  Boolen	 */	this._disabled = false;		/**	 * If true, this command is disabled on serach results	 * 	 * @type  Boolean	 */	this.disableOnSearch = false;		/**	 * Call update() when event select fired	 * 	 * @type  Boolean	 */	this.updateOnSelect = true;		/**	 * Sync toolbar button title on change	 * 	 * @type  Boolean	 */	this.syncTitleOnChange = false;	/**	 * Keep display of the context menu when command execution	 * 	 * @type  Boolean	 */	this.keepContextmenu = false;		/**	 * elFinder events defaults handlers.	 * Inside handlers "this" is current command object	 *	 * @type  Object	 */	this._handlers = {		enable  : function() { this.update(void(0), this.value); },		disable : function() { this.update(-1, this.value); },		'open reload load sync'    : function() { 			this._disabled = !(this.alwaysEnabled || this.fm.isCommandEnabled(this.name));			this.update(void(0), this.value);			this.change(); 		}	};		/**	 * elFinder events handlers.	 * Inside handlers "this" is current command object	 *	 * @type  Object	 */	this.handlers = {};		/**	 * Shortcuts	 *	 * @type  Array	 */	this.shortcuts = [];		/**	 * Command options	 *	 * @type  Object	 */	this.options = {ui : 'button'};		/**	 * Callback functions on `change` event	 * 	 * @type  Array	 */	this.listeners = [];	/**	 * Prepare object -	 * bind events and shortcuts	 *	 * @return void	 */	this.setup = function(name, opts) {		var self = this,			fm   = this.fm,			setCallback = function(s) {				var cb = s.callback || function(e) {							fm.exec(self.name, void(0), {							_userAction: true,							_currentType: 'shortcut'						});					};				s.callback = function(e) {					var enabled, checks = {};					if (self.enabled()) {						if (fm.searchStatus.state < 2) {							enabled = fm.isCommandEnabled(self.name);						} else {							$.each(fm.selected(), function(i, h) {								if (fm.optionsByHashes[h]) {									checks[h] = true;								} else {									$.each(fm.volOptions, function(id) {										if (!checks[id] && h.indexOf(id) === 0) {											checks[id] = true;											return false;										}									});								}							});							$.each(checks, function(h) {								enabled = fm.isCommandEnabled(self.name, h);								if (! enabled) {									return false;								}							});						}						if (enabled) {							self.event = e;							cb.call(self);							delete self.event;						}					}				};			},			i, s, sc;		this.name      = name;		this.title     = fm.messages['cmd'+name] ? fm.i18n('cmd'+name)		               : ((this.extendsCmd && fm.messages['cmd'+this.extendsCmd]) ? fm.i18n('cmd'+this.extendsCmd) : name);		this.options   = Object.assign({}, this.options, opts);		this.listeners = [];		this.dialogClass = 'elfinder-dialog-' + name;		if (opts.shortcuts) {			if (typeof opts.shortcuts === 'function') {				sc = opts.shortcuts(this.fm, this.shortcuts);			} else if (Array.isArray(opts.shortcuts)) {				sc = opts.shortcuts;			}			this.shortcuts = sc || [];		}		if (this.updateOnSelect) {			this._handlers.select = function() { this.update(void(0), this.value); };		}		$.each(Object.assign({}, self._handlers, self.handlers), function(cmd, handler) {			fm.bind(cmd, $.proxy(handler, self));		});		for (i = 0; i < this.shortcuts.length; i++) {			s = this.shortcuts[i];			setCallback(s);			!s.description && (s.description = this.title);			fm.shortcut(s);		}		if (this.disableOnSearch) {			fm.bind('search searchend', function() {				self._disabled = this.type === 'search'? true : ! (this.alwaysEnabled || fm.isCommandEnabled(name));				self.update(void(0), self.value);			});		}		this.init();	};	/**	 * Command specific init stuffs	 *	 * @return void	 */	this.init = function() {};	/**	 * Exec command	 *	 * @param  Array         target files hashes	 * @param  Array|Object  command value	 * @return $.Deferred	 */	this.exec = function(files, opts) { 		return $.Deferred().reject(); 	};		this.getUndo = function(opts, resData) {		return false;	};		/**	 * Return true if command disabled.	 *	 * @return Boolen	 */	this.disabled = function() {		return this.state < 0;	};		/**	 * Return true if command enabled.	 *	 * @return Boolen	 */	this.enabled = function() {		return this.state > -1;	};		/**	 * Return true if command active.	 *	 * @return Boolen	 */	this.active = function() {		return this.state > 0;	};		/**	 * Return current command state.	 * Must be overloaded in most commands	 *	 * @return Number	 */	this.getstate = function() {		return -1;	};		/**	 * Update command state/value	 * and rize 'change' event if smth changed	 *	 * @param  Number  new state or undefined to auto update state	 * @param  mixed   new value	 * @return void	 */	this.update = function(s, v) {		var state = this.state,			value = this.value;		if (this._disabled && this.fm.searchStatus === 0) {			this.state = -1;		} else {			this.state = s !== void(0) ? s : this.getstate();		}		this.value = v;				if (state != this.state || value != this.value) {			this.change();		}	};		/**	 * Bind handler / fire 'change' event.	 *	 * @param  Function|undefined  event callback	 * @return void	 */	this.change = function(c) {		var cmd, i;				if (typeof(c) === 'function') {			this.listeners.push(c);					} else {			for (i = 0; i < this.listeners.length; i++) {				cmd = this.listeners[i];				try {					cmd(this.state, this.value);				} catch (e) {					this.fm.debug('error', e);				}			}		}		return this;	};		/**	 * With argument check given files hashes and return list of existed files hashes.	 * Without argument return selected files hashes.	 *	 * @param  Array|String|void  hashes	 * @return Array	 */	this.hashes = function(hashes) {		return hashes			? $.grep(Array.isArray(hashes) ? hashes : [hashes], function(hash) { return fm.file(hash) ? true : false; })			: fm.selected();	};		/**	 * Return only existed files from given fils hashes | selected files	 *	 * @param  Array|String|void  hashes	 * @return Array	 */	this.files = function(hashes) {		var fm = this.fm;				return hashes			? $.map(Array.isArray(hashes) ? hashes : [hashes], function(hash) { return fm.file(hash) || null; })			: fm.selectedFiles();	};	/**	 * Wrapper to fm.dialog()	 *	 * @param  String|DOMElement  content	 * @param  Object             options	 * @return Object             jQuery element object	 */	this.fmDialog = function(content, options) {		if (options.cssClass) {			options.cssClass += ' ' + this.dialogClass;		} else {			options.cssClass = this.dialogClass;		}		return this.fm.dialog(content, options);	};};/* * File: /js/elFinder.resources.js *//** * elFinder resources registry. * Store shared data * * @type Object * @author Dmitry (dio) Levashov **/elFinder.prototype.resources = {	'class' : {		hover       : 'ui-state-hover',		active      : 'ui-state-active',		disabled    : 'ui-state-disabled',		draggable   : 'ui-draggable',		droppable   : 'ui-droppable',		adroppable  : 'elfinder-droppable-active',		cwdfile     : 'elfinder-cwd-file',		cwd         : 'elfinder-cwd',		tree        : 'elfinder-tree',		treeroot    : 'elfinder-navbar-root',		navdir      : 'elfinder-navbar-dir',		navdirwrap  : 'elfinder-navbar-dir-wrapper',		navarrow    : 'elfinder-navbar-arrow',		navsubtree  : 'elfinder-navbar-subtree',		navcollapse : 'elfinder-navbar-collapsed',		navexpand   : 'elfinder-navbar-expanded',		treedir     : 'elfinder-tree-dir',		placedir    : 'elfinder-place-dir',		searchbtn   : 'elfinder-button-search',		editing     : 'elfinder-to-editing',		preventback : 'elfinder-prevent-back',		tabstab     : 'ui-state-default ui-tabs-tab ui-corner-top ui-tab',		tabsactive  : 'ui-tabs-active ui-state-active'	},	tpl : {		perms      : '<span class="elfinder-perms"/>',		lock       : '<span class="elfinder-lock"/>',		symlink    : '<span class="elfinder-symlink"/>',		navicon    : '<span class="elfinder-nav-icon"/>',		navspinner : '<span class="elfinder-spinner elfinder-navbar-spinner"/>',		navdir     : '<div class="elfinder-navbar-wrapper{root}"><span id="{id}" class="ui-corner-all elfinder-navbar-dir {cssclass}"><span class="elfinder-navbar-arrow"/><span class="elfinder-navbar-icon" {style}/>{symlink}{permissions}{name}</span><div class="elfinder-navbar-subtree" style="display:none"/></div>',		placedir   : '<div class="elfinder-navbar-wrapper"><span id="{id}" class="ui-corner-all elfinder-navbar-dir {cssclass}" title="{title}"><span class="elfinder-navbar-arrow"/><span class="elfinder-navbar-icon" {style}/>{symlink}{permissions}{name}</span><div class="elfinder-navbar-subtree" style="display:none"/></div>'			},	// mimes.text will be overwritten with connector config if `textMimes` is included in initial response	// @see php/elFInder.class.php `public static $textMimes`	mimes : {		text : [			'application/dash+xml',			'application/docbook+xml',			'application/javascript',			'application/json',			'application/plt',			'application/sat',			'application/sql',			'application/step',			'application/vnd.hp-hpgl',			'application/x-awk',			'application/x-config',			'application/x-csh',			'application/x-empty',			'application/x-mpegurl',			'application/x-perl',			'application/x-php',			'application/x-web-config',			'application/xhtml+xml',			'application/xml',			'audio/x-mp3-playlist',			'image/cgm',			'image/svg+xml',			'image/vnd.dxf',			'model/iges'		]	},		mixin : {		make : function() {						var self = this,				fm   = this.fm,				cmd  = this.name,				req  = this.requestCmd || cmd,				wz   = fm.getUI('workzone'),				org  = (this.origin && this.origin === 'navbar')? 'tree' : 'cwd',				ui   = fm.getUI(org),				tree = (org === 'tree'),				find = tree? 'navHash2Id' : 'cwdHash2Id',				tarea= (! tree && fm.storage('view') != 'list'),				sel  = fm.selected(),				move = this.move || false,				empty= wz.hasClass('elfinder-cwd-wrapper-empty'),				unselect = function() {					requestAnimationFrame(function() {						input && input.trigger('blur');					});				},				rest = function(){					if (!overlay.is(':hidden')) {						overlay.elfinderoverlay('hide').off('click close', cancel);					}					pnode.removeClass('ui-front')						.css('position', '')						.off('unselect.'+fm.namespace, unselect);					if (tarea) {						nnode && nnode.css('max-height', '');					} else if (!tree) {						pnode.css('width', '')							.parent('td').css('overflow', '');					}				}, colwidth,				dfrd = $.Deferred()					.fail(function(error) {						dstCls && dst.attr('class', dstCls);						empty && wz.addClass('elfinder-cwd-wrapper-empty');						if (sel) {							move && fm.trigger('unlockfiles', {files: sel});							fm.clipboard([]);							fm.trigger('selectfiles', { files: sel });						}						error && fm.error(error);					})					.always(function() {						rest();						cleanup();						fm.enable().unbind('open', openCallback).trigger('resMixinMake');					}),				id    = 'tmp_'+parseInt(Math.random()*100000),				phash = this.data && this.data.target? this.data.target : (tree? fm.file(sel[0]).hash : fm.cwd().hash),				date = new Date(),				file   = {					hash  : id,					phash : phash,					name  : fm.uniqueName(this.prefix, phash),					mime  : this.mime,					read  : true,					write : true,					date  : 'Today '+date.getHours()+':'+date.getMinutes(),					move  : move				},				data = this.data || {},				node = ui.trigger('create.'+fm.namespace, file).find('#'+fm[find](id)),				nnode, pnode,				overlay = fm.getUI('overlay'),				cleanup = function() {					if (node && node.length) {						input.off();						node.hide();						fm.unselectfiles({files : [id]}).unbind('resize', resize);						requestAnimationFrame(function() {							if (tree) {								node.closest('.elfinder-navbar-wrapper').remove();							} else {								node.remove();							}						});					}				},				cancel = function(e) { 					if (!overlay.is(':hidden')) {						pnode.css('z-index', '');					}					if (! inError) {						cleanup();						dfrd.reject();						if (e) {							e.stopPropagation();							e.preventDefault();						}					}				},				input = $(tarea? '<textarea/>' : '<input type="text"/>')					.on('keyup text', function(){						if (tarea) {							this.style.height = '1px';							this.style.height = this.scrollHeight + 'px';						} else if (colwidth) {							this.style.width = colwidth + 'px';							if (this.scrollWidth > colwidth) {								this.style.width = this.scrollWidth + 10 + 'px';							}						}					})					.on('keydown', function(e) {						e.stopImmediatePropagation();						if (e.keyCode == $.ui.keyCode.ESCAPE) {							dfrd.reject();						} else if (e.keyCode == $.ui.keyCode.ENTER) {							input.trigger('blur');						}					})					.on('mousedown click dblclick', function(e) {						e.stopPropagation();						if (e.type === 'dblclick') {							e.preventDefault();						}					})					.on('blur', function() {						var name   = $.trim(input.val()),							parent = input.parent(),							valid  = true,							cut;						if (!overlay.is(':hidden')) {							pnode.css('z-index', '');						}						if (name === '') {							return cancel();						}						if (!inError && parent.length) {							if (fm.options.validName && fm.options.validName.test) {								try {									valid = fm.options.validName.test(name);								} catch(e) {									valid = false;								}							}							if (!name || name === '.' || name === '..' || !valid) {								inError = true;								fm.error(file.mime === 'directory'? 'errInvDirname' : 'errInvName', {modal: true, close: function(){setTimeout(select, 120);}});								return false;							}							if (fm.fileByName(name, phash)) {								inError = true;								fm.error(['errExists', name], {modal: true, close: function(){setTimeout(select, 120);}});								return false;							}							cut = (sel && move)? fm.exec('cut', sel) : null;							$.when(cut)							.done(function() {								var toast   = {},									nextAct = {};																rest();								input.hide().before($('<span>').text(name));								fm.lockfiles({files : [id]});								fm.request({										data        : Object.assign({cmd : req, name : name, target : phash}, data || {}), 										notify      : {type : req, cnt : 1},										preventFail : true,										syncOnFail  : true,										navigate    : {toast : toast},									})									.fail(function(error) {										fm.unlockfiles({files : [id]});										inError = true;										input.show().prev().remove();										fm.error(error, {											modal: true,											close: function() {												if (Array.isArray(error) && $.inArray('errUploadMime', error) !== -1) {													dfrd.notify('errUploadMime').reject();												} else {													setTimeout(select, 120);												}											}										});									})									.done(function(data) {										if (data && data.added && data.added[0]) {											var item    = data.added[0],												dirhash = item.hash,												newItem = ui.find('#'+fm[find](dirhash)),												acts    = {													'directory' : { cmd: 'open', msg: 'cmdopendir' },													'text'      : { cmd: 'edit', msg: 'cmdedit' },													'default'   : { cmd: 'open', msg: 'cmdopen' }												},												tmpMimes;											if (sel && move) {												fm.one(req+'done', function() {													fm.exec('paste', dirhash);												});											}											if (!move) {												if (fm.mimeIsText(item.mime) && !fm.mimesCanMakeEmpty[item.mime] && fm.mimeTypes[item.mime]) {													fm.trigger('canMakeEmptyFile', {mimes: [item.mime], unshift: true});													tmpMimes = {};													tmpMimes[item.mime] = fm.mimeTypes[item.mime];													fm.storage('mkfileTextMimes', Object.assign(tmpMimes, fm.storage('mkfileTextMimes') || {}));												}												Object.assign(nextAct, nextAction || acts[item.mime] || acts[item.mime.split('/')[0]] || acts[(fm.mimesCanMakeEmpty[item.mime] || $.inArray(item.mime, fm.resources.mimes.text) !== -1) ? 'text' : 'none'] || acts['default']);												Object.assign(toast, nextAct.cmd ? {													incwd    : {msg: fm.i18n(['complete', fm.i18n('cmd'+cmd)]), action: nextAct},													inbuffer : {msg: fm.i18n(['complete', fm.i18n('cmd'+cmd)]), action: nextAct}												} : {													inbuffer : {msg: fm.i18n(['complete', fm.i18n('cmd'+cmd)])}												});											}										}										dfrd.resolve(data);									});							})							.fail(function() {								dfrd.reject();							});						}					})					.on('dragenter dragleave dragover drop', function(e) {						// stop bubbling to prevent upload with native drop event						e.stopPropagation();					}),				select = function() {					var name = fm.splitFileExtention(input.val())[0];					if (!inError && fm.UA.Mobile && !fm.UA.iOS) { // since iOS has a bug? (z-index not effect) so disable it						overlay.on('click close', cancel).elfinderoverlay('show');						pnode.css('z-index', overlay.css('z-index') + 1);					}					inError = false;					! fm.enabled() && fm.enable();					input.trigger('focus').trigger('select');					input[0].setSelectionRange && input[0].setSelectionRange(0, name.length);				},				resize = function() {					node.trigger('scrolltoview', {blink : false});				},				openCallback = function() {					dfrd && (dfrd.state() === 'pending') && dfrd.reject();				},				inError = false,				nextAction,				// for tree				dst, dstCls, collapsed, expanded, arrow, subtree;			if (!fm.isCommandEnabled(req, phash) || !node.length) {				return dfrd.reject();			}			if ($.isPlainObject(self.nextAction)){				nextAction = Object.assign({}, self.nextAction);			}						if (tree) {				dst = $('#'+fm[find](phash));				collapsed = fm.res('class', 'navcollapse');				expanded  = fm.res('class', 'navexpand');				arrow = fm.res('class', 'navarrow');				subtree = fm.res('class', 'navsubtree');								node.closest('.'+subtree).show();				if (! dst.hasClass(collapsed)) {					dstCls = dst.attr('class');					dst.addClass(collapsed+' '+expanded+' elfinder-subtree-loaded');				}				if (dst.is('.'+collapsed+':not(.'+expanded+')')) {					dst.children('.'+arrow).trigger('click').data('dfrd').done(function() {						if (input.val() === file.name) {							input.val(fm.uniqueName(self.prefix, phash)).trigger('select').trigger('focus');						}					});				}				nnode = node.contents().filter(function(){ return this.nodeType==3 && $(this).parent().attr('id') === fm.navHash2Id(file.hash); });				pnode = nnode.parent();				nnode.replaceWith(input.val(file.name));			} else {				empty && wz.removeClass('elfinder-cwd-wrapper-empty');				nnode = node.find('.elfinder-cwd-filename');				pnode = nnode.parent();				if (tarea) {					nnode.css('max-height', 'none');				} else {					colwidth = pnode.width();					pnode.width(colwidth - 15)						.parent('td').css('overflow', 'visible');				}				nnode.empty().append(input.val(file.name));			}			pnode.addClass('ui-front')				.css('position', 'relative')				.on('unselect.'+fm.namespace, unselect);						fm.bind('resize', resize).one('open', openCallback);						input.trigger('keyup');			select();			return dfrd;		}	},	blink: function(elm, mode) {				var acts = {			slowonce : function(){elm.hide().delay(250).fadeIn(750).delay(500).fadeOut(3500);},			lookme   : function(){elm.show().fadeOut(500).fadeIn(750);}		}, func;		mode = mode || 'slowonce';				func = acts[mode] || acts['lookme'];				elm.stop(true, true);		func();	}};/* * File: /js/jquery.dialogelfinder.js *//** * @class dialogelfinder - open elFinder in dialog window * * @param  Object  elFinder options with dialog options * @example * $(selector).dialogelfinder({ *     // some elfinder options *     title          : 'My files', // dialog title, default = "Files" *     width          : 850,        // dialog width, default 840 *     autoOpen       : false,      // if false - dialog will not be opened after init, default = true *     destroyOnClose : true        // destroy elFinder on close dialog, default = false * }) * @author Dmitry (dio) Levashov **/$.fn.dialogelfinder = function(opts) {		var position = 'elfinderPosition',		destroy  = 'elfinderDestroyOnClose',		node;		this.not('.elfinder').each(function() {				var doc     = $(document),			toolbar = $('<div class="ui-widget-header dialogelfinder-drag ui-corner-top">'+(opts.title || 'Files')+'</div>'),			button  = $('<a href="#" class="dialogelfinder-drag-close ui-corner-all"><span class="ui-icon ui-icon-closethick"> </span></a>')				.appendTo(toolbar)				.on('click', function(e) {					e.preventDefault();										node.dialogelfinder('close');				}),			node    = $(this).addClass('dialogelfinder')				.css('position', 'absolute')				.hide()				.appendTo('body')				.draggable({					handle : '.dialogelfinder-drag',					containment : 'window',					stop : function() {						node.trigger('resize');						elfinder.trigger('resize');					}				})				.elfinder(opts)				.prepend(toolbar),			elfinder = node.elfinder('instance');						node.width(parseInt(node.width()) || 840) // fix width if set to "auto"			.data(destroy, !!opts.destroyOnClose)			.find('.elfinder-toolbar').removeClass('ui-corner-top');				opts.position && node.data(position, opts.position);				opts.autoOpen !== false && $(this).dialogelfinder('open');	});		if (opts == 'open') {		var node = $(this),			pos  = node.data(position) || {				top  : parseInt($(document).scrollTop() + ($(window).height() < node.height() ? 2 : ($(window).height() - node.height())/2)),				left : parseInt($(document).scrollLeft() + ($(window).width() < node.width()  ? 2 : ($(window).width()  - node.width())/2))			};		if (node.is(':hidden')) {			node.addClass('ui-front').css(pos).show().trigger('resize');			setTimeout(function() {				// fix resize icon position and make elfinder active				node.trigger('resize').trigger('mousedown');			}, 200);		}	} else if (opts == 'close') {		node = $(this).removeClass('ui-front');					if (node.is(':visible')) {			!!node.data(destroy)				? node.elfinder('destroy').remove()				: node.elfinder('close');		}	} else if (opts == 'instance') {		return $(this).getElFinder();	}	return this;};/* * File: /js/i18n/elfinder.en.js *//** * English translation * @author Troex Nevelin <troex@fury.scancode.ru> * @author Naoki Sawada <hypweb+elfinder@gmail.com> * @version 2018-10-19 */// elfinder.en.js is integrated into elfinder.(full|min).js by jake buildif (typeof elFinder === 'function' && elFinder.prototype.i18) {	elFinder.prototype.i18.en = {		translator : 'Troex Nevelin <troex@fury.scancode.ru>, Naoki Sawada <hypweb+elfinder@gmail.com>',		language   : 'English',		direction  : 'ltr',		dateFormat : 'M d, Y h:i A', // will show like: Aug 24, 2018 04:39 PM		fancyDateFormat : '$1 h:i A', // will show like: Today 04:39 PM		nonameDateFormat : 'ymd-His', // noname upload will show like: 180824-163916		messages   : {			/********************************** errors **********************************/			'error'                : 'Error',			'errUnknown'           : 'Unknown error.',			'errUnknownCmd'        : 'Unknown command.',			'errJqui'              : 'Invalid jQuery UI configuration. Selectable, draggable and droppable components must be included.',			'errNode'              : 'elFinder requires DOM Element to be created.',			'errURL'               : 'Invalid elFinder configuration! URL option is not set.',			'errAccess'            : 'Access denied.',			'errConnect'           : 'Unable to connect to backend.',			'errAbort'             : 'Connection aborted.',			'errTimeout'           : 'Connection timeout.',			'errNotFound'          : 'Backend not found.',			'errResponse'          : 'Invalid backend response.',			'errConf'              : 'Invalid backend configuration.',			'errJSON'              : 'PHP JSON module not installed.',			'errNoVolumes'         : 'Readable volumes not available.',			'errCmdParams'         : 'Invalid parameters for command "$1".',			'errDataNotJSON'       : 'Data is not JSON.',			'errDataEmpty'         : 'Data is empty.',			'errCmdReq'            : 'Backend request requires command name.',			'errOpen'              : 'Unable to open "$1".',			'errNotFolder'         : 'Object is not a folder.',			'errNotFile'           : 'Object is not a file.',			'errRead'              : 'Unable to read "$1".',			'errWrite'             : 'Unable to write into "$1".',			'errPerm'              : 'Permission denied.',			'errLocked'            : '"$1" is locked and can not be renamed, moved or removed.',			'errExists'            : 'Item named "$1" already exists.',			'errInvName'           : 'Invalid file name.',			'errInvDirname'        : 'Invalid folder name.',  // from v2.1.24 added 12.4.2017			'errFolderNotFound'    : 'Folder not found.',			'errFileNotFound'      : 'File not found.',			'errTrgFolderNotFound' : 'Target folder "$1" not found.',			'errPopup'             : 'Browser prevented opening popup window. To open file enable it in browser options.',			'errMkdir'             : 'Unable to create folder "$1".',			'errMkfile'            : 'Unable to create file "$1".',			'errRename'            : 'Unable to rename "$1".',			'errCopyFrom'          : 'Copying files from volume "$1" not allowed.',			'errCopyTo'            : 'Copying files to volume "$1" not allowed.',			'errMkOutLink'         : 'Unable to create a link to outside the volume root.', // from v2.1 added 03.10.2015			'errUpload'            : 'Upload error.',  // old name - errUploadCommon			'errUploadFile'        : 'Unable to upload "$1".', // old name - errUpload			'errUploadNoFiles'     : 'No files found for upload.',			'errUploadTotalSize'   : 'Data exceeds the maximum allowed size.', // old name - errMaxSize			'errUploadFileSize'    : 'File exceeds maximum allowed size.', //  old name - errFileMaxSize			'errUploadMime'        : 'File type not allowed.',			'errUploadTransfer'    : '"$1" transfer error.',			'errUploadTemp'        : 'Unable to make temporary file for upload.', // from v2.1 added 26.09.2015			'errNotReplace'        : 'Object "$1" already exists at this location and can not be replaced by object with another type.', // new			'errReplace'           : 'Unable to replace "$1".',			'errSave'              : 'Unable to save "$1".',			'errCopy'              : 'Unable to copy "$1".',			'errMove'              : 'Unable to move "$1".',			'errCopyInItself'      : 'Unable to copy "$1" into itself.',			'errRm'                : 'Unable to remove "$1".',			'errTrash'             : 'Unable into trash.', // from v2.1.24 added 30.4.2017			'errRmSrc'             : 'Unable remove source file(s).',			'errExtract'           : 'Unable to extract files from "$1".',			'errArchive'           : 'Unable to create archive.',			'errArcType'           : 'Unsupported archive type.',			'errNoArchive'         : 'File is not archive or has unsupported archive type.',			'errCmdNoSupport'      : 'Backend does not support this command.',			'errReplByChild'       : 'The folder "$1" can\'t be replaced by an item it contains.',			'errArcSymlinks'       : 'For security reason denied to unpack archives contains symlinks or files with not allowed names.', // edited 24.06.2012			'errArcMaxSize'        : 'Archive files exceeds maximum allowed size.',			'errResize'            : 'Unable to resize "$1".',			'errResizeDegree'      : 'Invalid rotate degree.',  // added 7.3.2013			'errResizeRotate'      : 'Unable to rotate image.',  // added 7.3.2013			'errResizeSize'        : 'Invalid image size.',  // added 7.3.2013			'errResizeNoChange'    : 'Image size not changed.',  // added 7.3.2013			'errUsupportType'      : 'Unsupported file type.',			'errNotUTF8Content'    : 'File "$1" is not in UTF-8 and cannot be edited.',  // added 9.11.2011			'errNetMount'          : 'Unable to mount "$1".', // added 17.04.2012			'errNetMountNoDriver'  : 'Unsupported protocol.',     // added 17.04.2012			'errNetMountFailed'    : 'Mount failed.',         // added 17.04.2012			'errNetMountHostReq'   : 'Host required.', // added 18.04.2012			'errSessionExpires'    : 'Your session has expired due to inactivity.',			'errCreatingTempDir'   : 'Unable to create temporary directory: "$1"',			'errFtpDownloadFile'   : 'Unable to download file from FTP: "$1"',			'errFtpUploadFile'     : 'Unable to upload file to FTP: "$1"',			'errFtpMkdir'          : 'Unable to create remote directory on FTP: "$1"',			'errArchiveExec'       : 'Error while archiving files: "$1"',			'errExtractExec'       : 'Error while extracting files: "$1"',			'errNetUnMount'        : 'Unable to unmount.', // from v2.1 added 30.04.2012			'errConvUTF8'          : 'Not convertible to UTF-8', // from v2.1 added 08.04.2014			'errFolderUpload'      : 'Try the modern browser, If you\'d like to upload the folder.', // from v2.1 added 26.6.2015			'errSearchTimeout'     : 'Timed out while searching "$1". Search result is partial.', // from v2.1 added 12.1.2016			'errReauthRequire'     : 'Re-authorization is required.', // from v2.1.10 added 24.3.2016			'errMaxTargets'        : 'Max number of selectable items is $1.', // from v2.1.17 added 17.10.2016			'errRestore'           : 'Unable to restore from the trash. Can\'t identify the restore destination.', // from v2.1.24 added 3.5.2017			'errEditorNotFound'    : 'Editor not found to this file type.', // from v2.1.25 added 23.5.2017			'errServerError'       : 'Error occurred on the server side.', // from v2.1.25 added 16.6.2017			'errEmpty'             : 'Unable to empty folder "$1".', // from v2.1.25 added 22.6.2017			/******************************* commands names ********************************/			'cmdarchive'   : 'Create archive',			'cmdback'      : 'Back',			'cmdcopy'      : 'Copy',			'cmdcut'       : 'Cut',			'cmddownload'  : 'Download',			'cmdduplicate' : 'Duplicate',			'cmdedit'      : 'Edit file',			'cmdextract'   : 'Extract files from archive',			'cmdforward'   : 'Forward',			'cmdgetfile'   : 'Select files',			'cmdhelp'      : 'About this software',			'cmdhome'      : 'Root',			'cmdinfo'      : 'Get info',			'cmdmkdir'     : 'New folder',			'cmdmkdirin'   : 'Into New Folder', // from v2.1.7 added 19.2.2016			'cmdmkfile'    : 'New file',			'cmdopen'      : 'Open',			'cmdpaste'     : 'Paste',			'cmdquicklook' : 'Preview',			'cmdreload'    : 'Reload',			'cmdrename'    : 'Rename',			'cmdrm'        : 'Delete',			'cmdtrash'     : 'Into trash', //from v2.1.24 added 29.4.2017			'cmdrestore'   : 'Restore', //from v2.1.24 added 3.5.2017			'cmdsearch'    : 'Find files',			'cmdup'        : 'Go to parent folder',			'cmdupload'    : 'Upload files',			'cmdview'      : 'View',			'cmdresize'    : 'Resize & Rotate',			'cmdsort'      : 'Sort',			'cmdnetmount'  : 'Mount network volume', // added 18.04.2012			'cmdnetunmount': 'Unmount', // from v2.1 added 30.04.2012			'cmdplaces'    : 'To Places', // added 28.12.2014			'cmdchmod'     : 'Change mode', // from v2.1 added 20.6.2015			'cmdopendir'   : 'Open a folder', // from v2.1 added 13.1.2016			'cmdcolwidth'  : 'Reset column width', // from v2.1.13 added 12.06.2016			'cmdfullscreen': 'Full Screen', // from v2.1.15 added 03.08.2016			'cmdmove'      : 'Move', // from v2.1.15 added 21.08.2016			'cmdempty'     : 'Empty the folder', // from v2.1.25 added 22.06.2017			'cmdundo'      : 'Undo', // from v2.1.27 added 31.07.2017			'cmdredo'      : 'Redo', // from v2.1.27 added 31.07.2017			'cmdpreference': 'Preferences', // from v2.1.27 added 03.08.2017			'cmdselectall' : 'Select all', // from v2.1.28 added 15.08.2017			'cmdselectnone': 'Select none', // from v2.1.28 added 15.08.2017			'cmdselectinvert': 'Invert selection', // from v2.1.28 added 15.08.2017			'cmdopennew'   : 'Open in new window', // from v2.1.38 added 3.4.2018			'cmdhide'      : 'Hide (Preference)', // from v2.1.41 added 24.7.2018			/*********************************** buttons ***********************************/			'btnClose'  : 'Close',			'btnSave'   : 'Save',			'btnRm'     : 'Remove',			'btnApply'  : 'Apply',			'btnCancel' : 'Cancel',			'btnNo'     : 'No',			'btnYes'    : 'Yes',			'btnMount'  : 'Mount',  // added 18.04.2012			'btnApprove': 'Goto $1 & approve', // from v2.1 added 26.04.2012			'btnUnmount': 'Unmount', // from v2.1 added 30.04.2012			'btnConv'   : 'Convert', // from v2.1 added 08.04.2014			'btnCwd'    : 'Here',      // from v2.1 added 22.5.2015			'btnVolume' : 'Volume',    // from v2.1 added 22.5.2015			'btnAll'    : 'All',       // from v2.1 added 22.5.2015			'btnMime'   : 'MIME Type', // from v2.1 added 22.5.2015			'btnFileName':'Filename',  // from v2.1 added 22.5.2015			'btnSaveClose': 'Save & Close', // from v2.1 added 12.6.2015			'btnBackup' : 'Backup', // fromv2.1 added 28.11.2015			'btnRename'    : 'Rename',      // from v2.1.24 added 6.4.2017			'btnRenameAll' : 'Rename(All)', // from v2.1.24 added 6.4.2017			'btnPrevious' : 'Prev ($1/$2)', // from v2.1.24 added 11.5.2017			'btnNext'     : 'Next ($1/$2)', // from v2.1.24 added 11.5.2017			'btnSaveAs'   : 'Save As', // from v2.1.25 added 24.5.2017			/******************************** notifications ********************************/			'ntfopen'     : 'Open folder',			'ntffile'     : 'Open file',			'ntfreload'   : 'Reload folder content',			'ntfmkdir'    : 'Creating folder',			'ntfmkfile'   : 'Creating files',			'ntfrm'       : 'Delete items',			'ntfcopy'     : 'Copy items',			'ntfmove'     : 'Move items',			'ntfprepare'  : 'Checking existing items',			'ntfrename'   : 'Rename files',			'ntfupload'   : 'Uploading files',			'ntfdownload' : 'Downloading files',			'ntfsave'     : 'Save files',			'ntfarchive'  : 'Creating archive',			'ntfextract'  : 'Extracting files from archive',			'ntfsearch'   : 'Searching files',			'ntfresize'   : 'Resizing images',			'ntfsmth'     : 'Doing something',			'ntfloadimg'  : 'Loading image',			'ntfnetmount' : 'Mounting network volume', // added 18.04.2012			'ntfnetunmount': 'Unmounting network volume', // from v2.1 added 30.04.2012			'ntfdim'      : 'Acquiring image dimension', // added 20.05.2013			'ntfreaddir'  : 'Reading folder infomation', // from v2.1 added 01.07.2013			'ntfurl'      : 'Getting URL of link', // from v2.1 added 11.03.2014			'ntfchmod'    : 'Changing file mode', // from v2.1 added 20.6.2015			'ntfpreupload': 'Verifying upload file name', // from v2.1 added 31.11.2015			'ntfzipdl'    : 'Creating a file for download', // from v2.1.7 added 23.1.2016			'ntfparents'  : 'Getting path infomation', // from v2.1.17 added 2.11.2016			'ntfchunkmerge': 'Processing the uploaded file', // from v2.1.17 added 2.11.2016			'ntftrash'    : 'Doing throw in the trash', // from v2.1.24 added 2.5.2017			'ntfrestore'  : 'Doing restore from the trash', // from v2.1.24 added 3.5.2017			'ntfchkdir'   : 'Checking destination folder', // from v2.1.24 added 3.5.2017			'ntfundo'     : 'Undoing previous operation', // from v2.1.27 added 31.07.2017			'ntfredo'     : 'Redoing previous undone', // from v2.1.27 added 31.07.2017			'ntfchkcontent' : 'Checking contents', // from v2.1.41 added 3.8.2018			/*********************************** volumes *********************************/			'volume_Trash' : 'Trash', //from v2.1.24 added 29.4.2017			/************************************ dates **********************************/			'dateUnknown' : 'unknown',			'Today'       : 'Today',			'Yesterday'   : 'Yesterday',			'msJan'       : 'Jan',			'msFeb'       : 'Feb',			'msMar'       : 'Mar',			'msApr'       : 'Apr',			'msMay'       : 'May',			'msJun'       : 'Jun',			'msJul'       : 'Jul',			'msAug'       : 'Aug',			'msSep'       : 'Sep',			'msOct'       : 'Oct',			'msNov'       : 'Nov',			'msDec'       : 'Dec',			'January'     : 'January',			'February'    : 'February',			'March'       : 'March',			'April'       : 'April',			'May'         : 'May',			'June'        : 'June',			'July'        : 'July',			'August'      : 'August',			'September'   : 'September',			'October'     : 'October',			'November'    : 'November',			'December'    : 'December',			'Sunday'      : 'Sunday',			'Monday'      : 'Monday',			'Tuesday'     : 'Tuesday',			'Wednesday'   : 'Wednesday',			'Thursday'    : 'Thursday',			'Friday'      : 'Friday',			'Saturday'    : 'Saturday',			'Sun'         : 'Sun',			'Mon'         : 'Mon',			'Tue'         : 'Tue',			'Wed'         : 'Wed',			'Thu'         : 'Thu',			'Fri'         : 'Fri',			'Sat'         : 'Sat',			/******************************** sort variants ********************************/			'sortname'          : 'by name',			'sortkind'          : 'by kind',			'sortsize'          : 'by size',			'sortdate'          : 'by date',			'sortFoldersFirst'  : 'Folders first',			'sortperm'          : 'by permission', // from v2.1.13 added 13.06.2016			'sortmode'          : 'by mode',       // from v2.1.13 added 13.06.2016			'sortowner'         : 'by owner',      // from v2.1.13 added 13.06.2016			'sortgroup'         : 'by group',      // from v2.1.13 added 13.06.2016			'sortAlsoTreeview'  : 'Also Treeview',  // from v2.1.15 added 01.08.2016			/********************************** new items **********************************/			'untitled file.txt' : 'NewFile.txt', // added 10.11.2015			'untitled folder'   : 'NewFolder',   // added 10.11.2015			'Archive'           : 'NewArchive',  // from v2.1 added 10.11.2015			'untitled file'     : 'NewFile.$1',  // from v2.1.41 added 6.8.2018			'extentionfile'     : '$1: File',    // from v2.1.41 added 6.8.2018			'extentiontype'     : '$1: $2',      // from v2.1.43 added 17.10.2018			/********************************** messages **********************************/			'confirmReq'      : 'Confirmation required',			'confirmRm'       : 'Are you sure you want to permanently remove items?<br/>This cannot be undone!',			'confirmRepl'     : 'Replace old file with new one? (If it contains folders, it will be merged. To backup and replace, select Backup.)',			'confirmRest'     : 'Replace existing item with the item in trash?', // fromv2.1.24 added 5.5.2017			'confirmConvUTF8' : 'Not in UTF-8<br/>Convert to UTF-8?<br/>Contents become UTF-8 by saving after conversion.', // from v2.1 added 08.04.2014			'confirmNonUTF8'  : 'Character encoding of this file couldn\'t be detected. It need to temporarily convert to UTF-8 for editting.<br/>Please select character encoding of this file.', // from v2.1.19 added 28.11.2016			'confirmNotSave'  : 'It has been modified.<br/>Losing work if you do not save changes.', // from v2.1 added 15.7.2015			'confirmTrash'    : 'Are you sure you want to move items to trash bin?', //from v2.1.24 added 29.4.2017			'apllyAll'        : 'Apply to all',			'name'            : 'Name',			'size'            : 'Size',			'perms'           : 'Permissions',			'modify'          : 'Modified',			'kind'            : 'Kind',			'read'            : 'read',			'write'           : 'write',			'noaccess'        : 'no access',			'and'             : 'and',			'unknown'         : 'unknown',			'selectall'       : 'Select all items',			'selectfiles'     : 'Select item(s)',			'selectffile'     : 'Select first item',			'selectlfile'     : 'Select last item',			'viewlist'        : 'List view',			'viewicons'       : 'Icons view',			'viewSmall'       : 'Small icons', // from v2.1.39 added 22.5.2018			'viewMedium'      : 'Medium icons', // from v2.1.39 added 22.5.2018			'viewLarge'       : 'Large icons', // from v2.1.39 added 22.5.2018			'viewExtraLarge'  : 'Extra large icons', // from v2.1.39 added 22.5.2018			'places'          : 'Places',			'calc'            : 'Calculate',			'path'            : 'Path',			'aliasfor'        : 'Alias for',			'locked'          : 'Locked',			'dim'             : 'Dimensions',			'files'           : 'Files',			'folders'         : 'Folders',			'items'           : 'Items',			'yes'             : 'yes',			'no'              : 'no',			'link'            : 'Link',			'searcresult'     : 'Search results',			'selected'        : 'selected items',			'about'           : 'About',			'shortcuts'       : 'Shortcuts',			'help'            : 'Help',			'webfm'           : 'Web file manager',			'ver'             : 'Version',			'protocolver'     : 'protocol version',			'homepage'        : 'Project home',			'docs'            : 'Documentation',			'github'          : 'Fork us on GitHub',			'twitter'         : 'Follow us on Twitter',			'facebook'        : 'Join us on Facebook',			'team'            : 'Team',			'chiefdev'        : 'chief developer',			'developer'       : 'developer',			'contributor'     : 'contributor',			'maintainer'      : 'maintainer',			'translator'      : 'translator',			'icons'           : 'Icons',			'dontforget'      : 'and don\'t forget to take your towel',			'shortcutsof'     : 'Shortcuts disabled',			'dropFiles'       : 'Drop files here',			'or'              : 'or',			'selectForUpload' : 'Select files',			'moveFiles'       : 'Move items',			'copyFiles'       : 'Copy items',			'restoreFiles'    : 'Restore items', // from v2.1.24 added 5.5.2017			'rmFromPlaces'    : 'Remove from places',			'aspectRatio'     : 'Aspect ratio',			'scale'           : 'Scale',			'width'           : 'Width',			'height'          : 'Height',			'resize'          : 'Resize',			'crop'            : 'Crop',			'rotate'          : 'Rotate',			'rotate-cw'       : 'Rotate 90 degrees CW',			'rotate-ccw'      : 'Rotate 90 degrees CCW',			'degree'          : '°',			'netMountDialogTitle' : 'Mount network volume', // added 18.04.2012			'protocol'            : 'Protocol', // added 18.04.2012			'host'                : 'Host', // added 18.04.2012			'port'                : 'Port', // added 18.04.2012			'user'                : 'User', // added 18.04.2012			'pass'                : 'Password', // added 18.04.2012			'confirmUnmount'      : 'Are you sure to unmount $1?',  // from v2.1 added 30.04.2012			'dropFilesBrowser': 'Drop or Paste files from browser', // from v2.1 added 30.05.2012			'dropPasteFiles'  : 'Drop files, Paste URLs or images(clipboard) here', // from v2.1 added 07.04.2014			'encoding'        : 'Encoding', // from v2.1 added 19.12.2014			'locale'          : 'Locale',   // from v2.1 added 19.12.2014			'searchTarget'    : 'Target: $1',                // from v2.1 added 22.5.2015			'searchMime'      : 'Search by input MIME Type', // from v2.1 added 22.5.2015			'owner'           : 'Owner', // from v2.1 added 20.6.2015			'group'           : 'Group', // from v2.1 added 20.6.2015			'other'           : 'Other', // from v2.1 added 20.6.2015			'execute'         : 'Execute', // from v2.1 added 20.6.2015			'perm'            : 'Permission', // from v2.1 added 20.6.2015			'mode'            : 'Mode', // from v2.1 added 20.6.2015			'emptyFolder'     : 'Folder is empty', // from v2.1.6 added 30.12.2015			'emptyFolderDrop' : 'Folder is empty\\A Drop to add items', // from v2.1.6 added 30.12.2015			'emptyFolderLTap' : 'Folder is empty\\A Long tap to add items', // from v2.1.6 added 30.12.2015			'quality'         : 'Quality', // from v2.1.6 added 5.1.2016			'autoSync'        : 'Auto sync',  // from v2.1.6 added 10.1.2016			'moveUp'          : 'Move up',  // from v2.1.6 added 18.1.2016			'getLink'         : 'Get URL link', // from v2.1.7 added 9.2.2016			'selectedItems'   : 'Selected items ($1)', // from v2.1.7 added 2.19.2016			'folderId'        : 'Folder ID', // from v2.1.10 added 3.25.2016			'offlineAccess'   : 'Allow offline access', // from v2.1.10 added 3.25.2016			'reAuth'          : 'To re-authenticate', // from v2.1.10 added 3.25.2016			'nowLoading'      : 'Now loading...', // from v2.1.12 added 4.26.2016			'openMulti'       : 'Open multiple files', // from v2.1.12 added 5.14.2016			'openMultiConfirm': 'You are trying to open the $1 files. Are you sure you want to open in browser?', // from v2.1.12 added 5.14.2016			'emptySearch'     : 'Search results is empty in search target.', // from v2.1.12 added 5.16.2016			'editingFile'     : 'It is editing a file.', // from v2.1.13 added 6.3.2016			'hasSelected'     : 'You have selected $1 items.', // from v2.1.13 added 6.3.2016			'hasClipboard'    : 'You have $1 items in the clipboard.', // from v2.1.13 added 6.3.2016			'incSearchOnly'   : 'Incremental search is only from the current view.', // from v2.1.13 added 6.30.2016			'reinstate'       : 'Reinstate', // from v2.1.15 added 3.8.2016			'complete'        : '$1 complete', // from v2.1.15 added 21.8.2016			'contextmenu'     : 'Context menu', // from v2.1.15 added 9.9.2016			'pageTurning'     : 'Page turning', // from v2.1.15 added 10.9.2016			'volumeRoots'     : 'Volume roots', // from v2.1.16 added 16.9.2016			'reset'           : 'Reset', // from v2.1.16 added 1.10.2016			'bgcolor'         : 'Background color', // from v2.1.16 added 1.10.2016			'colorPicker'     : 'Color picker', // from v2.1.16 added 1.10.2016			'8pxgrid'         : '8px Grid', // from v2.1.16 added 4.10.2016			'enabled'         : 'Enabled', // from v2.1.16 added 4.10.2016			'disabled'        : 'Disabled', // from v2.1.16 added 4.10.2016			'emptyIncSearch'  : 'Search results is empty in current view.\\A Press [Enter] to expand search target.', // from v2.1.16 added 5.10.2016			'emptyLetSearch'  : 'First letter search results is empty in current view.', // from v2.1.23 added 24.3.2017			'textLabel'       : 'Text label', // from v2.1.17 added 13.10.2016			'minsLeft'        : '$1 mins left', // from v2.1.17 added 13.11.2016			'openAsEncoding'  : 'Reopen with selected encoding', // from v2.1.19 added 2.12.2016			'saveAsEncoding'  : 'Save with the selected encoding', // from v2.1.19 added 2.12.2016			'selectFolder'    : 'Select folder', // from v2.1.20 added 13.12.2016			'firstLetterSearch': 'First letter search', // from v2.1.23 added 24.3.2017			'presets'         : 'Presets', // from v2.1.25 added 26.5.2017			'tooManyToTrash'  : 'It\'s too many items so it can\'t into trash.', // from v2.1.25 added 9.6.2017			'TextArea'        : 'TextArea', // from v2.1.25 added 14.6.2017			'folderToEmpty'   : 'Empty the folder "$1".', // from v2.1.25 added 22.6.2017			'filderIsEmpty'   : 'There are no items in a folder "$1".', // from v2.1.25 added 22.6.2017			'preference'      : 'Preference', // from v2.1.26 added 28.6.2017			'language'        : 'Language', // from v2.1.26 added 28.6.2017			'clearBrowserData': 'Initialize the settings saved in this browser', // from v2.1.26 added 28.6.2017			'toolbarPref'     : 'Toolbar settings', // from v2.1.27 added 2.8.2017			'charsLeft'       : '... $1 chars left.',  // from v2.1.29 added 30.8.2017			'sum'             : 'Sum', // from v2.1.29 added 28.9.2017			'roughFileSize'   : 'Rough file size', // from v2.1.30 added 2.11.2017			'autoFocusDialog' : 'Focus on the element of dialog with mouseover',  // from v2.1.30 added 2.11.2017			'select'          : 'Select', // from v2.1.30 added 23.11.2017			'selectAction'    : 'Action when select file', // from v2.1.30 added 23.11.2017			'useStoredEditor' : 'Open with the editor used last time', // from v2.1.30 added 23.11.2017			'selectinvert'    : 'Invert selection', // from v2.1.30 added 25.11.2017			'renameMultiple'  : 'Are you sure you want to rename $1 selected items like $2?<br/>This cannot be undone!', // from v2.1.31 added 4.12.2017			'batchRename'     : 'Batch rename', // from v2.1.31 added 8.12.2017			'plusNumber'      : '+ Number', // from v2.1.31 added 8.12.2017			'asPrefix'        : 'Add prefix', // from v2.1.31 added 8.12.2017			'asSuffix'        : 'Add suffix', // from v2.1.31 added 8.12.2017			'changeExtention' : 'Change extention', // from v2.1.31 added 8.12.2017			'columnPref'      : 'Columns settings (List view)', // from v2.1.32 added 6.2.2018			'reflectOnImmediate' : 'All changes will reflect immediately to the archive.', // from v2.1.33 added 2.3.2018			'reflectOnUnmount'   : 'Any changes will not reflect until un-mount this volume.', // from v2.1.33 added 2.3.2018			'unmountChildren' : 'The following volume(s) mounted on this volume also unmounted. Are you sure to unmount it?', // from v2.1.33 added 5.3.2018			'selectionInfo'   : 'Selection Info', // from v2.1.33 added 7.3.2018			'hashChecker'     : 'Algorithms to show the file hash', // from v2.1.33 added 10.3.2018			'infoItems'       : 'Info Items (Selection Info Panel)', // from v2.1.38 added 28.3.2018			'pressAgainToExit': 'Press again to exit.', // from v2.1.38 added 1.4.2018			'toolbar'         : 'Toolbar', // from v2.1.38 added 4.4.2018			'workspace'       : 'Work Space', // from v2.1.38 added 4.4.2018			'dialog'          : 'Dialog', // from v2.1.38 added 4.4.2018			'all'             : 'All', // from v2.1.38 added 4.4.2018			'iconSize'        : 'Icon Size (Icons view)', // from v2.1.39 added 7.5.2018			'editorMaximized' : 'Open the maximized editor window', // from v2.1.40 added 30.6.2018			'editorConvNoApi' : 'Because conversion by API is not currently available, please convert on the website.', //from v2.1.40 added 8.7.2018			'editorConvNeedUpload' : 'After conversion, you must be upload with the item URL or a downloaded file to save the converted file.', //from v2.1.40 added 8.7.2018			'convertOn'       : 'Convert on the site of $1', // from v2.1.40 added 10.7.2018			'integrations'    : 'Integrations', // from v2.1.40 added 11.7.2018			'integrationWith' : 'This elFinder has the following external services integrated. Please check the terms of use, privacy policy, etc. before using it.', // from v2.1.40 added 11.7.2018			'showHidden'      : 'Show hidden items', // from v2.1.41 added 24.7.2018			'hideHidden'      : 'Hide hidden items', // from v2.1.41 added 24.7.2018			'toggleHidden'    : 'Show/Hide hidden items', // from v2.1.41 added 24.7.2018			'makefileTypes'   : 'File types to enable with "New file"', // from v2.1.41 added 7.8.2018			'typeOfTextfile'  : 'Type of the Text file', // from v2.1.41 added 7.8.2018			'add'             : 'Add', // from v2.1.41 added 7.8.2018			'theme'           : 'Theme', // from v2.1.43 added 19.10.2018			'default'         : 'Default', // from v2.1.43 added 19.10.2018			'description'     : 'Description', // from v2.1.43 added 19.10.2018			'website'         : 'Website', // from v2.1.43 added 19.10.2018			'author'          : 'Author', // from v2.1.43 added 19.10.2018			'email'           : 'Email', // from v2.1.43 added 19.10.2018			'license'         : 'License', // from v2.1.43 added 19.10.2018			/********************************** mimetypes **********************************/			'kindUnknown'     : 'Unknown',			'kindRoot'        : 'Volume Root', // from v2.1.16 added 16.10.2016			'kindFolder'      : 'Folder',			'kindSelects'     : 'Selections', // from v2.1.29 added 29.8.2017			'kindAlias'       : 'Alias',			'kindAliasBroken' : 'Broken alias',			// applications			'kindApp'         : 'Application',			'kindPostscript'  : 'Postscript document',			'kindMsOffice'    : 'Microsoft Office document',			'kindMsWord'      : 'Microsoft Word document',			'kindMsExcel'     : 'Microsoft Excel document',			'kindMsPP'        : 'Microsoft Powerpoint presentation',			'kindOO'          : 'Open Office document',			'kindAppFlash'    : 'Flash application',			'kindPDF'         : 'Portable Document Format (PDF)',			'kindTorrent'     : 'Bittorrent file',			'kind7z'          : '7z archive',			'kindTAR'         : 'TAR archive',			'kindGZIP'        : 'GZIP archive',			'kindBZIP'        : 'BZIP archive',			'kindXZ'          : 'XZ archive',			'kindZIP'         : 'ZIP archive',			'kindRAR'         : 'RAR archive',			'kindJAR'         : 'Java JAR file',			'kindTTF'         : 'True Type font',			'kindOTF'         : 'Open Type font',			'kindRPM'         : 'RPM package',			// texts			'kindText'        : 'Text document',			'kindTextPlain'   : 'Plain text',			'kindPHP'         : 'PHP source',			'kindCSS'         : 'Cascading style sheet',			'kindHTML'        : 'HTML document',			'kindJS'          : 'Javascript source',			'kindRTF'         : 'Rich Text Format',			'kindC'           : 'C source',			'kindCHeader'     : 'C header source',			'kindCPP'         : 'C++ source',			'kindCPPHeader'   : 'C++ header source',			'kindShell'       : 'Unix shell script',			'kindPython'      : 'Python source',			'kindJava'        : 'Java source',			'kindRuby'        : 'Ruby source',			'kindPerl'        : 'Perl script',			'kindSQL'         : 'SQL source',			'kindXML'         : 'XML document',			'kindAWK'         : 'AWK source',			'kindCSV'         : 'Comma separated values',			'kindDOCBOOK'     : 'Docbook XML document',			'kindMarkdown'    : 'Markdown text', // added 20.7.2015			// images			'kindImage'       : 'Image',			'kindBMP'         : 'BMP image',			'kindJPEG'        : 'JPEG image',			'kindGIF'         : 'GIF Image',			'kindPNG'         : 'PNG Image',			'kindTIFF'        : 'TIFF image',			'kindTGA'         : 'TGA image',			'kindPSD'         : 'Adobe Photoshop image',			'kindXBITMAP'     : 'X bitmap image',			'kindPXM'         : 'Pixelmator image',			// media			'kindAudio'       : 'Audio media',			'kindAudioMPEG'   : 'MPEG audio',			'kindAudioMPEG4'  : 'MPEG-4 audio',			'kindAudioMIDI'   : 'MIDI audio',			'kindAudioOGG'    : 'Ogg Vorbis audio',			'kindAudioWAV'    : 'WAV audio',			'AudioPlaylist'   : 'MP3 playlist',			'kindVideo'       : 'Video media',			'kindVideoDV'     : 'DV movie',			'kindVideoMPEG'   : 'MPEG movie',			'kindVideoMPEG4'  : 'MPEG-4 movie',			'kindVideoAVI'    : 'AVI movie',			'kindVideoMOV'    : 'Quick Time movie',			'kindVideoWM'     : 'Windows Media movie',			'kindVideoFlash'  : 'Flash movie',			'kindVideoMKV'    : 'Matroska movie',			'kindVideoOGG'    : 'Ogg movie'		}	};}/* * File: /js/ui/button.js *//** * @class  elFinder toolbar button widget. * If command has variants - create menu * * @author Dmitry (dio) Levashov **/$.fn.elfinderbutton = function(cmd) {		return this.each(function() {				var c        = 'class',			fm       = cmd.fm,			disabled = fm.res(c, 'disabled'),			active   = fm.res(c, 'active'),			hover    = fm.res(c, 'hover'),			item     = 'elfinder-button-menu-item',			selected = 'elfinder-button-menu-item-selected',			menu,			text     = $('<span class="elfinder-button-text">'+cmd.title+'</span>'),			prvCname = 'elfinder-button-icon-' + (cmd.className? cmd.className : cmd.name),			button   = $(this).addClass('ui-state-default elfinder-button')				.attr('title', cmd.title)				.append('<span class="elfinder-button-icon ' + prvCname + '"/>', 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 = fm.getUI().offset(),					buttonOffset = fmNode.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 = $('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')				.hide()				.appendTo(fm.getUI())				.on('mouseenter mouseleave', '.'+item, function() { $(this).toggleClass(hover); })				.on('click', '.'+item, function(e) {					var opts = $(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('');				$.each(cmd.variants, function(i, variant) {					menu.append($('<div class="'+item+'">'+variant[1]+'</div>').data('value', variant[0]).addClass(variant[0] == cmd.value ? selected : ''));				});			});		}						cmd.change(function() {			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 = 'elfinder-button-icon-' + (cmd.className? cmd.className : cmd.name);					if (prvCname !== cName) {						button.children('.elfinder-button-icon').removeClass(prvCname).addClass(cName);						prvCname = cName;					}					text.html(cmd.title);					button.attr('title', cmd.title);				}			});		})		.change();	});};/* * File: /js/ui/contextmenu.js *//** * @class  elFinder contextmenu * * @author Dmitry (dio) Levashov **/$.fn.elfindercontextmenu = function(fm) {		return this.each(function() {		var self   = $(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 = $(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) {					$(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) {					$(this).parent().toggleClass(cHover, e.type === 'mouseleave');				})				.on('mouseenter mouseleave', '.'+cmItem+',.'+smItem, function(e) {					var setIndex = function(target, sub) {						$.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 = $(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>{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 $(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 = $(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 = $.ui.keyCode.ESCAPE,					ENT = $.ui.keyCode.ENTER,					LEFT = $.ui.keyCode.LEFT,					RIGHT = $.ui.keyCode.RIGHT,					UP = $.ui.keyCode.UP,					DOWN = $.ui.keyCode.DOWN,					subent = fm.direction === 'ltr'? RIGHT : LEFT,					sublev = subent === RIGHT? LEFT : RIGHT;								if ($.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();						}					} 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) {					$('div.elfinder div.overflow-scrolling-touch').css('-webkit-overflow-scrolling', 'auto');				}								selected = null;				subnodes = null;				subselected = null;				$(document).on('keydown.' + fm.namespace, keyEvts);				evts = $._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);				$(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) {						$('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 = $();				$.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] ? $.inArray(name, disabled) === -1 && (!useMap || !disabled[cmdName]) : false));						$.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 = $('<div class="ui-front ui-corner-all elfinder-contextmenu-sub"/>')								.hide()								.css('max-height', fm.getUI().height() - 30)								.appendTo(node.append('<span class="elfinder-contextmenu-arrow"/>'));														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 = $(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 (!$(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));											}										}									}								});														$.each(cmd.variants, function(i, variant) {								var item = variant === '|' ? '<div class="elfinder-contextmenu-separator"/>' :									$('<div class="'+cmItem+' '+smItem+'"><span>'+variant[1]+'</span></div>').data('exec', variant[0]),									iconClass, icon;								if (typeof variant[2] !== 'undefined') {									icon = $('<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) {								$('<span class="elfinder-button-icon elfinder-button-icon-'+(cmd.extra.icon || '')+' '+exIcon+'"/>')									.append(cmd.extra.node).appendTo(node);								$(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"/>');						}						menu.append(node);						sep = true;						insSep = false;					}										if (cmd && typeof cmd.__disabled !== 'undefined') {						cmd._disabled = cmd.__disabled;						delete cmd.__disabled;						$.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';				$.each(raw, function(i, data) {					var node;										if (data === '|') {						menu.append('<div class="elfinder-contextmenu-separator"/>');					} 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(), $(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();				$(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.cwdHash2Id(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				});			}		});			});	};/* * File: /js/ui/cwd.js *//** * elFinder current working directory ui. * * @author Dmitry (dio) Levashov **/$.fn.elfindercwd = function(fm, options) {		this.not('.elfinder-cwd').each(function() {		// fm.time('cwdLoad');				var 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}/>{marker}<span class="elfinder-cwd-filename">{name}</span></div>'+selectCheckbox+'</td>'+customColsBuild()+'</tr>';			},						selectCheckbox = ($.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,			/**			 * 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}/>{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, '​$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, '
') : '';					}					if (list) {						info += (info? '
' : '') + fm.escape(f.i18 || f.name);					}					return info? info + '
' + 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 ($('#elfinderAddBadgeStyle'+fm.namespace).length) {							$('#elfinderAddBadgeStyle'+fm.namespace).remove();						}						addBadgeStyleSheet = $('<style id="addBadgeStyle'+fm.namespace+'"/>').insertBefore($('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 = $(),						/**			 * Flag. Required for msie to avoid unselect files on dragstart			 *			 * @type Boolean			 **/			selectLock = false,						/**			 * Move selection to prev/next file			 *			 * @param String  move direction			 * @param Boolean append to current selection			 * @return void			 * @rise select						 */			select = function(keyCode, append) {				var code     = $.ui.keyCode,					prev     = keyCode == code.LEFT || keyCode == code.UP,					sel      = cwd.find('[id].'+clSelected),					selector = prev ? 'first:' : 'last',					s, n, sib, top, left;				function sibling(n, direction) {					return n[direction+'All']('[id]:not(.'+clDisabled+'):not(.elfinder-cwd-parent):first');				}								if (sel.length) {					s = sel.filter(prev ? ':first' : ':last');					sib = sibling(s, prev ? 'prev' : 'next');										if (!sib.length) {						// there is no sibling on required side - do not move selection						n = s;					} else if (list || keyCode == code.LEFT || keyCode == code.RIGHT) {						// find real prevoius file						n = sib;					} else {						// find up/down side file in icons view						top = s.position().top;						left = s.position().left;						n = s;						if (prev) {							do {								n = n.prev('[id]');							} while (n.length && !(n.position().top < top && n.position().left <= left));							if (n.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.cwdHash2Id(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 = $.map(incHashes || cwdHashes, function(hash) { return fm.file(hash) || null; });						files = files.slice(0, fm.maxTargets);						selectedFiles = {};						$.each(files, function(i, v) {							selectedFiles[v.hash] = true;							$('#'+fm.cwdHash2Id(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 {					$.each((incHashes || cwdHashes), function(i, h) {						var itemNode = $('#'+fm.cwdHash2Id(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) { $(ui.selected).trigger(evtSelect); },				unselected : function(e, ui) { $(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) {				var firstNode = (list? cwd.find('tbody:first') : cwd).children('[id]:first');				if (!firstNode.length) {					return;				}				var selectable = cwd.data('selectable'),					rec = (function() {						var wos = wrapper.offset(),							w = $(window),							x = (firstNode.width() / 2) * (!list && options.oldSchool? 3 : 1),							l = wos.left - w.scrollLeft() + (fm.direction === 'ltr'? x : wrapper.width() - x),							t = wos.top - w.scrollTop() + 10 + (list? (bufferExt.itemH * (options.oldSchool? 2 : 1)) || (fm.UA.Touch? 36 : 24) : 0);						return {left: Math.max(0, Math.round(l)), top: Math.max(0, Math.round(t))};					})(),					tgt = init? firstNode : $(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 = $(document.elementFromPoint(rec.left , rec.top));							widget.show();						} else {							widget = null;						}					}					setTarget();					if (!tgt.length) {						// try search 5px down						widget && widget.hide();						tgt = $(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 = $(itemhtml($.extend(true, {}, pdir, {name : '..', i18 : '..', mime : 'directory'})))								.addClass('elfinder-cwd-parent')								.on('dblclick', function() {									var hash = fm.cwdId2Hash(this.id);									fm.trigger('select', {selected : [hash]}).exec('open', hash);								});							(list ? oldSchoolItem.children('td:first') : oldSchoolItem).children('.elfinder-cwd-select').remove();							(list ? cwd.find('tbody') : cwd).prepend(oldSchoolItem);						}					};				if (pdir) {					set(pdir);				} else {					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 = $.htmlPrefilter? true : false,					tempDom = docFlag? $(document.createDocumentFragment()) : $('<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 = $.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($(this));							});						}												// append to cwd						place.append(docFlag? tempDom : tempDom.children());												// trigger select						if (selected.length) {							$.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);							}							wrapperRepaint(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 = $();						}					}					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;				}				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) {				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 = $('<div class="elfinder-table-header-sticky"/>').addClass(cwd.attr('class')).append($('<table/>').append(thead));							cwd.after(tableHeader);							wrapper.on('resize.fixheader', function(e) {								e.stopPropagation();								fixTableHeader({fitWidth: true});							});						} else {							base = $('<div/>').addClass(cwd.attr('class')).append($('<table/>').append(thead));							tableHeader = $('<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 = $('#'+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');								}							}						}));					}				}			},						// 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');						$.each($.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    = $(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);					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) {						$.each(helper.data('files'), function(i, h) {							if (h === hash || (inParent && !ctr && !helper.hasClass('elfinder-drag-helper-plus'))) {								dst.removeClass(clDropActive);								return false; // break $.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));					$(this).removeData('dropover')					       .removeClass(clDropActive);				},				deactivate : function() {					$(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   = $(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) {						$('<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.cwdHash2Id(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 ($.isPlainObject(tmbs) && Object.keys(tmbs).length) {					Object.assign(bufferExt.attachTmbs, tmbs);					$.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]]) {						$.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) {										$.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) {									$.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 = $.htmlPrefilter? true : false,					tempDom = docFlag? $(document.createDocumentFragment()) : $('<div/>'),					file, hash, node, nodes, ndx, stmb;				if (l > showFiles) {					// re-render for performance tune					content();					selectedFiles = fm.arrayFlip($.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.cwdHash2Id(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);							}						}												if ($('#'+fm.cwdHash2Id(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);					}				}			},						/**			 * 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) {					$.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.cwdHash2Id(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 = $.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 = $();					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/><tbody/></table>');						thtr = $('<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 ($.fn.sortable) {							thtr.addClass('touch-punch touch-punch-keep-default')								.sortable({								axis: 'x',								distance: 8,								items: '> .sortable-item',								start: function(e, ui) {									$(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 = $(ui.item[0]).attr('class').split(' ')[0].replace('elfinder-cwd-view-th-', ''),										prev, done;									customCols = $.map($(this).children(), function(n) {										var name = $(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 = $(this);											$this.children(prev).after($this.children(target));										});									});								},								stop: function(e, ui) {									setTimeout(function() {										$(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() {										$(this).width($(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 = $(this).attr('class').split(' ')[0].replace('elfinder-col-', '');									colWidth[name] = $(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 = $.map(incHashes || cwdHashes, function(hash) { return fm.file(hash) || null; });										buffer = fm.sortFiles(buffer);										if (incHashes) {						incHashes = $.map(buffer, function(f) { return f.hash; });					} else {						cwdHashes = $.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 = $(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 ? $(this) : $(this).parents('[id]:first'),						tgt  = $(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.add(p).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) {							$(this).trigger(evtUnselect);							$('#'+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 ? $(this) : $(this).parents('[id]:first'),						tgt = $(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 = $(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 ? $(this) : $(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 = $(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 = e.shiftKey || e.altKey,								disable = false;							if (metaKey && !fm.UA.IE && 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 = $(e.target).closest('span,tr').is('tr');									} else {										disable = $(e.target).hasClass('elfinder-cwd-file');									}								}								if (disable) {									$this.draggable('option', 'disabled', true);								} else {									$this.draggable('option', 'disabled', false)										  .removeAttr('draggable')									      .draggable('option', 'cursorAt', {left: 50 - parseInt($(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 ? $(this) : $(this).parents('[id]:first'),									elm   = $('<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"/>';										if (tmb) {											i = $(i).addClass(tmb.className).css('background-image', "url('"+tmb.url+"')").get(0).outerHTML;										}										return i;									}, l, geturl = [];								p.trigger(evtSelect);								trigger();								$.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);											$('<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) {									$.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 = $('<div class="elfinder-drag-helper html5-native"></div>').append(icon(fm.file(files[0]))).appendTo($(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 = $(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 = $(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  = $(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  = $(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($(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($(this).attr('id')), type : e.type});					$(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; }					$(this).closest(fileSelector).children('.elfinder-cwd-file-wrapper,.elfinder-cwd-filename').toggleClass(clActive, (e.type == 'mouseenter'));				})				.on('contextmenu.'+fm.namespace, function(e) {					var file = $(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 = $(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.cwdHash2Id(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 = $('<div class="elfinder-cwd-wrapper"/>')				// 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 || $(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 = $('<div> </div>')				.css({position: 'absolute', width: '1px', height: '1px'})				.hide(),						selectAllCheckbox = selectCheckbox? $('<div class="elfinder-cwd-selectall"><input type="checkbox"/></div>')				.attr('title', fm.i18n('selectall'))				.on('touchstart mousedown click', function(e) {					e.stopPropagation();					e.preventDefault();					if ($(this).data('pending') || e.type === 'click') {						return false;					}					selectAllCheckbox.data('pending', true);					if (cwd.hasClass('elfinder-cwd-allselected')) {						selectAllCheckbox.find('input').prop('checked', false);						requestAnimationFrame(function() {							unselectAll();						});					} else {						selectAll();					}				}) : $(),						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 += $(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 = $(this).parent().on('resize', resize),						// workzone node 			wz = parent.children('.elfinder-workzone').append(wrapper.append(this).append(bottomMarker)),						// message board			mBoard = $('<div class="elfinder-cwd-message-board"/>').insertAfter(cwd),			// Volume expires			vExpires = $('<div class="elfinder-cwd-expires" />'),			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($('<div class="elfinder-cwd-trash" />').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 = $.grep(customCols, function(n) {					return (options.listView.columns.indexOf(n) !== -1)? true : false;				});				if (options.listView.columns.length > customCols.length) {					$.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 = $.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			$('body').on('touchstart touchmove touchend', function(e){});		}				selectCheckbox && cwd.addClass('elfinder-has-checkbox');				$(window).on('scroll.'+fm.namespace, function() {			winScrTm && cancelAnimationFrame(winScrTm);			winScrTm = requestAnimationFrame(function() {				wrapper.trigger(scrollEvent);			});		});				$(document).on('keydown.'+fm.namespace, function(e) {			if (e.keyCode == $.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') || 0) {					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 = $('<div style="position:absolute"/>');					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 = $.map(fm.files(phash), function(f) { return f.hash; });					fm.trigger('cwdhasheschange', cwdHashes);				}				if (type === 'open') {					var inTrash = function() {							var isIn = false;							$.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 = $.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					$.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 = $.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) {				selectedFiles = {};				fm.lazy(function() {					// incremental search					var regex, q, fst = '';					q = query = e.data.query || '';					if (q) {						if (q.substr(0,1) === '/') {							q = q.substr(1);							fst = '^';						}						regex = new RegExp(fst + q.replace(/([\\*\;\.\?\[\]\{\}\(\)\^\$\-\|])/g, '\\$1'), 'i');						incHashes = $.grep(cwdHashes, function(hash) {							var file = fm.file(hash);							return (file && (file.name.match(regex) || (file.i18 && file.i18.match(regex))))? true : false;						});						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.storage('view') == '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) {					$.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;								$.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 = $.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 = $.grep(e.data.added || [], function(f) { return inTarget(f)? true : false ;});				add(files);				if (fm.searchStatus.state === 2) {					$.each(files, function(i, f) {						if ($.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) {					$.each(e.data.changed || [], function(i, file) {						if ($('#'+fm.cwdHash2Id(file.hash)).length) {							remove([file.hash]);							add([file], 'change');							$.inArray(file.hash, sel) !== -1 && selectFile(file.hash);							added = true;						}					});				} else {					$.each($.grep(e.data.changed || [], function(f) { return f.phash == phash ? true : false; }), function(i, file) {						if ($('#'+fm.cwdHash2Id(file.hash)).length) {							remove([file.hash]);							add([file], 'change');							$.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).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 = $(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 || $(),					parents, ctr, add;				if (l > 0) {					parents = fm.parents(files[0]);				}				if (event === evtSelect || event === evtUnselect) {					add  = (event === evtSelect),					$.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.cwdHash2Id(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 });				$.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;};/* * File: /js/ui/dialog.js *//** * @class  elFinder dialog * * @author Dmitry (dio) Levashov **/$.fn.elfinderdialog = function(opts, fm) {		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 : $(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 (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({}, $.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       = $(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   = $('<div class="ui-dialog-titlebar ui-widget-header ui-corner-top ui-helper-clearfix"><span class="elfinder-dialog-title">'+opts.title+'</span></div>'),			buttonset  = $('<div class="ui-dialog-buttonset"/>'),			buttonpane = $('<div class=" ui-helper-clearfix ui-dialog-buttonpane ui-widget-content"/>')				.append(buttonset),			btnWidth   = 0,			btnCnt     = 0,			tabstops   = $(),			evCover    = $('<div style="width:100%;height:100%;position:absolute;top:0px;left:0px;"/>').hide(),			numberToTel = function() {				if (opts.optimizeNumber) {					dialog.find('input[type=number]').each(function() {						$(this).attr('inputmode', 'numeric');						$(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) {					$.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();				$.each(elms, function(i, elm) {					if (elm === cur && elms[i-1]) {						node = elms.eq(i-1);						return false;					}				});				return node;			},			makeHeaderBtn = function() {				$.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($('<span class="ui-widget-header ui-dialog-titlebar-close ui-corner-all elfinder-titlebar-button"><span class="ui-icon ui-icon-closethick"/></span>')						.on('mousedown', 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});							}						});						titlebar.prepend($('<span class="ui-widget-header ui-corner-all elfinder-titlebar-button elfinder-titlebar-full"><span class="ui-icon ui-icon-plusthick"/></span>')							.on('mousedown', function(e) {								var elm = $(this);								e.preventDefault();								e.stopPropagation();								if (!dialog.hasClass('elfinder-maximized') && typeof elm.data('style') === 'undefined') {									self.height(self.height());									elm.data('style', self.attr('style') || '');								}								fm.toggleMaximize(dialog);								typeof(opts.maximize) === 'function' && opts.maximize.call(self[0]);							})						);					}									},				minimize: function() {					var btn, mnode, doffset;					if (opts.allowMinimize) {						btn = $('<span class="ui-widget-header ui-corner-all elfinder-titlebar-button elfinder-titlebar-minimize"><span class="ui-icon ui-icon-minusthick"/></span>')							.on('mousedown', function(e) {								var $this = $(this),									tray = fm.getUI('bottomtray'),									dumStyle = { width: 70, height: 24 },									dum = $('<div/>').css(dumStyle).addClass(dialog.get(0).className + ' elfinder-dialog-minimized'),									pos = {};																e.preventDefault();								e.stopPropagation();								if (!dialog.data('minimized')) {									// minimize									doffset = dialog.data('minimized', true).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();										mnode.remove();										dialog.show();										self.elfinderdialog('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) {							$(this).children('.elfinder-titlebar-minimize').trigger('mousedown');						}).prepend(btn);						dialog.on('togleminimize', function() {							btn.trigger('mousedown');						});					}				}			},			dialog = $('<div class="ui-front ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable std42-dialog touch-punch '+cldialog+' '+opts.cssClass+'"/>')				.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 = $(':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     = $(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' && $.proxy(opts.open, self[0])();										if (opts.closeOnEscape) {						$(document).on('keydown.'+id, function(e) {							if (e.keyCode == $.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? $.Deferred().reject() : $.Deferred().resolve();						}					} else {						dfd = $.Deferred().resolve();					}										dfd.done(function() {						syncSize.enabled && elfNode.off('resize.'+fm.namespace, syncFunc);												if (opts.closeOnEscape) {							$(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') {							$.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');						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 = $(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;					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 += $(this).outerHeight(true);					});					if (!init && syncSize.enabled && !e.originalEvent && !dialog.hasClass('elfinder-maximized')) {						h = Math.min(syncSize.defaultSize.height, Math.max(parseInt(dialog.css('max-height')), parseInt(dialog.css('min-height'))) - oh - dialog.data('margin-y'));					} else {						h = dialog.height() - oh - dialog.data('margin-y');					}					self.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') {						$.proxy(opts.resize, self[0])(e, data);					}				})				.on('tabstopsInit', tabstopsInit)				.on('focus', '.'+cltabstop, function() {					$(this).addClass(clhover).parent('label').addClass(clhover);					this.id && $(this).parent().find('label[for='+this.id+']').addClass(clhover);				})				.on('click', 'select.'+cltabstop, function() {					var node = $(this);					node.data('keepFocus')? node.removeData('keepFocus') : node.data('keepFocus', true);				})				.on('blur', '.'+cltabstop, function() {					$(this).removeClass(clhover).removeData('keepFocus').parent('label').removeClass(clhover);					this.id && $(this).parent().find('label[for='+this.id+']').removeClass(clhover);				})				.on('mouseenter mouseleave', '.'+cltabstop+',label', function(e) {					var $this = $(this), labelfor;					if (this.nodeName === 'LABEL') {						if (!$this.children('.'+cltabstop).length && (!(labelfor = $this.attr('for')) || !$('#'+labelfor).hasClass(cltabstop))) {							return;						}					}					if (opts.btnHoverFocus && dialog.data('focusOnMouseOver')) {						if (e.type === 'mouseenter' && ! $(':focus').data('keepFocus')) {							$this.trigger('focus');						}					} else {						$this.toggleClass(clhover, e.type == 'mouseenter');					}				})				.on('keydown', '.'+cltabstop, function(e) {					var $this = $(this),						esc, move, moveTo;					if ($this.is(':focus')) {						esc = e.keyCode === $.ui.keyCode.ESCAPE;						if (e.keyCode === $.ui.keyCode.ENTER) {							e.preventDefault();							$this.trigger('click');						}  else if (((e.keyCode === $.ui.keyCode.TAB) && e.shiftKey) || e.keyCode === $.ui.keyCode.LEFT || e.keyCode == $.ui.keyCode.UP) {							move = 'prev';						}  else if (e.keyCode === $.ui.keyCode.TAB || e.keyCode == $.ui.keyCode.RIGHT || e.keyCode == $.ui.keyCode.DOWN) {							move = 'next';						}						if (move								&&							(								($this.is('textarea') && !(e.ctrlKey || e.metaKey))									||								($this.is('select,span.ui-slider-handle') && e.keyCode !== $.ui.keyCode.TAB)									||								($this.is('input:not(:checkbox,:radio)') && (!(e.ctrlKey || e.metaKey) && e.keyCode === $.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();		$.each(opts.buttons, function(name, cb) {			var button = $('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only '					+'elfinder-btncnt-'+(btnCnt++)+' '					+cltabstop					+'"><span class="ui-button-text">'+name+'</span></button>')				.on('click', $.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 += $(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' && $.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;};$.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']};/* * File: /js/ui/fullscreenbutton.js *//** * @class  elFinder toolbar button to switch full scrren mode. * * @author Naoki Sawada **/$.fn.elfinderfullscreenbutton = function(cmd) {		return this.each(function() {		var button = $(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' : '';			});		});	});};/* * File: /js/ui/navbar.js *//** * @class elfindernav - elFinder container for diretories tree and places * * @author Dmitry (dio) Levashov **/$.fn.elfindernavbar = function(fm, opts) {		this.not('.elfinder-navbar').each(function() {		var nav    = $(this).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() {			var set = function() {				navdock =fm.getUI('navdock');				setDelta();				fm.trigger('wzresize');			};			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);			});			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 && $.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 = $('<div class="elfinder-navbar-swipe-handle"/>').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 ($(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 = $(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('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());					$(window).on('resize.' + fm.namespace, set);					set();				});			}		}	});		return this;};/* * File: /js/ui/navdock.js *//** * @class elfindernavdock - elFinder container for preview etc at below the navbar * * @author Naoki Sawada **/$.fn.elfindernavdock = function(fm, opts) {		this.not('.elfinder-navdock').each(function() {		var self = $(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);					$.each(sizeSyncs, function(id, n) {						n.height(n.height() + calc).trigger('resize.' + fm.namespace);					});					fm.trigger('wzresize');					self.css('overflow', ovf);				}			},			handle = $('<div class="ui-front ui-resizable-handle ui-resizable-n"/>').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 = $('#'+nodeId);			delete sizeSyncs[nodeId];			self.height(self.height() - $('#'+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;};/* * File: /js/ui/overlay.js */$.fn.elfinderoverlay = function(opts) {		var fm = this.parent().elfinder('instance'),		o, cnt, show, hide;		this.filter(':not(.elfinder-overlay)').each(function() {		opts = Object.assign({}, opts);		$(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;};/* * File: /js/ui/panel.js */$.fn.elfinderpanel = function(fm) {		return this.each(function() {		var panel = $(this).addClass('elfinder-panel ui-state-default ui-corner-all'),			margin = 'margin-'+(fm.direction == 'ltr' ? 'left' : 'right');				fm.one('load', function(e) {			var navbar = fm.getUI('navbar');						panel.css(margin, parseInt(navbar.outerWidth(true)));			navbar.on('resize', function(e) {				e.preventDefault();				e.stopPropagation();				panel.is(':visible') && panel.css(margin, parseInt(navbar.outerWidth(true)));			});		});	});};/* * File: /js/ui/path.js *//** * @class elFinder ui * Display current folder path in statusbar. * Click on folder name in path - open folder * * @author Dmitry (dio) Levashov **/$.fn.elfinderpath = function(fm, options) {		return this.each(function() {		var query  = '',			target = '',			mimes  = [],			place  = 'statusbar',			clHover= fm.res('class', 'hover'),			prefix = 'path' + (elFinder.prototype.uniqueid? elFinder.prototype.uniqueid : '') + '-',			wzbase = $('<div class="ui-widget-header ui-helper-clearfix elfinder-workzone-path"/>'),			path   = $(this).addClass('elfinder-path').html(' ')				.on('mousedown', 'span.elfinder-path-dir', function(e) {					var hash = $(this).attr('id').substr(prefix.length);					e.preventDefault();					if (hash != fm.cwd().hash) {						$(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 = $('<div class="elfinder-path-roots"/>').on('click', function(e) {				e.stopPropagation();				e.preventDefault();								var roots = $.map(fm.roots, function(h) { return fm.file(h); }),				raw = [];				$.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" />').appendTo(wzbase),			render = function(cwd) {				var dirs = [],					names = [];				$.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'? $('#'+prefix + fm.cwd().hash).prevAll('span.elfinder-path-dir:first') : $();				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 -= $(this).width();				});				ids = [];				dirs.each(function(i) {					var dir = $(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;						$.each(ids, function(i, k) {							var d = $(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);	});};/* * File: /js/ui/places.js *//** * @class elFinder places/favorites ui * * @author Dmitry (dio) Levashov * @author Naoki Sawada **/$.fn.elfinderplaces = function(fm, opts) {		return this.each(function() {		var dirs      = {},			c         = 'class',			navdir    = fm.res(c, 'navdir'),			collapsed = fm.res(c, 'navcollapse'),			expanded  = fm.res(c, 'navexpand'),			hover     = fm.res(c, 'hover'),			clroot    = fm.res(c, 'treeroot'),			dropover  = fm.res(c, 'adroppable'),			tpl       = fm.res('tpl', 'placedir'),			ptpl      = fm.res('tpl', 'perms'),			spinner   = $(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 node into dir hash			 *			 * @param  String  directory id			 * @return String			 **/			hash2id   = function(hash) { return 'place-'+hash; },						/**			 * Save current places state			 *			 * @return void			 **/			save      = function() {				var hashes = [], data = {};								hashes = $.map(subtree.children().find('[id]'), function(n) {					return id2hash(n.id);				});				if (hashes.length) {					$.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 = $.grep(dat.split(','), function(hash) { return hash? true : false;});					$.each(dat, function(i, d) {						var dir = d.split('#');						dirs[dir[0]] = dir[1]? dir[1] : dir[0];					});				} else if ($.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);												$.each(data.files, function(i, f) {							var hash = f.hash;							exists[hash] = f;						});						$.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 $(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 && dir.path)? fm.escape(dir.path) : '')						.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 = $('#'+hash2id(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 = $('#'+hash2id(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  = $('#'+hash2id(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() {				$.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) {						$.each(subtree.children(), function() {							var current =  $(this);							if ((dir.i18 || dir.name).localeCompare(current.children('.'+navdir).text()) < 0) {								ret = !node.insertBefore(current);								return ret;							}						});						if (ret !== null) {							return true;						}					}					!$('#'+hash2id(h)).length && subtree.append(node);				});				save();			},			// sort button			sortBtn = $('<span class="elfinder-button-icon elfinder-button-icon-sort elfinder-places-root-icon" title="'+fm.i18n('cmdsort')+'"/>')				.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 = $(this).addClass(fm.res(c, 'tree')+' elfinder-places ui-corner-all')				.hide()				.append(wrapper)				.appendTo(fm.getUI('navbar'))				.on('mouseenter mouseleave', '.'+navdir, function(e) {					$(this).toggleClass('ui-state-hover', (e.type == 'mouseenter'));				})				.on('click', '.'+navdir, function(e) {					var p = $(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 = $(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    = $.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 {								$(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));						$(this).removeData('dropover')						       .removeClass(dropover);					},					drop       : function(e, ui) {						var helper  = ui.helper,							resolve = true;												$.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 = $(this).attr('id').substr(6),					p = $(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($(this).data('tmlongtap'));					if (e.type == 'touchmove') {						$(this).removeClass(hover);					}				});		if ($.fn.sortable) {			subtree.addClass('touch-punch')			.sortable({				appendTo : fm.getUI(),				revert   : false,				helper   : function(e) {					var dir = $(e.target).parent();											dir.children().removeClass('ui-state-hover');										return $('<div class="ui-widget elfinder-place-drag elfinder-'+fm.direction+'"/>')							.append($('<div class="elfinder-navbar"/>').show().append(dir.clone()));				},				stop     : function(e, ui) {					var target = $(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		$(this).on('regist', function(e, files){			var added = false;			$.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;				$.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) {					$.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) {					$.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) {					$.each(e.data.added, function(i, file) {						if ($.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;						$.each(data.files || [], function(i, file) {							var hash = file.hash;							exists[hash] = file;							if (!fm.files().hasOwnProperty(file.hash)) {								// update cache								fm.trigger('tree', {tree: [file]});							}						});						$.each(dirs, function(h, f) {							if (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();					});				}			});					});			});};/* * File: /js/ui/searchbutton.js *//** * @class  elFinder toolbar search button widget. * * @author Dmitry (dio) Levashov **/$.fn.elfindersearchbutton = function(cmd) {		return this.each(function() {		var result = false,			fm     = cmd.fm,			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 = $(this)				.hide()				.addClass('ui-widget-content elfinder-button '+btnCls)				.on('click', function(e) {					e.stopPropagation();				}),			search = function() {				input.data('inctm') && clearTimeout(input.data('inctm'));				var val = $.trim(input.val()),					from = !$('#' + id('SearchFromAll')).prop('checked'),					mime = $('#' + id('SearchMime')).prop('checked'),					type = '';				if (from) {					if ($('#' + 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  = $('<input type="text" size="42"/>')				.on('focus', function() {					inFocus = true;					incVal = '';					button.addClass('ui-state-active');					fm.trigger('uiresize');					opts && opts.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 === $.ui.keyCode.ENTER) {						search();					} else if (e.keyCode === $.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 });								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 === $.ui.keyCode.ENTER && input.trigger('compositionend');						} else {							input.trigger('input');						}					});			}		}				$('<span class="ui-icon ui-icon-search" title="'+cmd.title+'"/>')			.appendTo(button)			.on('mousedown', function(e) {				e.stopPropagation();				e.preventDefault();				if (button.hasClass('ui-state-active')) {					search();				} else {					input.trigger('focus');				}			});				$('<span class="ui-icon ui-icon-close"/>')			.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 : $('<div class="ui-front ui-widget ui-widget-content elfinder-button-search-menu ui-corner-all"/>')					.append(						$('<div class="buttonset"/>')							.append(								$('<input id="'+id('SearchFromCwd')+'" name="serchfrom" type="radio" checked="checked"/><label for="'+id('SearchFromCwd')+'">'+fm.i18n('btnCwd')+'</label>'),								$('<input id="'+id('SearchFromVol')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromVol')+'">'+fm.i18n('btnVolume')+'</label>'),								$('<input id="'+id('SearchFromAll')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromAll')+'">'+fm.i18n('btnAll')+'</label>')							),						$('<div class="buttonset elfinder-search-type"/>')							.append(								$('<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');						$.each(cmd.options.searchTypes, function(i, v) {							typeSet.append($('<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();					$('#'+id('SearchFromAll')).next('label').attr('title', fm.i18n('searchTarget', fm.i18n('btnAll')));					if (sTypes) {						$.each(sTypes, function(i, v) {							if (v.title) {								$('#'+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();							$.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) {					$.each(fm.parents(fm.cwd().hash), function(i, hash) {						dirs.push(fm.file(hash).name);					});							$('#'+id('SearchFromCwd')).next('label').attr('title', fm.i18n('searchTarget', dirs.join(fm.option('separator'))));					$('#'+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 = $.ui.keyCode[(!sel.length || $('#'+fm.cwdHash2Id(sel[0])).next('[id]').length)? 'RIGHT' : 'HOME'];							$(document).trigger($.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();					}				}			});	});};/* * File: /js/ui/sortbutton.js *//** * @class  elFinder toolbar button menu with sort variants. * * @author Dmitry (dio) Levashov **/$.fn.elfindersortbutton = function(cmd) {		return this.each(function() {		var fm       = cmd.fm,			name     = cmd.name,			c        = 'class',			disabled = fm.res(c, 'disabled'),			hover    = fm.res(c, 'hover'),			item     = 'elfinder-button-menu-item',			selected = item+'-selected',			asc      = selected+'-asc',			desc     = selected+'-desc',			text     = $('<span class="elfinder-button-text">'+cmd.title+'</span>'),			button   = $(this).addClass('ui-state-default elfinder-button elfinder-menubutton elfiner-button-'+name)				.attr('title', cmd.title)				.append('<span class="elfinder-button-icon elfinder-button-icon-'+name+'"/>', 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 = $('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')				.hide()				.appendTo(fm.getUI())				.on('mouseenter mouseleave', '.'+item, function(e) { $(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();				$.each(fm.sortRules, function(name, value) {			menu.append($('<div class="'+item+'" rel="'+name+'"><span class="ui-icon ui-icon-arrowthick-1-n"/><span class="ui-icon ui-icon-arrowthick-1-s"/>'+fm.i18n('sort'+name)+'</div>').data('type', name));		});				menu.children().on('click', function(e) {			cmd.exec([], $(this).removeClass(hover).attr('rel'));		});				$('<div class="'+item+' '+item+'-separated elfinder-sort-ext elfinder-sort-stick"><span class="ui-icon ui-icon-check"/>'+fm.i18n('sortFoldersFirst')+'</div>')			.appendTo(menu)			.on('click', function() {				cmd.exec([], 'stick');			});		if ($.fn.elfindertree && $.inArray('tree', fm.options.ui) !== -1) {			$('<div class="'+item+' '+item+'-separated elfinder-sort-ext elfinder-sort-tree"><span class="ui-icon ui-icon-check"/>'+fm.i18n('sortAlsoTreeview')+'</div>')				.appendTo(menu)				.on('click', function() {					cmd.exec([], 'tree');				});		}				fm.bind('disable select', hide).getUI().on('click', hide);					fm.bind('open', function() {			menu.children('[rel]').each(function() {				var $this = $(this);				$this.toggle(fm.sorters[$this.attr('rel')]);			});		}).bind('sortchange', update);				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);		}	});	};/* * File: /js/ui/stat.js *//** * @class elFinder ui * Display number of files/selected files and its size in statusbar * * @author Dmitry (dio) Levashov **/$.fn.elfinderstat = function(fm) {		return this.each(function() {		var size       = $(this).addClass('elfinder-stat-size'),			sel        = $('<div class="elfinder-stat-selected"/>')				.on('click', 'a', function(e) {					var hash = $(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;				}				$.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+', <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) {					$.each(files, function(i, file) {						c++;						s += parseInt(file.size)||0;					});					sel.html(c ? titlesel+': '+c+', '+titlesize+': '+fm.formatSize(s) : ' ');				} else {					sel.html('');				}				sel.attr('title', sel.text());				fm.trigger('uistatchange');			};		fm.getUI('statusbar').prepend(size).append(sel).show();		if (fm.UA.Mobile && $.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($.map(e.data, function(h) { return fm.file(h); }));		})		.change(function(e) {			var files = e.data.changed || [],				cwdHash = fm.cwd().hash;			$.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();		})		;	});};/* * File: /js/ui/toast.js *//** * @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 **/$.fn.elfindertoast = function(opts, fm) {		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	}, $.isPlainObject(fm.options.uiOptions.toast.defaults)? fm.options.uiOptions.toast.defaults : {});	return this.each(function() {		opts = Object.assign({}, defOpts, opts || {});				var self = $(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($('<div class="elfinder-toast-msg"/>').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(				$('<button class="ui-button ui-widget ui-state-default ui-corner-all elfinder-tabstop"/>')				.append($('<span class="ui-button-text"/>').text(fm.i18n(opts.button.text)))				.on('mouseenter mouseleave', function(e) { 					$(this).toggleClass('ui-state-hover', e.type == 'mouseenter');				})				.on('click', opts.button.click || function(){})			);		}		if (opts.width) {			self.css('max-width', opts.width);		}				show();	});};/* * File: /js/ui/toolbar.js *//** * @class  elFinder toolbar * * @author Dmitry (dio) Levashov **/$.fn.elfindertoolbar = function(fm, opts) {		this.not('.elfinder-toolbar').each(function() {		var commands = fm._commands,			self     = $(this).addClass('ui-helper-clearfix ui-widget-header elfinder-toolbar'),			options  = {				// default options				displayTextLabel: false,				labelExcludeUA: ['Mobile'],				autoHideUA: ['Mobile'],				showPreferenceButton: 'none'			},			filter   = function(opts) {				return $.grep(opts, function(v) {					if ($.isPlainObject(v)) {						options = Object.assign(options, v);						return false;					}					return true;				});			},			render = function(disabled){				var name,cmdPref;								$.each(buttons, function(i, b) { b.detach(); });				self.empty();				l = panels.length;				while (l--) {					if (panels[l]) {						panel = $('<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>');						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] && $.fn[button]) {									buttons[name] = $('<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"/>');					}				}								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 = $('<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>');						name = 'preference';						button = 'elfinder'+cmd.options.ui;						buttons[name] = $('<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 || ! $.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 = {};				$.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);				}			}						$.each(userHides, function(n) {				if (!disabled[n]) {					disabled[n] = true;				}			});						if (Object.keys(fm.commandMap).length) {				$.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					$.each($('div.elfinder-button'), function(){						var origin = $(this).data('origin');						if (origin) {							$(this).after(origin).detach();						}					});				}				if (Object.keys(fm.commandMap).length) {					$.each(fm.commandMap, function(from, to){						var cmd = fm._commands[to],							button = cmd? 'elfinder'+cmd.options.ui : null,							btn;						if (button && $.fn[button]) {							btn = buttons[from];							if (btn) {								if (! buttons[to] && $.fn[button]) {									buttons[to] = $('<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 && $.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 = $('<div class="elfinder-toolbar-swipe-handle"/>').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;};/* * File: /js/ui/tree.js *//** * @class  elFinder folders tree * * @author Dmitry (dio) Levashov **/$.fn.elfindertree = function(fm, opts) {		var treeclass = fm.res('class', 'tree');		this.not('.'+treeclass).each(function() {		var c = 'class', 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 = [];				$.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) {							$.each(res.subdirs, function(hash, subdirs) {								var elm = $('#'+fm.navHash2Id(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($('#'+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 = $.extend(true, {}, fm.droppable, {				// show subfolders on dropover				over : function(e, ui) {					var dst    = $(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 || ! insideNavbar(e.clientX) || ! fm.insideWorkzone(e.pageX, e.pageY)) {						dst.removeClass(cl);						helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');						return;					}					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);					$.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 $.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    = $(this),						helper = ui.helper;					e.stopPropagation();					helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus').data('dropover', Math.max(helper.data('dropover') - 1, 0));					dst.data('expandTimer') && clearTimeout(dst.data('expandTimer'));					dst.removeData('dropover')					   .removeClass(hover+' '+dropover);				},				deactivate : function() {					$(this).removeData('dropover')					       .removeClass(hover+' '+dropover);				},				drop : function(e, ui) {					insideNavbar(e.clientX) && drop.call(this, e, ui);				}			}),						spinner = $(fm.res('tpl', 'navspinner')),						/**			 * Directory html template			 *			 * @type String			 */			tpl = fm.res('tpl', 'navdir'),						/**			 * Permissions marker html template			 *			 * @type String			 */			ptpl = fm.res('tpl', 'perms'),						/**			 * 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;				},				root        : function(dir) {					var cls = '';					if (!dir.phash || dir.isroot) {						cls += ' '+wrapperRoot;						if (!dir.disabled || dir.disabled.length < 1) {							cls += ' '+pastable+' '+uploadable;						} else {							if ($.inArray('paste', dir.disabled) === -1) {								cls += ' '+pastable;							}							if ($.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 $.map(files || [], function(f) {					return (f.mime === 'directory' && (!checkExists || $('#'+fm.navHash2Id(f.hash)).length)) ? f : null;				});			},						/**			 * Find parent subtree for required directory			 *			 * @param  String  dir hash			 * @return jQuery			 */			findSubtree = function(hash) {				return hash ? $('#'+fm.navHash2Id(hash)).next('.'+subtree) : tree;			},						/**			 * Find directory (wrapper) in required node			 * before which we can insert new directory			 *			 * @param  jQuery  parent directory			 * @param  Object  new directory			 * @return jQuery			 */			findSibling = function(subtree, dir) {				var node = subtree.children(':first'),					info;				while (node.length) {					info = fm.file(fm.navId2Hash(node.children('[id]').attr('id')));										if ((info = fm.file(fm.navId2Hash(node.children('[id]').attr('id')))) 					&& 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 = $(),					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 = {};								$.each(dirs, function(i, d) {									hashes[d.hash] = i;								});							},							change = function(mode) {								if (mode === 'prepare') {									$.each(dirs, function(i, d) {										d.node && parent.append(d.node.hide());									});								} else if (mode === 'done') {									$.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 = $.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($.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);								}								$.each(parts || dirs, function(i, d) {									html.push(itemhtml(d));									if (d.node) {										nodes[d.hash] = d.node;									}								});								if (prev > -1) {									prevBtn = $('<button class="elfinder-navbar-pager elfinder-navbar-pager-prev"/>')										.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 = $();								}								if (next) {									nextBtn = $('<button class="elfinder-navbar-pager elfinder-navbar-pager-next"/>')										.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 = $();								}								detach();								parent.empty()[parts? 'addClass' : 'removeClass']('elfinder-navbar-hasmore').append(prevBtn, html.join(''), nextBtn);								$.each(nodes, function(h, n) {									$('#'+fm.navHash2Id(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() {								$.each(parent.children('.elfinder-navbar-wrapper'), function(i, elm) {									var n = $(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,					firstVol = true; // check for netmount volume								while (i--) {					dir = dirs[i];					if (done[dir.hash] || $('#'+fm.navHash2Id(dir.hash)).length) {						continue;					}					done[dir.hash] = true;										if ((parent = findSubtree(dir.phash)).length) {						if (dir.phash && ((init = !parent.children().length) || 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);							parent[firstVol || dir.phash ? 'append' : 'prepend'](node);							firstVol = false;							if (!dir.phash || dir.isroot) {								base = $('#'+fm.navHash2Id(dir.hash)).parent();							}							! mobile && updateDroppable(null, base);						}					} else {						orphans.push(dir);					}				}				// When init, html append at once				if (Object.keys(atonce).length){					$.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 = $.Deferred(),					current, parent, top, treeH, bottom, tgtTop;				autoScrTm && clearTimeout(autoScrTm);				autoScrTm = setTimeout(function() {					current = $('#'+(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.navHash2Id(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.navHash2Id(curHash));							if (!node.length) {					while(cur && cur.phash) {						if (hasMoreDirs[cur.phash] && !$('#'+fm.navHash2Id(cur.hash)).length) {							hasMoreDirs[cur.phash].trigger('update.'+fm.namespace, { select : cur.hash });						}						cur = fm.file(cur.phash);					}					node = $('#'+fm.navHash2Id(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  = $.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 = $.map(ends, function(h) {							var d = fm.file(h),								isRoot = d? fm.isRoot(d) : false,								node = $('#'+fm.navHash2Id(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.navHash2Id(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.navHash2Id(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 = $('#'+baseId);							spinner = $(fm.res('tpl', 'navspinner')).insertBefore(baseNode.children('.'+arrow));							baseNode.removeClass(collapsed);														$.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) {							$.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 = $.Deferred(),					baseNode, spinner;								if (!$('#'+fm.navHash2Id(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 $.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 = $();					}					if (node) {						// check leaf roots						node.children('div.'+wrapperRoot).each(function() {							updateDroppable(null, $(this));						});					}				}								// make droppable on async				if (target.length) {					fm.asyncJob(function(elm) {						$(elm).droppable(droppableopts);					}, $.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+')';								$.each(dirs, function(i, dir) {					$('#'+fm.navHash2Id(dir.phash)+sel)						.filter(function() { return $.grep($(this).next('.'+subtree).children(), function(n) {							return ($(n).children().hasClass(root))? false : true;						}).length > 0; })						.addClass(cls);				});			},												/**			 * Navigation tree			 *			 * @type JQuery			 */			tree = $(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  = $(this); 										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', fm.navId2Hash(link.attr('id')))) {								link.draggable(fm.draggable);							}						}						link.toggleClass(hover, enter);					}				})				// native drag enter				.on('dragenter', selNavdir, function(e) {					if (e.originalEvent.dataTransfer) {						var dst = $(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 = $(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 = $(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 = $(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($(this).data('tmlongtap'));					if (e.type == 'touchmove') {						$(this).removeClass(hover);					}				})				// toggle subfolders in tree				.on('click', selNavdir+'.'+collapsed+' .'+arrow, function(e) {					var arrow = $(this),						link  = arrow.parent(selNavdir),						stree = link.next('.'+subtree),						dfrd  = $.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 = $(this);										// now dirname editing					if (self.find('input:text').length) {						e.stopPropagation();						return;					}										e.preventDefault();					fm.trigger('contextmenu', {						'type'    : 'navbar',						'targets' : [fm.navId2Hash($(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 = $(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  = $(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 = $(),				changed = {},				dir, phash, node, tmp, realParent, reqParent, realSibling, reqSibling, isExpanded, isLoaded, parent, subdirs;						$.each(hasMoreDirs, function(h, node) {				node.trigger('update.'+fm.namespace, { change: 'prepare' });			});						while (l--) {				dir = dirs[l];				phash = dir.phash;				if ((node = $('#'+fm.navHash2Id(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        = $(itemhtml(dir));					node.replaceWith(tmp.children(selNavdir));					! mobile && updateDroppable(null, parent);										if (dir.dirs					&& (isExpanded || isLoaded) 					&& (node = $('#'+fm.navHash2Id(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();			}						$.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;						$.each(hasMoreDirs, function(h, node) {				node.trigger('update.'+fm.namespace, { removed : dirs });				node.trigger('update.'+fm.namespace, { change: 'prepare' });			});			while (l--) {				if ((node = $('#'+fm.navHash2Id(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');						$.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 = $.grep(e.data.files||[], function(h) {  					var dir = fm.file(h);					return dir && dir.mime == 'directory' ? true : false;				});							$.each(dirs, function(i, hash) {				var dir = $('#'+fm.navHash2Id(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($.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) {							$.each(ends, function(i, end) {								var vid = fm.file(fm.root(end)).volumeid; 								if (i === 0) {									topVid = vid;								}								endsVid[vid] = end;								endsMap[end] = [];							});							$.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) {							$.each(ends, function(i, endHash) {								updateTree(dirs);								current = selectPages(fm.file(endHash));								updateArrows(dirs, loaded);							});						} else {							$.each(endsMap, function(endHash, dirs) {								updateTree(dirs);								current = selectPages(fm.file(endHash));								updateArrows(dirs, loaded);							});						}					}										sync();				}, 100);			}		});	});		return this;};/* * File: /js/ui/uploadButton.js *//** * @class  elFinder toolbar's button tor upload file * * @author Dmitry (dio) Levashov **/$.fn.elfinderuploadbutton = function(cmd) {		return this.each(function() {		var fm = cmd.fm,			button = $(this).elfinderbutton(cmd)				.off('click'), 			form = $('<form/>').appendTo(button),			input = $('<input type="file" multiple="true" title="'+cmd.fm.i18n('selectForUpload')+'"/>')				.on('change', function() {					var _input = $(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();	});};/* * File: /js/ui/viewbutton.js *//** * @class  elFinder toolbar button to switch current directory view. * * @author Dmitry (dio) Levashov **/$.fn.elfinderviewbutton = function(cmd) {		return this.each(function() {		var button = $(this).elfinderbutton(cmd),			icon   = button.children('.elfinder-button-icon'),			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);			});		});	});};/* * File: /js/ui/workzone.js *//** * @class elfinderworkzone - elFinder container for nav and current directory * @author Dmitry (dio) Levashov **/$.fn.elfinderworkzone = function(fm) {		var cl = 'elfinder-workzone';		this.not('.'+cl).each(function() {		var wz     = $(this).addClass(cl),			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 = $(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;};/* * File: /js/commands/archive.js *//** * @class  elFinder command "archive" * Archive selected files * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.archive = function() {		var self  = this,		fm    = self.fm,		mimes = [],		dfrd;			this.variants = [];		this.disableOnSearch = false;		this.nextAction = {};		/**	 * Update mimes on open/reload	 *	 * @return void	 **/	fm.bind('open reload', function() {		self.variants = [];		$.each((mimes = fm.option('archivers')['create'] || []), function(i, mime) {			self.variants.push([mime, fm.mime2kind(mime)]);		});		self.change();	});		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length,			chk = (cnt && ! fm.isRoot(sel[0]) && (fm.file(sel[0].phash) || {}).write && ! $.grep(sel, function(f){ return f.read ? false : true; }).length),			cwdId;				if (chk && fm.searchStatus.state > 1) {			cwdId = fm.cwd().volumeid;			chk = (cnt === $.grep(sel, function(f) { return f.read && f.hash.indexOf(cwdId) === 0 ? true : false; }).length);		}				return chk && !this._disabled && mimes.length && (cnt || (dfrd && dfrd.state() == 'pending')) ? 0 : -1;	};		this.exec = function(hashes, type) {		var files = this.files(hashes),			cnt   = files.length,			mime  = type || mimes[0],			cwd   = fm.file(files[0].phash) || null,			error = ['errArchive', 'errPerm', 'errCreatingTempDir', 'errFtpDownloadFile', 'errFtpUploadFile', 'errFtpMkdir', 'errArchiveExec', 'errExtractExec', 'errRm'],			i, open;		dfrd = $.Deferred().fail(function(error) {			error && fm.error(error);		});		if (! (cnt && mimes.length && $.inArray(mime, mimes) !== -1)) {			return dfrd.reject();		}				if (!cwd.write) {			return dfrd.reject(error);		}				for (i = 0; i < cnt; i++) {			if (!files[i].read) {				return dfrd.reject(error);			}		}		self.mime   = mime;		self.prefix = ((cnt > 1)? 'Archive' : files[0].name) + (fm.option('archivers')['createext']? '.' + fm.option('archivers')['createext'][mime] : '');		self.data   = {targets : self.hashes(hashes), type : mime};				if (fm.cwd().hash !== cwd.hash) {			open = fm.exec('open', cwd.hash).done(function() {				fm.one('cwdrender', function() {					fm.selectfiles({files : hashes});					dfrd = $.proxy(fm.res('mixin', 'make'), self)();				});			});		} else {			fm.selectfiles({files : hashes});			dfrd = $.proxy(fm.res('mixin', 'make'), self)();		}				return dfrd;	};};/* * File: /js/commands/back.js *//** * @class  elFinder command "back" * Open last visited folder * * @author Dmitry (dio) Levashov **/(elFinder.prototype.commands.back = function() {		this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.shortcuts      = [{		pattern     : 'ctrl+left backspace'	}];		this.getstate = function() {		return this.fm.history.canBack() ? 0 : -1;	};		this.exec = function() {		return this.fm.history.back();	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/chmod.js *//** * @class elFinder command "chmod". * Chmod files. * * @type  elFinder.command * @author Naoki Sawada */elFinder.prototype.commands.chmod = function() {		this.updateOnSelect = false;	var fm  = this.fm,		level = {			0 : 'owner',			1 : 'group',			2 : 'other'		},		msg = {			read     : fm.i18n('read'),			write    : fm.i18n('write'),			execute  : fm.i18n('execute'),			perm     : fm.i18n('perm'),			kind     : fm.i18n('kind'),			files    : fm.i18n('files')		},		isPerm = function(perm){			return (!isNaN(parseInt(perm, 8) && parseInt(perm, 8) <= 511) || perm.match(/^([r-][w-][x-]){3}$/i));		};	this.tpl = {		main       : '<div class="ui-helper-clearfix elfinder-info-title"><span class="elfinder-cwd-icon {class} ui-corner-all"/>{title}</div>'					+'{dataTable}',		itemTitle  : '<strong>{name}</strong><span id="elfinder-info-kind">{kind}</span>',		groupTitle : '<strong>{items}: {num}</strong>',		dataTable  : '<table id="{id}-table-perm"><tr><td>{0}</td><td>{1}</td><td>{2}</td></tr></table>'					+'<div class="">'+msg.perm+': <input class="elfinder-tabstop elfinder-focus" id="{id}-perm" type="text" size="4" maxlength="3" value="{value}"></div>',		fieldset   : '<fieldset id="{id}-fieldset-{level}"><legend>{f_title}{name}</legend>'					+'<input type="checkbox" value="4" class="elfinder-tabstop" id="{id}-read-{level}-perm"{checked-r}> <label for="{id}-read-{level}-perm">'+msg.read+'</label><br>'					+'<input type="checkbox" value="6" class="elfinder-tabstop" id="{id}-write-{level}-perm"{checked-w}> <label for="{id}-write-{level}-perm">'+msg.write+'</label><br>'					+'<input type="checkbox" value="5" class="elfinder-tabstop" id="{id}-execute-{level}-perm"{checked-x}> <label for="{id}-execute-{level}-perm">'+msg.execute+'</label><br>'	};	this.shortcuts = [{		//pattern     : 'ctrl+p'	}];	this.getstate = function(sel) {		var fm = this.fm;		sel = sel || fm.selected();		if (sel.length == 0) {			sel = [ fm.cwd().hash ];		}		return this.checkstate(this.files(sel)) ? 0 : -1;	};		this.checkstate = function(sel) {		var cnt = sel.length;		if (!cnt) return false;		var chk = $.grep(sel, function(f) {			return (f.isowner && f.perm && isPerm(f.perm) && (cnt == 1 || f.mime != 'directory')) ? true : false;		}).length;		return (cnt == chk)? true : false;	};	this.exec = function(select) {		var hashes  = this.hashes(select),			files   = this.files(hashes);		if (! files.length) {			hashes = [ this.fm.cwd().hash ];			files   = this.files(hashes);		}		var fm  = this.fm,		dfrd    = $.Deferred().always(function() {			fm.enable();		}),		tpl     = this.tpl,		cnt     = files.length,		file    = files[0],		id = fm.namespace + '-perm-' + file.hash,		view    = tpl.main,		checked = ' checked="checked"',		buttons = function() {			var buttons = {};			buttons[fm.i18n('btnApply')] = save;			buttons[fm.i18n('btnCancel')] = function() { dialog.elfinderdialog('close'); };			return buttons;		},		save = function() {			var perm = $.trim($('#'+id+'-perm').val()),				reqData;						if (!isPerm(perm)) return false;						dialog.elfinderdialog('close');						reqData = {				cmd     : 'chmod',				targets : hashes,				mode    : perm			};			fm.request({				data : reqData,				notify : {type : 'chmod', cnt : cnt}			})			.fail(function(error) {				dfrd.reject(error);			})			.done(function(data) {				if (data.changed && data.changed.length) {					data.undo = {						cmd : 'chmod',						callback : function() {							var reqs = [];							$.each(prevVals, function(perm, hashes) {								reqs.push(fm.request({									data : {cmd : 'chmod', targets : hashes, mode : perm},									notify : {type : 'undo', cnt : hashes.length}								}));							});							return $.when.apply(null, reqs);						}					};					data.redo = {						cmd : 'chmod',						callback : function() {							return fm.request({								data : reqData,								notify : {type : 'redo', cnt : hashes.length}							});						}					};				}				dfrd.resolve(data);			});		},		setperm = function() {			var perm = '';			var _perm;			for (var i = 0; i < 3; i++){				_perm = 0;				if ($("#"+id+"-read-"+level[i]+'-perm').is(':checked')) {					_perm = (_perm | 4);				}				if ($("#"+id+"-write-"+level[i]+'-perm').is(':checked')) {					_perm = (_perm | 2);				}				if ($("#"+id+"-execute-"+level[i]+'-perm').is(':checked')) {					_perm = (_perm | 1);				}				perm += _perm.toString(8);			}			$('#'+id+'-perm').val(perm);		},		setcheck = function(perm) {			var _perm;			for (var i = 0; i < 3; i++){				_perm = parseInt(perm.slice(i, i+1), 8);				$("#"+id+"-read-"+level[i]+'-perm').prop("checked", false);				$("#"+id+"-write-"+level[i]+'-perm').prop("checked", false);				$("#"+id+"-execute-"+level[i]+'-perm').prop("checked", false);				if ((_perm & 4) == 4) {					$("#"+id+"-read-"+level[i]+'-perm').prop("checked", true);				}				if ((_perm & 2) == 2) {					$("#"+id+"-write-"+level[i]+'-perm').prop("checked", true);				}				if ((_perm & 1) == 1) {					$("#"+id+"-execute-"+level[i]+'-perm').prop("checked", true);				}			}			setperm();		},		makeperm = function(files) {			var perm = '777', ret = '', chk, _chk, _perm;			var len = files.length;			for (var i2 = 0; i2 < len; i2++) {				chk = getPerm(files[i2].perm);				if (! prevVals[chk]) {					prevVals[chk] = [];				}				prevVals[chk].push(files[i2].hash);				ret = '';				for (var i = 0; i < 3; i++){					_chk = parseInt(chk.slice(i, i+1), 8);					_perm = parseInt(perm.slice(i, i+1), 8);					if ((_chk & 4) != 4 && (_perm & 4) == 4) {						_perm -= 4;					}					if ((_chk & 2) != 2 && (_perm & 2) == 2) {						_perm -= 2;					}					if ((_chk & 1) != 1 && (_perm & 1) == 1) {						_perm -= 1;					}					ret += _perm.toString(8);				}				perm = ret;			}			return perm;		},		makeName = function(name) {			return name? ':'+name : '';		},		makeDataTable = function(perm, f) {			var _perm, fieldset;			var value = '';			var dataTable = tpl.dataTable;			for (var i = 0; i < 3; i++){				_perm = parseInt(perm.slice(i, i+1), 8);				value += _perm.toString(8);				fieldset = tpl.fieldset.replace('{f_title}', fm.i18n(level[i])).replace('{name}', makeName(f[level[i]])).replace(/\{level\}/g, level[i]);				dataTable = dataTable.replace('{'+i+'}', fieldset)				                     .replace('{checked-r}', ((_perm & 4) == 4)? checked : '')				                     .replace('{checked-w}', ((_perm & 2) == 2)? checked : '')				                     .replace('{checked-x}', ((_perm & 1) == 1)? checked : '');			}			dataTable = dataTable.replace('{value}', value).replace('{valueCaption}', msg['perm']);			return dataTable;		},		getPerm = function(perm){			if (isNaN(parseInt(perm, 8))) {				var mode_array = perm.split('');				var a = [];				for (var i = 0, l = mode_array.length; i < l; i++) {					if (i === 0 || i === 3 || i === 6) {						if (mode_array[i].match(/[r]/i)) {							a.push(1);						} else if (mode_array[i].match(/[-]/)) {							a.push(0);						}					} else if ( i === 1 || i === 4 || i === 7) {						 if (mode_array[i].match(/[w]/i)) {							a.push(1);						} else if (mode_array[i].match(/[-]/)) {							a.push(0);						}					} else {						if (mode_array[i].match(/[x]/i)) {							a.push(1);						} else if (mode_array[i].match(/[-]/)) {							a.push(0);						}					}				}							a.splice(3, 0, ",");				a.splice(7, 0, ",");				var b = a.join("");				var b_array = b.split(",");				var c = [];							for (var j = 0, m = b_array.length; j < m; j++) {					var p = parseInt(b_array[j], 2).toString(8);					c.push(p);				}				perm = c.join('');			} else {				perm = parseInt(perm, 8).toString(8);			}			return perm;		},		opts    = {			title : this.title,			width : 'auto',			buttons : buttons(),			close : function() { $(this).elfinderdialog('destroy'); }		},		dialog = fm.getUI().find('#'+id),		prevVals = {},		tmb = '', title, dataTable;		if (dialog.length) {			dialog.elfinderdialog('toTop');			return $.Deferred().resolve();		}		view  = view.replace('{class}', cnt > 1 ? 'elfinder-cwd-icon-group' : fm.mime2class(file.mime));		if (cnt > 1) {			title = tpl.groupTitle.replace('{items}', fm.i18n('items')).replace('{num}', cnt);		} else {			title = tpl.itemTitle.replace('{name}', file.name).replace('{kind}', fm.mime2kind(file));			tmb = fm.tmb(file);		}		dataTable = makeDataTable(makeperm(files), files.length == 1? files[0] : {});		view = view.replace('{title}', title).replace('{dataTable}', dataTable).replace(/{id}/g, id);		dialog = this.fmDialog(view, opts);		dialog.attr('id', id);		// load thumbnail		if (tmb) {			$('<img/>')				.on('load', function() { dialog.find('.elfinder-cwd-icon').addClass(tmb.className).css('background-image', "url('"+tmb.url+"')"); })				.attr('src', tmb.url);		}		$('#' + id + '-table-perm :checkbox').on('click', function(){setperm('perm');});		$('#' + id + '-perm').on('keydown', function(e) {			var c = e.keyCode;			if (c == $.ui.keyCode.ENTER) {				e.stopPropagation();				save();				return;			}		}).on('focus', function(e){			$(this).trigger('select');		}).on('keyup', function(e) {			if ($(this).val().length == 3) {				$(this).trigger('select');				setcheck($(this).val());			}		});				return dfrd;	};};/* * File: /js/commands/colwidth.js *//** * @class  elFinder command "colwidth" * CWD list table columns width to auto * * @author Naoki Sawada **/elFinder.prototype.commands.colwidth = function() {		this.alwaysEnabled = true;	this.updateOnSelect = false;		this.getstate = function() {		return this.fm.getUI('cwd').find('table').css('table-layout') === 'fixed' ? 0 : -1;	};		this.exec = function() {		this.fm.getUI('cwd').trigger('colwidth');		return $.Deferred().resolve();	};	};/* * File: /js/commands/copy.js *//** * @class elFinder command "copy". * Put files in filemanager clipboard. * * @type  elFinder.command * @author  Dmitry (dio) Levashov */elFinder.prototype.commands.copy = function() {		this.shortcuts = [{		pattern     : 'ctrl+c ctrl+insert'	}];		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;		return cnt && $.grep(sel, function(f) { return f.read ? true : false; }).length == cnt ? 0 : -1;	};		this.exec = function(hashes) {		var fm   = this.fm,			dfrd = $.Deferred()				.fail(function(error) {					fm.error(error);				});		$.each(this.files(hashes), function(i, file) {			if (! file.read) {				return !dfrd.reject(['errCopy', file.name, 'errPerm']);			}		});				return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes)));	};};/* * File: /js/commands/cut.js *//** * @class elFinder command "copy". * Put files in filemanager clipboard. * * @type  elFinder.command * @author  Dmitry (dio) Levashov */elFinder.prototype.commands.cut = function() {		var fm = this.fm;		this.shortcuts = [{		pattern     : 'ctrl+x shift+insert'	}];		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;				return cnt && $.grep(sel, function(f) { return f.read && ! f.locked && ! fm.isRoot(f) ? true : false; }).length == cnt ? 0 : -1;	};		this.exec = function(hashes) {		var dfrd = $.Deferred()				.fail(function(error) {					fm.error(error);				});		$.each(this.files(hashes), function(i, file) {			if (!(file.read && ! file.locked && ! fm.isRoot(file)) ) {				return !dfrd.reject(['errCopy', file.name, 'errPerm']);			}			if (file.locked) {				return !dfrd.reject(['errLocked', file.name]);			}		});				return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes), true));	};};/* * File: /js/commands/download.js *//** * @class elFinder command "download".  * Download selected files. * Only for new api * * @author Dmitry (dio) Levashov, dio@std42.ru **/elFinder.prototype.commands.zipdl = function() {};elFinder.prototype.commands.download = function() {		var self   = this,		fm     = this.fm,		czipdl = null,		zipOn  = false,		mixed  = false,		dlntf  = false,		cpath  = window.location.pathname || '/',		filter = function(hashes, inExec) {			var volumeid, mixedCmd;						if (czipdl !== null) {				if (fm.searchStatus.state > 1) {					mixed = fm.searchStatus.mixed;				} else if (fm.leafRoots[fm.cwd().hash]) {					volumeid = fm.cwd().volumeid;					$.each(hashes, function(i, h) {						if (h.indexOf(volumeid) !== 0) {							mixed = true;							return false;						}					});				}				zipOn = (fm.isCommandEnabled('zipdl', hashes[0]));			}			if (mixed) {				mixedCmd = czipdl? 'zipdl' : 'download';				hashes = $.grep(hashes, function(h) {					var f = fm.file(h),						res = (! f || (! czipdl && f.mime === 'directory') || ! fm.isCommandEnabled(mixedCmd, h))? false : true;					if (f && inExec && ! res) {						$('#' + fm.cwdHash2Id(f.hash)).trigger('unselect');					}					return res;				});				if (! hashes.length) {					return [];				}			} else {				if (!fm.isCommandEnabled('download', hashes[0])) {					return [];				}			}						return $.grep(self.files(hashes), function(f) { 				var res = (! f.read || (! zipOn && f.mime == 'directory')) ? false : true;				if (inExec && ! res) {					$('#' + fm.cwdHash2Id(f.hash)).trigger('unselect');				}				return res;			});		};		this.linkedCmds = ['zipdl'];		this.shortcuts = [{		pattern     : 'shift+enter'	}];		this.getstate = function(select) {		var sel    = this.hashes(select),			cnt    = sel.length,			maxReq = this.options.maxRequests || 10,			mixed  = false,			croot  = '';				if (cnt < 1) {			return -1;		}		cnt = filter(sel).length;				return  (cnt && (zipOn || (cnt <= maxReq && ((!fm.UA.IE && !fm.UA.Mobile) || cnt == 1))) ? 0 : -1);	};		fm.bind('contextmenu', function(e){		var fm = self.fm,			helper = null,			targets, file, link,			getExtra = function(file) {				var link = file.url || fm.url(file.hash);				return {					icon: 'link',					node: $('<a/>')						.attr({href: link, target: '_blank', title: fm.i18n('link')})						.text(file.name)						.on('mousedown click touchstart touchmove touchend contextmenu', function(e){							e.stopPropagation();						})						.on('dragstart', function(e) {							var dt = e.dataTransfer || e.originalEvent.dataTransfer || null;							helper = null;							if (dt) {								var icon  = function(f) {										var mime = f.mime, i, tmb = fm.tmb(f);										i = '<div class="elfinder-cwd-icon '+fm.mime2class(mime)+' ui-corner-all"/>';										if (tmb) {											i = $(i).addClass(tmb.className).css('background-image', "url('"+tmb.url+"')").get(0).outerHTML;										}										return i;									};								dt.effectAllowed = 'copyLink';								if (dt.setDragImage) {									helper = $('<div class="elfinder-drag-helper html5-native">').append(icon(file)).appendTo($(document.body));									dt.setDragImage(helper.get(0), 50, 47);								}								if (!fm.UA.IE) {									dt.setData('elfinderfrom', window.location.href + file.phash);									dt.setData('elfinderfrom:' + dt.getData('elfinderfrom'), '');								}							}						})						.on('dragend', function(e) {							helper && helper.remove();						})				};			};		self.extra = null;		if (e.data) {			targets = e.data.targets || [];			if (targets.length === 1 && (file = fm.file(targets[0])) && file.mime !== 'directory') {				if (file.url != '1') {					self.extra = getExtra(file);				} else {					// Get URL ondemand					var node;					self.extra = {						icon: 'link',						node: $('<a/>')							.attr({href: '#', title: fm.i18n('getLink'), draggable: 'false'})							.text(file.name)							.on('click touchstart', function(e){								if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {									return;								}								var parent = node.parent();								e.stopPropagation();								e.preventDefault();								parent.removeClass('ui-state-disabled').addClass('elfinder-button-icon-spinner');								fm.request({									data : {cmd : 'url', target : file.hash},									preventDefault : true								})								.always(function(data) {									parent.removeClass('elfinder-button-icon-spinner');									if (data.url) {										var rfile = fm.file(file.hash);										rfile.url = data.url;										node.replaceWith(getExtra(file).node);									} else {										parent.addClass('ui-state-disabled');									}								});							})					};					node = self.extra.node;					node.ready(function(){						requestAnimationFrame(function(){							node.parent().addClass('ui-state-disabled').css('pointer-events', 'auto');						});					});				}			}		}	}).one('open', function() {		if (fm.api >= 2.1012) {			czipdl = fm.getCommand('zipdl');		}		dlntf = fm.api > 2.1038 && !fm.isCORS;	});		this.exec = function(select) {		var hashes  = this.hashes(select),			fm      = this.fm,			base    = fm.options.url,			files   = filter(hashes, true),			dfrd    = $.Deferred(),			iframes = '',			cdata   = '',			targets = {},			i, url,			linkdl  = false,			getTask = function(hashes) {				return function() {					var dfd = $.Deferred(),						root = fm.file(fm.root(hashes[0])),						single = (hashes.length === 1),						volName = root? (root.i18 || root.name) : null,						dir, dlName, phash;					if (single) {						if (dir = fm.file(hashes[0])) {							dlName = (dir.i18 || dir.name);						}					} else {						$.each(hashes, function() {							var d = fm.file(this);							if (d && (!phash || phash === d.phash)) {								phash = d.phash;							} else {								phash = null;								return false;							}						});						if (phash && (dir = fm.file(phash))) {							dlName = (dir.i18 || dir.name) + '-' + hashes.length;						}					}					if (dlName) {						volName = dlName;					}					volName && (volName = ' (' + volName + ')');					fm.request({						data : {cmd : 'zipdl', targets : hashes},						notify : {type : 'zipdl', cnt : 1, hideCnt : true, msg : fm.i18n('ntfzipdl') + volName},						cancel : true,						eachCancel : true,						preventDefault : true					}).done(function(e) {						var zipdl, dialog, btn = {}, dllink, form, iframe, m,							uniq = 'dlw' + (+new Date());						if (e.error) {							fm.error(e.error);							dfd.resolve();						} else if (e.zipdl) {							zipdl = e.zipdl;							if (dlName) {								m = fm.splitFileExtention(zipdl.name || '');								dlName += m[1]? ('.' + m[1]) : '.zip';							} else {								dlName = zipdl.name;							}							if ((html5dl && (!fm.UA.Safari || fm.isSameOrigin(fm.options.url))) || linkdl) {								url = fm.options.url + (fm.options.url.indexOf('?') === -1 ? '?' : '&')								+ 'cmd=zipdl&download=1';								$.each([hashes[0], zipdl.file, dlName, zipdl.mime], function(key, val) {									url += '&targets%5B%5D='+encodeURIComponent(val);								});								$.each(fm.customData, function(key, val) {									url += '&'+encodeURIComponent(key)+'='+encodeURIComponent(val);								});								url += '&'+encodeURIComponent(dlName);								dllink = $('<a/>')									.attr('href', url)									.attr('download', fm.escape(dlName))									.on('click', function() {										dfd.resolve();										dialog && dialog.elfinderdialog('destroy');									});								if (linkdl) {									dllink.attr('target', '_blank')										.append('<span class="elfinder-button-icon elfinder-button-icon-download"></span>'+fm.escape(dlName));									btn[fm.i18n('btnCancel')] = function() {										dialog.elfinderdialog('destroy');									};									dialog = self.fmDialog(dllink, {										title: fm.i18n('link'),										buttons: btn,										width: '200px',										destroyOnClose: true,										close: function() {											(dfd.state() !== 'resolved') && dfd.resolve();										}									});								} else {									click(dllink.hide().appendTo('body').get(0));									dllink.remove();								}							} else {								form = $('<form action="'+fm.options.url+'" method="post" target="'+uniq+'" style="display:none"/>')								.append('<input type="hidden" name="cmd" value="zipdl"/>')								.append('<input type="hidden" name="download" value="1"/>');								$.each([hashes[0], zipdl.file, dlName, zipdl.mime], function(key, val) {									form.append('<input type="hidden" name="targets[]" value="'+fm.escape(val)+'"/>');								});								$.each(fm.customData, function(key, val) {									form.append('<input type="hidden" name="'+key+'" value="'+fm.escape(val)+'"/>');								});								form.attr('target', uniq).appendTo('body');								iframe = $('<iframe style="display:none" name="'+uniq+'">')									.appendTo('body')									.ready(function() {										form.submit().remove();										dfd.resolve();										setTimeout(function() {											iframe.remove();										}, 20000); // give 20 sec file to be saved									});							}						}					}).fail(function(error) {						error && fm.error(error);						dfd.resolve();					});					return dfd.promise();				};			},			// use MouseEvent to click element for Safari etc			click = function(a) {				var clickEv;				if (typeof MouseEvent === 'function') {					clickEv = new MouseEvent('click');				} else {					clickEv = document.createEvent('MouseEvents');					clickEv.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);				}				a.dispatchEvent(clickEv);			},			checkCookie = function(id) {				var name = 'elfdl' + id,					parts;				parts = document.cookie.split(name + "=");				if (parts.length === 2) {					ntftm && clearTimeout(ntftm);					document.cookie = name + '=; path=' + cpath + '; max-age=0';					closeNotify();				} else {					setTimeout(function() { checkCookie(id); }, 200);				}			},			closeNotify = function() {				if (fm.ui.notify.children('.elfinder-notify-download').length) {					fm.notify({						type : 'download',						cnt : -1					});				}			},			reqids = [],			link, html5dl, fileCnt, clickEv, cid, ntftm, reqid;					if (!files.length) {			return dfrd.reject();		}				fileCnt = $.grep(files, function(f) { return f.mime === 'directory'? false : true; }).length;		link = $('<a>').hide().appendTo('body');		html5dl = (typeof link.get(0).download === 'string');				if (zipOn && (fileCnt !== files.length || fileCnt >= (this.options.minFilesZipdl || 1))) {			link.remove();			linkdl = (!html5dl && fm.UA.Mobile);			if (mixed) {				targets = {};				$.each(files, function(i, f) {					var p = f.hash.split('_', 2);					if (! targets[p[0]]) {						targets[p[0]] = [ f.hash ];					} else {						targets[p[0]].push(f.hash);					}				});				if (!linkdl && fm.UA.Mobile && Object.keys(targets).length > 1) {					linkdl = true;				}			} else {				targets = [ $.map(files, function(f) { return f.hash; }) ];			}			dfrd = fm.sequence($.map(targets, function(t) { return getTask(t); })).always(				function() {					fm.trigger('download', {files : files});				}			);			return dfrd;		} else {			reqids = [];			for (i = 0; i < files.length; i++) {				url = fm.openUrl(files[i].hash, true);				if (dlntf && url.substr(0, fm.options.url.length) === fm.options.url) {					reqid = fm.getRequestId();					reqids.push(reqid);					url += '&cpath=' + cpath + '&reqid=' + reqid;					ntftm = setTimeout(function() {						fm.notify({							type : 'download',							cnt : 1,							cancel : (fm.UA.IE || fm.UA.Edge)? void(0) : function() {								if (reqids.length) {									$.each(reqids, function() {										fm.request({											data: {												cmd: 'abort',												id: this											},											preventDefault: true										});									});								}								reqids = [];							}						});					}, fm.notifyDelay);					checkCookie(reqid);				}				if (html5dl && (!fm.UA.Safari || fm.isSameOrigin(url))) {					click(link.attr('href', url)						.attr('download', fm.escape(files[i].name))						.get(0)					);				} else {					if (fm.UA.Mobile) {						setTimeout(function(){							if (! window.open(url)) {								fm.error('errPopup');								ntftm && cleaerTimeout(ntftm);								closeNotify();							}						}, 100);					} else {						iframes += '<iframe class="downloader" id="downloader-' + files[i].hash+'" style="display:none" src="'+url+'"/>';					}				}			}			link.remove();			$(iframes)				.appendTo('body')				.ready(function() {					setTimeout(function() {						$(iframes).each(function() {							$('#' + $(this).attr('id')).remove();						});					}, 20000 + (10000 * i)); // give 20 sec + 10 sec for each file to be saved				});			fm.trigger('download', {files : files});			return dfrd.resolve();		}	};};/* * File: /js/commands/duplicate.js *//** * @class elFinder command "duplicate" * Create file/folder copy with suffix "copy Number" * * @type  elFinder.command * @author  Dmitry (dio) Levashov */elFinder.prototype.commands.duplicate = function() {		var fm = this.fm;		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;		return cnt && fm.cwd().write && $.grep(sel, function(f) { return f.read && f.phash === fm.cwd().hash && ! fm.isRoot(f)? true : false; }).length == cnt ? 0 : -1;	};		this.exec = function(hashes) {		var fm     = this.fm,			files  = this.files(hashes),			cnt    = files.length,			dfrd   = $.Deferred()				.fail(function(error) {					error && fm.error(error);				}), 			args = [];					if (! cnt) {			return dfrd.reject();		}				$.each(files, function(i, file) {			if (!file.read || !fm.file(file.phash).write) {				return !dfrd.reject(['errCopy', file.name, 'errPerm']);			}		});				if (dfrd.state() == 'rejected') {			return dfrd;		}				return fm.request({			data   : {cmd : 'duplicate', targets : this.hashes(hashes)},			notify : {type : 'copy', cnt : cnt},			navigate : {				toast : {					inbuffer : {msg: fm.i18n(['complete', fm.i18n('cmdduplicate')])}				}			}		});			};};/* * File: /js/commands/edit.js *//** * @class elFinder command "edit".  * Edit text file in dialog window * * @author Dmitry (dio) Levashov, dio@std42.ru **/elFinder.prototype.commands.edit = function() {		var self  = this,		fm    = this.fm,		clsEditing = fm.res('class', 'editing'),		mimesSingle = [],		mimes = [],		allowAll = false,		rtrim = function(str){			return str.replace(/\s+$/, '');		},		getEncSelect = function(heads) {			var sel = $('<select class="ui-corner-all"/>'),				hval;			if (heads) {				$.each(heads, function(i, head) {					hval = fm.escape(head.value);					sel.append('<option value="'+hval+'">'+(head.caption? fm.escape(head.caption) : hval)+'</option>');				});			}			$.each(self.options.encodings, function(i, v) {				sel.append('<option value="'+v+'">'+v+'</option>');			});			return sel;		},		getDlgWidth = function() {			var m, width;			if (typeof self.options.dialogWidth === 'string' && (m = self.options.dialogWidth.match(/(\d+)%/))) {				width = parseInt(fm.getUI().width() * (m[1] / 100));			} else {				width = parseInt(self.options.dialogWidth || 650);			}			return Math.min(width, $(window).width());		},		/**		 * Return files acceptable to edit		 *		 * @param  Array  files hashes		 * @return Array		 **/		filter = function(files) {			var cnt = files.length,				mime, ext, skip;						if (cnt > 1) {				mime = files[0].mime;				ext = files[0].name.replace(/^.*(\.[^.]+)$/, '$1');			}			return $.grep(files, function(file) {				var res;				if (skip || file.mime === 'directory') {					return false;				}				res = file.read					&& (allowAll || fm.mimeIsText(file.mime) || $.inArray(file.mime, cnt === 1? mimesSingle : mimes) !== -1) 					&& (!self.onlyMimes.length || $.inArray(file.mime, self.onlyMimes) !== -1)					&& (cnt === 1 || (file.mime === mime && file.name.substr(ext.length * -1) === ext))					&& (fm.uploadMimeCheck(file.mime, file.phash)? true : false)					&& setEditors(file, cnt)					&& Object.keys(editors).length;				if (!res) {					skip = true;				}				return res;			});		},		fileSync = function(hash) {			var old = fm.file(hash),				f;			fm.request({				cmd: 'info',				targets: [hash],				preventDefault: true			}).done(function(data) {				var changed;				if (data && data.files && data.files.length) {					f = data.files[0];					if (old.ts != f.ts || old.size != f.size) {						changed = { changed: [ f ] };						fm.updateCache(changed);						fm.change(changed);					}				}			});		},		/**		 * Open dialog with textarea to edit file		 *		 * @param  String  id       dialog id		 * @param  Object  file     file object		 * @param  String  content  file content		 * @return $.Deferred		 **/		dialog = function(id, file, content, encoding, editor) {			var dfrd = $.Deferred(),				_loaded = false,				loaded = function() {					if (!_loaded) {						fm.toast({							mode: 'warning',							msg: fm.i18n('nowLoading')						});						return false;					}					return true;				},				save = function() {					var encord = selEncoding? selEncoding.val():void(0),						saveDfd = $.Deferred().fail(function(err) {							dialogNode.show().find('button.elfinder-btncnt-0,button.elfinder-btncnt-1').hide();						}),						conf, res;					if (!loaded()) {						return saveDfd.resolve();					}					if (ta.editor) {						ta.editor.save(ta[0], ta.editor.instance);						conf = ta.editor.confObj;						if (conf.info && (conf.info.schemeContent || conf.info.arrayBufferContent)) {							encord = 'scheme';						}					}					res = getContent();					setOld(res);					if (res.promise) {						res.done(function(data) {							dfrd.notifyWith(ta, [encord, ta.data('hash'), old, saveDfd]);						}).fail(function(err) {							saveDfd.reject(err);						});					} else {						dfrd.notifyWith(ta, [encord, ta.data('hash'), old, saveDfd]);					}					return saveDfd;				},				saveon = function() {					if (!loaded()) { return; }					save().fail(function(err) {						err && fm.error(err);					});				},				cancel = function() {					ta.elfinderdialog('close');				},				savecl = function() {					if (!loaded()) { return; }					save().done(function() {						_loaded = false;						dialogNode.show();						cancel();					}).fail(function(err) {						dialogNode.show();						err && fm.error(err);					});					dialogNode.hide();				},				saveAs = function() {					if (!loaded()) { return; }					var prevOld = old,						phash = fm.file(file.phash)? file.phash : fm.cwd().hash,						fail = function(err) {							dialogs.addClass(clsEditing).fadeIn(function() {								err && fm.error(err);							});							old = prevOld;							fm.disable();						},						make = function() {							self.mime = saveAsFile.mime || file.mime;							self.prefix = (saveAsFile.name || file.name).replace(/ \d+(\.[^.]+)?$/, '$1');							self.requestCmd = 'mkfile';							self.nextAction = {};							self.data = {target : phash};							$.proxy(fm.res('mixin', 'make'), self)()								.done(function(data) {									if (data.added && data.added.length) {										ta.data('hash', data.added[0].hash);										save().done(function() {											_loaded = false;											dialogNode.show();											cancel();											dialogs.fadeIn();										}).fail(fail);									} else {										fail();									}								})								.progress(function(err) {									if (err && err === 'errUploadMime') {										ta.trigger('saveAsFail');									}								})								.fail(fail)								.always(function() {									delete self.mime;									delete self.prefix;									delete self.nextAction;									delete self.data;								});							fm.trigger('unselectfiles', { files: [ file.hash ] });						},						reqOpen = null,						dialogs = fm.getUI().children('.' + self.dialogClass + ':visible');						if (dialogNode.is(':hidden')) {							dialogs = dialogs.add(dialogNode);						}						dialogs.removeClass(clsEditing).fadeOut();										fm.enable();										if (fm.searchStatus.state < 2 && phash !== fm.cwd().hash) {						reqOpen = fm.exec('open', [phash], {thash: phash});					}										$.when([reqOpen]).done(function() {						reqOpen? fm.one('cwdrender', make) : make();					}).fail(fail);				},				changed = function() {					var dfd = $.Deferred(),						res, tm;					if (!_loaded) {						return dfd.resolve(false);					}					ta.editor && ta.editor.save(ta[0], ta.editor.instance);					res = getContent();					if (res && res.promise) {						tm = setTimeout(function() {							fm.notify({								type : 'chkcontent',								cnt : 1,								hideCnt: true							});						}, 100);						res.always(function() {							tm && clearTimeout(tm);							fm.notify({ type : 'chkcontent', cnt: -1 });						}).done(function(d) {							dfd.resolve(old !== d);						}).fail(function(err) {							dfd.resolve(err || true);						});					} else {						dfd.resolve(old !== res);					}					return dfd;				},				opts = {					title   : fm.escape(file.name),					width   : getDlgWidth(),					buttons : {},					cssClass  : clsEditing,					maxWidth  : 'window',					maxHeight : 'window',					allowMinimize : true,					allowMaximize : true,					openMaximized : editorMaximized() || (editor && editor.info && editor.info.openMaximized),					btnHoverFocus : false,					closeOnEscape : false,					propagationEvents : ['mousemove', 'mouseup', 'click'],					minimize : function() {						var conf;						if (ta.editor && dialogNode.closest('.ui-dialog').is(':hidden')) {							conf = ta.editor.confObj;							if (conf.info && conf.info.syncInterval) {								fileSync(file.hash);							}						}					},					close   : function() {						var close = function() {								var conf;								dfrd.resolve();								if (ta.editor) {									ta.editor.close(ta[0], ta.editor.instance);									conf = ta.editor.confObj;									if (conf.info && conf.info.syncInterval) {										fileSync(file.hash);									}								}								ta.elfinderdialog('destroy');							},							onlySaveAs = (typeof saveAsFile.name !== 'undefined'),							accept = onlySaveAs? {								label    : 'btnSaveAs',								callback : function() {									requestAnimationFrame(saveAs);								}							} : {								label    : 'btnSaveClose',								callback : function() {									save().done(function() {										close();									});								}							};						changed().done(function(change) {							var msgs = ['confirmNotSave'];							if (change) {								if (typeof change === 'string') {									msgs.unshift(change);								}								fm.confirm({									title  : self.title,									text   : msgs,									accept : accept,									cancel : {										label    : 'btnClose',										callback : close									},									buttons : onlySaveAs? null : [{										label    : 'btnSaveAs',										callback : function() {											requestAnimationFrame(saveAs);										}									}]								});							} else {								close();							}						});					},					open    : function() {						var loadRes, conf, interval;						ta.initEditArea.call(ta, id, file, content, fm);						if (ta.editor) {							loadRes = ta.editor.load(ta[0]) || null;							if (loadRes && loadRes.done) {								loadRes.always(function() {									_loaded = true;								}).done(function(instance) {									ta.editor.instance = instance;									ta.editor.focus(ta[0], ta.editor.instance);									setOld(getContent());									requestAnimationFrame(function() {										dialogNode.trigger('resize');									});								}).fail(function(error) {									error && fm.error(error);									ta.elfinderdialog('destroy');									return;								});							} else {								_loaded = true;								if (loadRes && (typeof loadRes === 'string' || Array.isArray(loadRes))) {									fm.error(loadRes);									ta.elfinderdialog('destroy');									return;								}								ta.editor.instance = loadRes;								ta.editor.focus(ta[0], ta.editor.instance);								setOld(getContent());								requestAnimationFrame(function() {									dialogNode.trigger('resize');								});							}							conf = ta.editor.confObj;							if (conf.info && conf.info.syncInterval) {								if (interval = parseInt(conf.info.syncInterval)) {									setTimeout(function() {										autoSync(interval);									}, interval);								}							}						} else {							_loaded = true;							setOld(getContent());						}					},					resize : function(e, data) {						ta.editor && ta.editor.resize(ta[0], ta.editor.instance, e, data || {});					}				},				getContent = function() {					return ta.getContent.call(ta, ta[0]);				},				setOld = function(res) {					if (res && res.promise) {						res.done(function(d) {							old = d;						});					} else {						old = res;					}				},				autoSync = function(interval) {					if (dialogNode.is(':visible')) {						fileSync(file.hash);						setTimeout(function() {							autoSync(interval);						}, interval);					}				},				saveAsFile = {},				ta, old, dialogNode, selEncoding, extEditor, maxW, syncInterval;							if (editor) {				if (editor.html) {					ta = $(editor.html);				}				extEditor = {					init     : editor.init || null,					load     : editor.load,					getContent : editor.getContent || null,					save     : editor.save,					beforeclose : typeof editor.beforeclose == 'function' ? editor.beforeclose : void 0,					close    : typeof editor.close == 'function' ? editor.close : function() {},					focus    : typeof editor.focus == 'function' ? editor.focus : function() {},					resize   : typeof editor.resize == 'function' ? editor.resize : function() {},					instance : null,					doSave   : saveon,					doCancel : cancel,					doClose  : savecl,					file     : file,					fm       : fm,					confObj  : editor,					trigger  : function(evName, data) {						fm.trigger('editEditor' + evName, Object.assign({}, editor.info || {}, data));					}				};			}						if (!ta) {				if (!fm.mimeIsText(file.mime)) {					return dfrd.reject('errEditorNotFound');				}				(function() {					var stateChange = function() {							if (selEncoding) {								changed().done(function(change) {									if (change) {										selEncoding.attr('title', fm.i18n('saveAsEncoding')).addClass('elfinder-edit-changed');									} else {										selEncoding.attr('title', fm.i18n('openAsEncoding')).removeClass('elfinder-edit-changed');									}								});							}						};											ta = $('<textarea class="elfinder-file-edit" rows="20" id="'+id+'-ta"></textarea>')						.on('input propertychange', stateChange);										if (!ta.editor || !ta.editor.info || ta.editor.info.useTextAreaEvent) {						ta.on('keydown', function(e) {							var code = e.keyCode,								value, start;														e.stopPropagation();							if (code == $.ui.keyCode.TAB) {								e.preventDefault();								// insert tab on tab press								if (this.setSelectionRange) {									value = this.value;									start = this.selectionStart;									this.value = value.substr(0, start) + "\t" + value.substr(this.selectionEnd);									start += 1;									this.setSelectionRange(start, start);								}							}														if (e.ctrlKey || e.metaKey) {								// close on ctrl+w/q								if (code == 'Q'.charCodeAt(0) || code == 'W'.charCodeAt(0)) {									e.preventDefault();									cancel();								}								if (code == 'S'.charCodeAt(0)) {									e.preventDefault();									saveon();								}							}													})						.on('mouseenter', function(){this.focus();});					}					ta.initEditArea = function(id, file, content) {						var heads = (encoding && encoding !== 'unknown')? [{value: encoding}] : [],							wfake = $('<select/>').hide(),							setSelW = function(init) {								init && wfake.appendTo(selEncoding.parent());								wfake.empty().append($('<option/>').text(selEncoding.val()));								selEncoding.width(wfake.width());							};						// ta.hide() for performance tune. Need ta.show() in `load()` if use textarea node.						ta.hide().val(content);						if (content === '' || ! encoding || encoding !== 'UTF-8') {							heads.push({value: 'UTF-8'});						}						selEncoding = getEncSelect(heads).on('touchstart', function(e) {							// for touch punch event handler							e.stopPropagation();						}).on('change', function() {							// reload to change encoding if not edited							changed().done(function(change) {								if (! change && getContent() !== '') {									cancel();									edit(file, selEncoding.val(), editor).fail(function(err) { err && fm.error(err); });								}							});							setSelW();						}).on('mouseover', stateChange);						ta.parent().next().prepend($('<div class="ui-dialog-buttonset elfinder-edit-extras"/>').append(selEncoding));						setSelW(true);					};				})();			}						ta.data('hash', file.hash);						if (extEditor) {				ta.editor = extEditor;								if (typeof extEditor.beforeclose === 'function') {					opts.beforeclose = function() {						return extEditor.beforeclose(ta[0], extEditor.instance);					};				}								if (typeof extEditor.init === 'function') {					ta.initEditArea = extEditor.init;				}								if (typeof extEditor.getContent === 'function') {					ta.getContent = extEditor.getContent;				}			}						if (! ta.initEditArea) {				ta.initEditArea = function() {};			}						if (! ta.getContent) {				ta.getContent = function() {					return rtrim(ta.val());				};			}						if (!editor || !editor.info || !editor.info.preventGet) {				opts.buttons[fm.i18n('btnSave')]      = saveon;				opts.buttons[fm.i18n('btnSaveClose')] = savecl;				opts.buttons[fm.i18n('btnSaveAs')]    = saveAs;				opts.buttons[fm.i18n('btnCancel')]    = cancel;			}						if (editor && typeof editor.prepare === 'function') {				editor.prepare(ta, opts, file);			}						dialogNode = self.fmDialog(ta, opts)				.attr('id', id)				.on('keydown keyup keypress', function(e) {					e.stopPropagation();				})				.css({ overflow: 'hidden', minHeight: '7em' })				.addClass('elfinder-edit-editor')				.closest('.ui-dialog')				.on('changeType', function(e, data) {					if (data.extention && data.mime) {						var ext = data.extention,							mime = data.mime,							btnSet = $(this).children('.ui-dialog-buttonpane').children('.ui-dialog-buttonset');						btnSet.children('.elfinder-btncnt-0,.elfinder-btncnt-1').hide();						saveAsFile.name = fm.splitFileExtention(file.name)[0] + '.' + data.extention;						saveAsFile.mime = data.mime;						if (!data.keepEditor) {							btnSet.children('.elfinder-btncnt-2').trigger('click');						}					}				});						// care to viewport scale change with mobile devices			maxW = (fm.options.dialogContained? elfNode : $(window)).width();			(dialogNode.width() > maxW) && dialogNode.width(maxW);						return dfrd.promise();		},				/**		 * Get file content and		 * open dialog with textarea to edit file content		 *		 * @param  String  file hash		 * @return jQuery.Deferred		 **/		edit = function(file, convert, editor) {			var hash   = file.hash,				opts   = fm.options,				dfrd   = $.Deferred(), 				id     = 'edit-'+fm.namespace+'-'+file.hash,				d      = fm.getUI().find('#'+id),				conv   = !convert? 0 : convert,				req, error, res;									if (d.length) {				d.elfinderdialog('toTop');				return dfrd.resolve();			}						if (!file.read || (!file.write && (!editor.info || !editor.info.converter))) {				error = ['errOpen', file.name, 'errPerm'];				return dfrd.reject(error);			}						if (editor && editor.info) {				if (typeof editor.info.edit === 'function') {					res = editor.info.edit.call(fm, file, editor);					if (res.promise) {						res.done(function() {							dfrd.resolve();						}).fail(function(error) {							dfrd.reject(error);						});					} else {						res? dfrd.resolve() : dfrd.reject();					}					return dfrd;				}				if (editor.info.urlAsContent || editor.info.preventGet) {					req = $.Deferred();					if (! editor.info.preventGet) {						fm.url(hash, { async: true, temporary: true }).done(function(url) {							req.resolve({content: url});						});					} else {						req.resolve({});					}				} else {					req = fm.request({						data           : {cmd : 'get', target : hash, conv : conv, _t : file.ts},						options        : {type: 'get', cache : true},						notify         : {type : 'file', cnt : 1},						preventDefault : true					});				}				req.done(function(data) {					var selEncoding, reg, m, res;					if (data.doconv) {						fm.confirm({							title  : self.title,							text   : data.doconv === 'unknown'? 'confirmNonUTF8' : 'confirmConvUTF8',							accept : {								label    : 'btnConv',								callback : function() {  									dfrd = edit(file, selEncoding.val(), editor);								}							},							cancel : {								label    : 'btnCancel',								callback : function() { dfrd.reject(); }							},							optionsCallback : function(options) {								options.create = function() {									var base = $('<div class="elfinder-dialog-confirm-encoding"/>'),										head = {value: data.doconv},										detected;																		if (data.doconv === 'unknown') {										head.caption = '-';									}									selEncoding = getEncSelect([head]);									$(this).next().find('.ui-dialog-buttonset')										.prepend(base.append($('<label>'+fm.i18n('encoding')+' </label>').append(selEncoding)));								};							}						});					} else {						if ((!editor || !editor.info || !editor.info.preventGet) && fm.mimeIsText(file.mime)) {							reg = new RegExp('^(data:'+file.mime.replace(/([.+])/g, '\\$1')+';base64,)', 'i');							if (!editor.info.dataScheme) {								if (window.atob && (m = data.content.match(reg))) {									data.content = atob(data.content.substr(m[1].length));								}							} else {								if (window.btoa && !data.content.match(reg)) {									data.content = 'data:'+file.mime+';base64,'+btoa(data.content);								}							}						}						dialog(id, file, data.content, data.encoding, editor)							.done(function(data) {								dfrd.resolve(data);							})							.progress(function(encoding, newHash, data, saveDfd) {								var ta = this;								if (newHash) {									hash = newHash;								}								fm.request({									options : {type : 'post'},									data : {										cmd     : 'put',										target  : hash,										encoding : encoding || data.encoding,										content : data									},									notify : {type : 'save', cnt : 1},									syncOnFail : true,									preventFail : true,									navigate : {										target : 'changed',										toast : {											inbuffer : {msg: fm.i18n(['complete', fm.i18n('btnSave')])}										}									}								})								.fail(function(error) {									dfrd.reject(error);									saveDfd.reject();								})								.done(function(data) {									requestAnimationFrame(function(){										ta.trigger('focus');										ta.editor && ta.editor.focus(ta[0], ta.editor.instance);									});									saveDfd.resolve();								});							})							.fail(function(error) {								dfrd.reject(error);							});					}				})				.fail(function(error) {					var err = fm.parseError(error);					err = Array.isArray(err)? err[0] : err;					(err !== 'errConvUTF8') && fm.sync();					dfrd.reject(error);				});			}			return dfrd.promise();		},				/**		 * Current editors of selected files		 * 		 * @type Object		 */		editors = {},				/**		 * Fallback editor (Simple text editor)		 * 		 * @type Object		 */		fallbackEditor = {			// Simple Text (basic textarea editor)			info : {				id : 'textarea',				name : 'TextArea',				useTextAreaEvent : true			},			load : function(textarea) {				// trigger event 'editEditorPrepare'				this.trigger('Prepare', {					node: textarea,					editorObj: void(0),					instance: void(0),					opts: {}				});				textarea.setSelectionRange && textarea.setSelectionRange(0, 0);				$(textarea).trigger('focus').show();			},			save : function(){}		},		/**		 * Set current editors		 * 		 * @param  Object  file object		 * @param  Number  cnt  count of selected items		 * @return Void		 */		setEditors = function(file, cnt) {			var mimeMatch = function(fileMime, editorMimes){					if (!editorMimes) {						return fm.mimeIsText(fileMime);					} else {						if (editorMimes[0] === '*' || $.inArray(fileMime, editorMimes) !== -1) {							return true;						}						var i, l;						l = editorMimes.length;						for (i = 0; i < l; i++) {							if (fileMime.indexOf(editorMimes[i]) === 0) {								return true;							}						}						return false;					}				},				extMatch = function(fileName, editorExts){					if (!editorExts || !editorExts.length) {						return true;					}					var ext = fileName.replace(/^.+\.([^.]+)|(.+)$/, '$1$2').toLowerCase(),					i, l;					l = editorExts.length;					for (i = 0; i < l; i++) {						if (ext === editorExts[i].toLowerCase()) {							return true;						}					}					return false;				},				optEditors = self.options.editors || [],				cwdWrite = fm.cwd().write;						stored = fm.storage('storedEditors') || {};			editors = {};			if (!optEditors.length) {				optEditors = [fallbackEditor];			}			$.each(optEditors, function(i, editor) {				var name;				if ((cnt === 1 || !editor.info.single)						&& ((!editor.info || !editor.info.converter)? file.write : cwdWrite)						&& (file.size > 0 || (!editor.info.converter && (editor.info.canMakeEmpty || (editor.info.canMakeEmpty !== false && fm.mimeIsText(file.mime)))))						&& (!editor.info.maxSize || file.size <= editor.info.maxSize)						&& mimeMatch(file.mime, editor.mimes || null)						&& extMatch(file.name, editor.exts || null)						&& typeof editor.load == 'function'						&& typeof editor.save == 'function') {										name = editor.info.name? editor.info.name : ('Editor ' + i);					editor.id = editor.info.id? editor.info.id : ('editor' + i),					editor.name = name;					editor.i18n = fm.i18n(name);					editors[editor.id] = editor;				}			});			return Object.keys(editors).length? true : false;		},		store = function(mime, editor) {			if (mime && editor) {				if (!$.isPlainObject(stored)) {					stored = {};				}				stored[mime] = editor.id;				fm.storage('storedEditors', stored);				fm.trigger('selectfiles', {files : fm.selected()});			}		},		useStoredEditor = function() {			var d = fm.storage('useStoredEditor');			return d? (d > 0) : self.options.useStoredEditor;		},		editorMaximized = function() {			var d = fm.storage('editorMaximized');			return d? (d > 0) : self.options.editorMaximized;		},		getSubMenuRaw = function(files, callback) {			var subMenuRaw = [];			$.each(editors, function(id, ed) {				subMenuRaw.push(					{						label    : fm.escape(ed.i18n),						icon     : ed.info && ed.info.icon? ed.info.icon : 'edit',						options  : { iconImg: ed.info && ed.info.iconImg? fm.baseUrl + ed.info.iconImg : void(0) },						callback : function() {							store(files[0].mime, ed);							callback && callback.call(ed);						}					}						);			});			return subMenuRaw;		},		getStoreId = function(name) {			// for compatibility to previous version			return name.toLowerCase().replace(/ +/g, '');		},		getStoredEditor = function(mime) {			var name = stored[mime];			return name && Object.keys(editors).length? editors[getStoreId(name)] : void(0);		},		infoRequest = function() {		},		stored;			this.shortcuts = [{		pattern     : 'ctrl+e'	}];		this.init = function() {		var self = this,			fm   = this.fm,			opts = this.options,			cmdChecks = [],			ccData, dfd;				this.onlyMimes = this.options.mimes || [];				fm.one('open', function() {			// editors setup			if (opts.editors && Array.isArray(opts.editors)) {				fm.trigger('canMakeEmptyFile', {mimes: Object.keys(fm.storage('mkfileTextMimes') || {}).concat(opts.makeTextMimes || ['text/plain'])});				$.each(opts.editors, function(i, editor) {					if (editor.info && editor.info.cmdCheck) {						cmdChecks.push(editor.info.cmdCheck);					}				});				if (cmdChecks.length) {					if (fm.api >= 2.1030) {						dfd = fm.request({							data : {								cmd: 'editor',								name: cmdChecks,								method: 'enabled'							},							preventDefault : true						}).done(function(d) {							ccData = d;						}).fail(function() {							ccData = {};						});					} else {						ccData = {};						dfd = $.Deferred().resolve();					}				} else {					dfd = $.Deferred().resolve();				}								dfd.always(function() {					if (ccData) {						opts.editors = $.grep(opts.editors, function(e) {							if (e.info && e.info.cmdCheck) {								return ccData[e.info.cmdCheck]? true : false;							} else {								return true;							}						});					}					$.each(opts.editors, function(i, editor) {						if (editor.setup && typeof editor.setup === 'function') {							editor.setup.call(editor, opts, fm);						}						if (!editor.disabled) {							if (editor.mimes && Array.isArray(editor.mimes)) {								mimesSingle = mimesSingle.concat(editor.mimes);								if (!editor.info || !editor.info.single) {									mimes = mimes.concat(editor.mimes);								}							}							if (!allowAll && editor.mimes && editor.mimes[0] === '*') {								allowAll = true;							}							if (!editor.info) {								editor.info = {};							}							if (editor.info.integrate) {								fm.trigger('helpIntegration', Object.assign({cmd: 'edit'}, editor.info.integrate));							}							if (editor.info.canMakeEmpty) {								fm.trigger('canMakeEmptyFile', {mimes: editor.mimes});							}						}					});										mimesSingle = ($.uniqueSort || $.unique)(mimesSingle);					mimes = ($.uniqueSort || $.unique)(mimes);										opts.editors = $.grep(opts.editors, function(e) {						return e.disabled? false : true;					});				});			}		})		.bind('select', function() {			editors = null;		})		.bind('contextmenucreate', function(e) {			var file, editor,				single = function(editor) {					var title = self.title;					fm.one('contextmenucreatedone', function() {						self.title = title;					});					self.title = fm.escape(editor.i18n);					if (editor.info && editor.info.iconImg) {						self.contextmenuOpts = {							iconImg: fm.baseUrl + editor.info.iconImg						};					}					delete self.variants;				};						self.contextmenuOpts = void(0);			if (e.data.type === 'files' && self.enabled()) {				file = fm.file(e.data.targets[0]);				if (setEditors(file, e.data.targets.length)) {					if (Object.keys(editors).length > 1) {						if (!useStoredEditor() || !(editor = getStoredEditor(file.mime))) {							delete self.extra;							self.variants = [];							$.each(editors, function(id, editor) {								self.variants.push([{ editor: editor }, editor.i18n, editor.info && editor.info.iconImg? fm.baseUrl + editor.info.iconImg : 'edit']);							});						} else {							single(editor);							self.extra = {								icon: 'menu',								node: $('<span/>')									.attr({title: fm.i18n('select')})									.on('click touchstart', function(e){										if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {											return;										}										var node = $(this);										e.stopPropagation();										e.preventDefault();										fm.trigger('contextmenu', {											raw: getSubMenuRaw(fm.selectedFiles(), function() {												var hashes = fm.selected();												fm.exec('edit', hashes, {editor: this});												fm.trigger('selectfiles', {files : hashes});											}),											x: node.offset().left,											y: node.offset().top										});									})							};						}					} else {						single(editors[Object.keys(editors)[0]]);						delete self.extra;					}				}			}		})		.bind('canMakeEmptyFile', function(e) {			if (e.data && e.data.resetTexts) {				var defs = fm.arrayFlip(self.options.makeTextMimes || ['text/plain']),					hides = fm.storage('mkfileHides') || {};				$.each((fm.storage('mkfileTextMimes') || {}), function(mime, type) {					if (!defs[mime]) {						delete fm.mimesCanMakeEmpty[mime];						delete hides[mime];					}				});				fm.storage('mkfileTextMimes', null);				if (Object.keys(hides).length) {					fm.storage('mkfileHides', hides);				} else {					fm.storage('mkfileHides', null);				}			}		});	};		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;		return cnt && filter(sel).length == cnt ? 0 : -1;	};		this.exec = function(select, opts) {		var fm    = this.fm, 			files = filter(this.files(select)),			hashes = $.map(files, function(f) { return f.hash; }),			list  = [],			editor = opts && opts.editor? opts.editor : null,			node = $(opts && opts._currentNode? opts._currentNode : $('#'+ fm.cwdHash2Id(hashes[0]))),			getEditor = function() {				var dfd = $.Deferred(),					storedId;								if (!editor && Object.keys(editors).length > 1) {					if (useStoredEditor() && (editor = getStoredEditor(files[0].mime))) {						return dfd.resolve(editor);					}					fm.trigger('contextmenu', {						raw: getSubMenuRaw(files, function() {							dfd.resolve(this);						}),						x: node.offset().left,						y: node.offset().top + 22,						opened: function() {							fm.one('closecontextmenu',function() {								requestAnimationFrame(function() {									if (dfd.state() === 'pending') {										dfd.reject();									}								});							});						}					});										fm.trigger('selectfiles', {files : hashes});										return dfd;				} else {					Object.keys(editors).length > 1 && editor && store(files[0].mime, editor);					return dfd.resolve(editor? editor : (Object.keys(editors).length? editors[Object.keys(editors)[0]] : null));				}			},			dfrd = $.Deferred(),			file;		if (editors === null) {			setEditors(files[0], hashes.length);		}				if (!node.length) {			node = fm.getUI('cwd');		}				getEditor().done(function(editor) {			while ((file = files.shift())) {				list.push(edit(file, void(0), editor).fail(function(error) {					error && fm.error(error);				}));			}						if (list.length) { 				$.when.apply(null, list).done(function() {					dfrd.resolve();				}).fail(function() {					dfrd.reject();				});			} else {				dfrd.reject();			}		}).fail(function() {			dfrd.reject();		});				return dfrd;	};};/* * File: /js/commands/empty.js *//** * @class elFinder command "empty". * Empty the folder * * @type  elFinder.command * @author  Naoki Sawada */elFinder.prototype.commands.empty = function() {		var self, fm,		selFiles = function(select) {			var sel = self.files(select);			if (!sel.length) {				sel = [ fm.cwd() ];			}			return sel;		};		this.linkedCmds = ['rm'];		this.init = function() {		// lazy assign to make possible to become superclass		self = this;		fm = this.fm;	};	this.getstate = function(select) {		var sel = selFiles(select),			cnt;				cnt = sel.length;		return $.grep(sel, function(f) { return f.read && f.write && f.mime === 'directory' ? true : false; }).length == cnt ? 0 : -1;	};		this.exec = function(hashes) {		var dirs = selFiles(hashes),			cnt  = dirs.length,			dfrd = $.Deferred()				.done(function() {					var data = {changed: {}};					fm.toast({msg: fm.i18n(['"'+success.join('", ')+'"', 'complete', fm.i18n('cmdempty')])});					$.each(dirs, function(i, dir) {						data.changed[dir.hash] = dir;					});					fm.change(data);				})				.always(function() {					var cwd = fm.cwd().hash;					fm.trigger('selectfiles', {files: $.map(dirs, function(d) { return cwd === d.phash? d.hash : null; })});				}),			success = [],			done = function(res) {				if (typeof res === 'number') {					success.push(dirs[res].name);					delete dirs[res].dirs;				} else {					res && fm.error(res);				}				(--cnt < 1) && dfrd[success.length? 'resolve' : 'reject']();			};		$.each(dirs, function(i, dir) {			var tm;			if (!(dir.write && dir.mime === 'directory')) {				done(['errEmpty', dir.name, 'errPerm']);				return null;			}			if (!fm.isCommandEnabled('rm', dir.hash)) {				done(['errCmdNoSupport', '"rm"']);				return null;			}			tm = setTimeout(function() {				fm.notify({type : 'search', cnt : 1, hideCnt : cnt > 1? false : true});			}, fm.notifyDelay);			fm.request({				data : {cmd  : 'open', target : dir.hash},				preventDefault : true,				asNotOpen : true			}).done(function(data) {				var targets = [];				tm && clearTimeout(tm);				if (fm.ui.notify.children('.elfinder-notify-search').length) {					fm.notify({type : 'search', cnt : -1, hideCnt : cnt > 1? false : true});				}				if (data && data.files && data.files.length) {					if (data.files.length > fm.maxTargets) {						done(['errEmpty', dir.name, 'errMaxTargets', fm.maxTargets]);					} else {						fm.updateCache(data);						$.each(data.files, function(i, f) {							if (!f.write || f.locked) {								done(['errEmpty', dir.name, 'errRm', f.name, 'errPerm']);								targets = [];								return false;							}							targets.push(f.hash);						});						if (targets.length) {							fm.exec('rm', targets, { _userAction : true, addTexts : [ fm.i18n('folderToEmpty', dir.name) ] })							.fail(function(error) {								fm.trigger('unselectfiles', {files: fm.selected()});								done(fm.parseError(error) || '');							})							.done(function() { done(i); });						}					}				} else {					fm.toast({ mode: 'warning', msg: fm.i18n('filderIsEmpty', dir.name)});					done('');				}			}).fail(function(error) {				done(fm.parseError(error) || '');			});		});				return dfrd;	};};/* * File: /js/commands/extract.js *//** * @class  elFinder command "extract" * Extract files from archive * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.extract = function() {		var self    = this,		fm      = self.fm,		mimes   = [],		filter  = function(files) {			return $.grep(files, function(file) { 				return file.read && $.inArray(file.mime, mimes) !== -1 ? true : false;			});		};		this.variants = [];	this.disableOnSearch = true;		// Update mimes list on open/reload	fm.bind('open reload', function() {		mimes = fm.option('archivers')['extract'] || [];		if (fm.api > 2) {			self.variants = [[{makedir: true}, fm.i18n('cmdmkdir')], [{}, fm.i18n('btnCwd')]];		} else {			self.variants = [[{}, fm.i18n('btnCwd')]];		}		self.change();	});		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;				return cnt && this.fm.cwd().write && filter(sel).length == cnt ? 0 : -1;	};		this.exec = function(hashes, opts) {		var files    = this.files(hashes),			dfrd     = $.Deferred(),			cnt      = files.length,			makedir  = opts && opts.makedir ? 1 : 0,			i, error,			decision;		var overwriteAll = false;		var omitAll = false;		var mkdirAll = 0;		var names = $.map(fm.files(hashes), function(file) { return file.name; });		var map = {};		$.grep(fm.files(hashes), function(file) {			map[file.name] = file;			return false;		});				var decide = function(decision) {			switch (decision) {				case 'overwrite_all' :					overwriteAll = true;					break;				case 'omit_all':					omitAll = true;					break;			}		};		var unpack = function(file) {			if (!(file.read && fm.file(file.phash).write)) {				error = ['errExtract', file.name, 'errPerm'];				fm.error(error);				dfrd.reject(error);			} else if ($.inArray(file.mime, mimes) === -1) {				error = ['errExtract', file.name, 'errNoArchive'];				fm.error(error);				dfrd.reject(error);			} else {				fm.request({					data:{cmd:'extract', target:file.hash, makedir:makedir},					notify:{type:'extract', cnt:1},					syncOnFail:true,					navigate:{						toast : makedir? {							incwd    : {msg: fm.i18n(['complete', fm.i18n('cmdextract')]), action: {cmd: 'open', msg: 'cmdopen'}},							inbuffer : {msg: fm.i18n(['complete', fm.i18n('cmdextract')]), action: {cmd: 'open', msg: 'cmdopen'}}						} : {							inbuffer : {msg: fm.i18n(['complete', fm.i18n('cmdextract')])}						}					}				})				.fail(function (error) {					if (dfrd.state() != 'rejected') {						dfrd.reject(error);					}				})				.done(function () {				});			}		};				var confirm = function(files, index) {			var file = files[index],			name = fm.splitFileExtention(file.name)[0],			existed = ($.inArray(name, names) >= 0),			next = function(){				if((index+1) < cnt) {					confirm(files, index+1);				} else {					dfrd.resolve();				}			};			if (!makedir && existed && map[name].mime != 'directory') {				fm.confirm(					{						title : fm.i18n('ntfextract'),						text  : ['errExists', name, 'confirmRepl'],						accept:{							label : 'btnYes',							callback:function (all) {								decision = all ? 'overwrite_all' : 'overwrite';								decide(decision);								if(!overwriteAll && !omitAll) {									if('overwrite' == decision) {										unpack(file);									}									if((index+1) < cnt) {										confirm(files, index+1);									} else {										dfrd.resolve();									}								} else if(overwriteAll) {									for (i = index; i < cnt; i++) {										unpack(files[i]);									}									dfrd.resolve();								}							}						},						reject : {							label : 'btnNo',							callback:function (all) {								decision = all ? 'omit_all' : 'omit';								decide(decision);								if(!overwriteAll && !omitAll && (index+1) < cnt) {									confirm(files, index+1);								} else if (omitAll) {									dfrd.resolve();								}							}						},						cancel : {							label : 'btnCancel',							callback:function () {								dfrd.resolve();							}						},						all : ((index+1) < cnt)					}				);			} else if (!makedir) {				if (mkdirAll == 0) {					fm.confirm({						title : fm.i18n('cmdextract'),						text  : [fm.i18n('cmdextract')+' "'+file.name+'"', 'confirmRepl'],						accept:{							label : 'btnYes',							callback:function (all) {								all && (mkdirAll = 1);								unpack(file);								next();							}						},						reject : {							label : 'btnNo',							callback:function (all) {								all && (mkdirAll = -1);								next();							}						},						cancel : {							label : 'btnCancel',							callback:function () {								dfrd.resolve();							}						},						all : ((index+1) < cnt)					});				} else {					(mkdirAll > 0) && unpack(file);					next();				}			} else {				unpack(file);				next();			}		};				if (!(this.enabled() && cnt && mimes.length)) {			return dfrd.reject();		}				if(cnt > 0) {			confirm(files, 0);		}		return dfrd;	};};/* * File: /js/commands/forward.js *//** * @class  elFinder command "forward" * Open next visited folder * * @author Dmitry (dio) Levashov **/(elFinder.prototype.commands.forward = function() {		this.alwaysEnabled = true;	this.updateOnSelect = true;	this.shortcuts = [{		pattern     : 'ctrl+right'	}];		this.getstate = function() {		return this.fm.history.canForward() ? 0 : -1;	};		this.exec = function() {		return this.fm.history.forward();	};	}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/fullscreen.js *//** * @class  elFinder command "fullscreen" * elFinder node to full scrren mode * * @author Naoki Sawada **/elFinder.prototype.commands.fullscreen = function() {		var self   = this,		fm     = this.fm,		update = function(e, data) {			e.preventDefault();			e.stopPropagation();			if (data && data.fullscreen) {				self.update(void(0), (data.fullscreen === 'on'));			}		};	this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.syncTitleOnChange = true;	this.value = false;	this.options = {		ui : 'fullscreenbutton'	};	this.getstate = function() {		return 0;	};		this.exec = function() {		var node = fm.getUI().get(0),			full = (node === fm.toggleFullscreen(node));		self.title = fm.i18n(full ? 'reinstate' : 'cmdfullscreen');		self.update(void(0), full);		return $.Deferred().resolve();	};		fm.bind('init', function() {		fm.getUI().off('resize.' + fm.namespace, update).on('resize.' + fm.namespace, update);	});};/* * File: /js/commands/getfile.js *//** * @class elFinder command "getfile".  * Return selected files info into outer callback. * For use elFinder with wysiwyg editors etc. * * @author Dmitry (dio) Levashov, dio@std42.ru **/(elFinder.prototype.commands.getfile = function() {		var self   = this,		fm     = this.fm,		filter = function(files) {			var o = self.options;			files = $.grep(files, function(file) {				return (file.mime != 'directory' || o.folders) && file.read ? true : false;			});			return o.multiple || files.length == 1 ? files : [];		};		this.alwaysEnabled = true;	this.callback      = fm.options.getFileCallback;	this._disabled     = typeof(this.callback) == 'function';		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;					return this.callback && cnt && filter(sel).length == cnt ? 0 : -1;	};		this.exec = function(hashes) {		var fm    = this.fm,			opts  = this.options,			files = this.files(hashes),			cnt   = files.length,			url   = fm.option('url'),			tmb   = fm.option('tmbUrl'),			dfrd  = $.Deferred()				.done(function(data) {					var res,						done = function() {							if (opts.oncomplete == 'close') {								fm.hide();							} else if (opts.oncomplete == 'destroy') {								fm.destroy();							}						},						fail = function(error) {							if (opts.onerror == 'close') {								fm.hide();							} else if (opts.onerror == 'destroy') {								fm.destroy();							} else {								error && fm.error(error);							}						};										fm.trigger('getfile', {files : data});										try {						res = self.callback(data, fm);					} catch(e) {						fail(['Error in `getFileCallback`.', e.message]);						return;					}										if (typeof res === 'object' && typeof res.done === 'function') {						res.done(done).fail(fail);					} else {						done();					}				}),			result = function(file) {				return opts.onlyURL					? opts.multiple ? $.map(files, function(f) { return f.url; }) : files[0].url					: opts.multiple ? files : files[0];			},			req = [], 			i, file, dim;		for (i = 0; i < cnt; i++) {			file = files[i];			if (file.mime == 'directory' && !opts.folders) {				return dfrd.reject();			}			file.baseUrl = url;			if (file.url == '1') {				req.push(fm.request({					data : {cmd : 'url', target : file.hash},					notify : {type : 'url', cnt : 1, hideCnt : true},					preventDefault : true				})				.done(function(data) {					if (data.url) {						var rfile = fm.file(this.hash);						rfile.url = this.url = data.url;					}				}.bind(file)));			} else {				file.url = fm.url(file.hash);			}			if (! opts.onlyURL) {				if (opts.getPath) {					file.path = fm.path(file.hash);					if (file.path === '' && file.phash) {						// get parents						(function() {							var dfd  = $.Deferred();							req.push(dfd);							fm.path(file.hash, false, {})								.done(function(path) {									file.path = path;								})								.fail(function() {									file.path = '';								})								.always(function() {									dfd.resolve();								});						})();					}				}				if (file.tmb && file.tmb != 1) {					file.tmb = tmb + file.tmb;				}				if (!file.width && !file.height) {					if (file.dim) {						dim = file.dim.split('x');						file.width = dim[0];						file.height = dim[1];					} else if (opts.getImgSize && file.mime.indexOf('image') !== -1) {						req.push(fm.request({							data : {cmd : 'dim', target : file.hash},							notify : {type : 'dim', cnt : 1, hideCnt : true},							preventDefault : true						})						.done(function(data) {							if (data.dim) {								var dim = data.dim.split('x');								var rfile = fm.file(this.hash);								rfile.width = this.width = dim[0];								rfile.height = this.height = dim[1];							}						}.bind(file)));					}				}			}		}				if (req.length) {			$.when.apply(null, req).always(function() {				dfrd.resolve(result(files));			});			return dfrd;		}				return dfrd.resolve(result(files));	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/help.js *//** * @class  elFinder command "help" * "About" dialog * * @author Dmitry (dio) Levashov **/(elFinder.prototype.commands.help = function() {		var fm   = this.fm,		self = this,		linktpl = '<div class="elfinder-help-link"> <a href="{url}">{link}</a></div>',		linktpltgt = '<div class="elfinder-help-link"> <a href="{url}" target="_blank">{link}</a></div>',		atpl    = '<div class="elfinder-help-team"><div>{author}</div>{work}</div>',		url     = /\{url\}/,		link    = /\{link\}/,		author  = /\{author\}/,		work    = /\{work\}/,		r       = 'replace',		prim    = 'ui-priority-primary',		sec     = 'ui-priority-secondary',		lic     = 'elfinder-help-license',		tab     = '<li class="' + fm.res('class', 'tabstab') + ' elfinder-help-tab-{id}"><a href="#'+fm.namespace+'-help-{id}" class="ui-tabs-anchor">{title}</a></li>',		html    = ['<div class="ui-tabs ui-widget ui-widget-content ui-corner-all elfinder-help">', 				'<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-top">'],		stpl    = '<div class="elfinder-help-shortcut"><div class="elfinder-help-shortcut-pattern">{pattern}</div> {descrip}</div>',		sep     = '<div class="elfinder-help-separator"/>',		selfUrl = $('base').length? document.location.href.replace(/#.*$/, '') : '',		clTabActive = fm.res('class', 'tabsactive'),				getTheme = function() {			var src;			if (fm.theme && fm.theme.author) {				src = atpl[r]('elfinder-help-team', 'elfinder-help-team elfinder-help-term-theme')[r](author, fm.i18n(fm.theme.author) + (fm.theme.email? ' <'+fm.theme.email+'>' : ''))[r](work, fm.i18n('theme') + ' ('+fm.i18n(fm.theme.name)+')');			} else {				src = '<div class="elfinder-help-team elfinder-help-term-theme" style="display:none"></div>';			}			return src;		},		about = function() {			html.push('<div id="'+fm.namespace+'-help-about" class="ui-tabs-panel ui-widget-content ui-corner-bottom"><div class="elfinder-help-logo"/>');			html.push('<h3>elFinder</h3>');			html.push('<div class="'+prim+'">'+fm.i18n('webfm')+'</div>');			html.push('<div class="'+sec+'">'+fm.i18n('ver')+': '+fm.version+'</div>');			html.push('<div class="'+sec+'">'+fm.i18n('protocolver')+': <span class="apiver"></span></div>');			html.push('<div class="'+sec+'">jQuery/jQuery UI: '+$().jquery+'/'+$.ui.version+'</div>');			html.push(sep);						html.push(linktpltgt[r](url, 'https://studio-42.github.io/elFinder/')[r](link, fm.i18n('homepage')));			html.push(linktpltgt[r](url, 'https://github.com/Studio-42/elFinder/wiki')[r](link, fm.i18n('docs')));			html.push(linktpltgt[r](url, 'https://github.com/Studio-42/elFinder')[r](link, fm.i18n('github')));			//html.push(linktpltgt[r](url, 'http://twitter.com/elrte_elfinder')[r](link, fm.i18n('twitter')));						html.push(sep);						html.push('<div class="'+prim+'">'+fm.i18n('team')+'</div>');						html.push(atpl[r](author, 'Dmitry "dio" Levashov <dio@std42.ru>')[r](work, fm.i18n('chiefdev')));			html.push(atpl[r](author, 'Naoki Sawada <hypweb+elfinder@gmail.com>')[r](work, fm.i18n('developer')));			html.push(atpl[r](author, 'Troex Nevelin <troex@fury.scancode.ru>')[r](work, fm.i18n('maintainer')));			html.push(atpl[r](author, 'Alexey Sukhotin <strogg@yandex.ru>')[r](work, fm.i18n('contributor')));						if (fm.i18[fm.lang].translator) {				$.each(fm.i18[fm.lang].translator.split(', '), function() {					html.push(atpl[r](author, $.trim(this))[r](work, fm.i18n('translator')+' ('+fm.i18[fm.lang].language+')'));				});				}						html.push(getTheme());			html.push(sep);			html.push('<div class="'+lic+'">'+fm.i18n('icons')+': Pixelmixer, <a href="http://p.yusukekamiyamane.com" target="_blank">Fugue</a>, <a href="https://icons8.com" target="_blank">Icons8</a></div>');						html.push(sep);			html.push('<div class="'+lic+'">Licence: 3-clauses BSD Licence</div>');			html.push('<div class="'+lic+'">Copyright © 2009-2018, Studio 42</div>');			html.push('<div class="'+lic+'">„ …'+fm.i18n('dontforget')+' ”</div>');			html.push('</div>');		},		shortcuts = function() {			var sh = fm.shortcuts();			// shortcuts tab			html.push('<div id="'+fm.namespace+'-help-shortcuts" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');						if (sh.length) {				html.push('<div class="ui-widget-content elfinder-help-shortcuts">');				$.each(sh, function(i, s) {					html.push(stpl.replace(/\{pattern\}/, s[0]).replace(/\{descrip\}/, s[1]));				});							html.push('</div>');			} else {				html.push('<div class="elfinder-help-disabled">'+fm.i18n('shortcutsof')+'</div>');			}									html.push('</div>');					},		help = function() {			// help tab			html.push('<div id="'+fm.namespace+'-help-help" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');			html.push('<a href="https://github.com/Studio-42/elFinder/wiki" target="_blank" class="elfinder-dont-panic"><span>DON\'T PANIC</span></a>');			html.push('</div>');			// end help		},		useInteg = false,		integrations = function() {			useInteg = true;			html.push('<div id="'+fm.namespace+'-help-integrations" class="ui-tabs-panel ui-widget-content ui-corner-bottom"/>');		},		useDebug = false,		debug = function() {			useDebug = true;			// debug tab			html.push('<div id="'+fm.namespace+'-help-debug" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');			html.push('<div class="ui-widget-content elfinder-help-debug"><ul></ul></div>');			html.push('</div>');			// end debug		},		debugRender = function() {			var render = function(elm, obj) {				$.each(obj, function(k, v) {					elm.append($('<dt/>').text(k));					if (typeof v === 'undefined') {						elm.append($('<dd/>').append($('<span/>').text('undfined')));					} else if (typeof v === 'object' && !v) {						elm.append($('<dd/>').append($('<span/>').text('null')));					} else if (typeof v === 'object' && ($.isPlainObject(v) || v.length)) {						elm.append( $('<dd/>').append(render($('<dl/>'), v)));					} else {						elm.append($('<dd/>').append($('<span/>').text((v && typeof v === 'object')? '[]' : (v? v : '""'))));					}				});				return elm;			},			cnt = debugUL.children('li').length,			targetL, target, tabId,			info, lastUL, lastDIV;						if (self.debug.options || self.debug.debug) {				if (cnt >= 5) {					lastUL = debugUL.children('li:last');					lastDIV = debugDIV.children('div:last');					if (lastDIV.is(':hidden')) {						lastUL.remove();						lastDIV.remove();					} else {						lastUL.prev().remove();						lastDIV.prev().remove();					}				}								tabId = fm.namespace + '-help-debug-' + (+new Date());				targetL = $('<li/>').html('<a href="'+selfUrl+'#'+tabId+'">'+self.debug.debug.cmd+'</a>').prependTo(debugUL);				target = $('<div id="'+tabId+'"/>').data('debug', self.debug);								targetL.on('click.debugrender', function() {					var debug = target.data('debug');					target.removeData('debug');					if (debug) {						target.hide();						if (debug.debug) {							info = $('<fieldset>').append($('<legend/>').text('debug'), render($('<dl/>'), debug.debug));							target.append(info);						}						if (debug.options) {							info = $('<fieldset>').append($('<legend/>').text('options'), render($('<dl/>'), debug.options));							target.append(info);						}						target.show();					}					targetL.off('click.debugrender');				});								debugUL.after(target);								opened && debugDIV.tabs('refresh');			}		},		content = '',		opened, tabInteg, integDIV, tabDebug, debugDIV, debugUL;		this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.state = -1;		this.shortcuts = [{		pattern     : 'f1',		description : this.title	}];		fm.bind('load', function() {		var parts = self.options.view || ['about', 'shortcuts', 'help', 'integrations', 'debug'],			i, helpSource, tabBase, tabNav, tabs, delta;				// remove 'preference' tab, it moved to command 'preference'		if ((i = $.inArray('preference', parts)) !== -1) {			parts.splice(i, 1);		}				// debug tab require jQueryUI Tabs Widget		if (! $.fn.tabs) {			if ((i = $.inArray(parts, 'debug')) !== -1) {				parts.splice(i, 1);			}		}				$.each(parts, function(i, title) {			html.push(tab[r](/\{id\}/g, title)[r](/\{title\}/, fm.i18n(title)));		});				html.push('</ul>');		$.inArray('about', parts) !== -1 && about();		$.inArray('shortcuts', parts) !== -1 && shortcuts();		if ($.inArray('help', parts) !== -1) {			helpSource = fm.i18nBaseUrl + 'help/%s.html.js';			help();		}		$.inArray('integrations', parts) !== -1 && integrations();		$.inArray('debug', parts) !== -1 && debug();				html.push('</div>');		content = $(html.join(''));				content.find('.ui-tabs-nav li')			.on('mouseenter mouseleave', function(e) {				$(this).toggleClass('ui-state-hover', e.type === 'mouseenter');			})			.on('focus blur', 'a', function(e) {				$(e.delegateTarget).toggleClass('ui-state-focus', e.type === 'focusin');			})			.children()			.on('click', function(e) {				var link = $(this);								e.preventDefault();				e.stopPropagation();								link.parent().addClass(clTabActive).siblings().removeClass(clTabActive);				content.children('.ui-tabs-panel').hide().filter(link.attr('href')).show();			})			.filter(':first').trigger('click');				if (useInteg) {			tabInteg = content.find('.elfinder-help-tab-integrations').hide();			integDIV = content.find('#'+fm.namespace+'-help-integrations').hide().append($('<div class="elfinder-help-integrations-desc"/>').html(fm.i18n('integrationWith')));			fm.bind('helpIntegration', function(e) {				var ul = integDIV.children('ul:first'),					data, elm, cmdUL, cmdCls;				if (e.data) {					if ($.isPlainObject(e.data)) {						data = Object.assign({							link: '',							title: '',							banner: ''						}, e.data);						if (data.title || data.link) {							if (!data.title) {								data.title = data.link;							}							if (data.link) {								elm = $('<a/>').attr('href', data.link).attr('target', '_blank').text(data.title);							} else {								elm = $('<span/>').text(data.title);							}							if (data.banner) {								elm = $('<span/>').append($('<img/>').attr(data.banner), elm);							}						}					} else {						elm = $(e.data);						elm.filter('a').each(function() {							var tgt = $(this);							if (!tgt.attr('target')) {								tgt.attr('target', '_blank');;							}						});					}					if (elm) {						tabInteg.show();						if (!ul.length) {							ul = $('<ul class="elfinder-help-integrations"/>').appendTo(integDIV);						}						if (data && data.cmd) {							cmdCls = 'elfinder-help-integration-' + data.cmd;							cmdUL = ul.find('ul.' + cmdCls);							if (!cmdUL.length) {								cmdUL = $('<ul class="'+cmdCls+'"/>');								ul.append($('<li/>').append($('<span/>').html(fm.i18n('cmd'+data.cmd))).append(cmdUL));							}							elm = cmdUL.append($('<li/>').append(elm));						} else {							ul.append($('<li/>').append(elm));						}					}				}			}).bind('themechange', function() {				content.find('div.elfinder-help-term-theme').replaceWith(getTheme());			});		}		// debug		if (useDebug) {			tabDebug = content.find('.elfinder-help-tab-debug').hide();			debugDIV = content.find('#'+fm.namespace+'-help-debug').children('div:first');			debugUL = debugDIV.children('ul:first').on('click', function(e) {				e.preventDefault();				e.stopPropagation();			});			self.debug = {};				fm.bind('backenddebug', function(e) {				// CAUTION: DO NOT TOUCH `e.data`				if (useDebug && e.data && e.data.debug) {					self.debug = { options : e.data.options, debug : Object.assign({ cmd : fm.currentReqCmd }, e.data.debug) };					if (self.dialog) {						debugRender();					}				}			});		}		content.find('#'+fm.namespace+'-help-about').find('.apiver').text(fm.api);		self.dialog = self.fmDialog(content, {				title : self.title,				width : 530,				maxWidth: 'window',				maxHeight: 'window',				autoOpen : false,				destroyOnClose : false,				close : function() {					if (useDebug) {						tabDebug.hide();						debugDIV.tabs('destroy');					}					opened = false;				}			})			.on('click', function(e) {				e.stopPropagation();			})			.css({				overflow: 'hidden'			});				tabBase = self.dialog.children('.ui-tabs');		tabNav = tabBase.children('.ui-tabs-nav:first');		tabs = tabBase.children('.ui-tabs-panel');		delta = self.dialog.outerHeight(true) - self.dialog.height();		self.dialog.closest('.ui-dialog').on('resize', function() {			tabs.height(self.dialog.height() - delta - tabNav.outerHeight(true) - 20);		});				if (helpSource) {			self.dialog.one('initContents', function() {				$.ajax({					url: self.options.helpSource? self.options.helpSource : helpSource.replace('%s', fm.lang),					dataType: 'html'				}).done(function(source) {					$('#'+fm.namespace+'-help-help').html(source);				}).fail(function() {					$.ajax({						url: helpSource.replace('%s', 'en'),						dataType: 'html'					}).done(function(source) {						$('#'+fm.namespace+'-help-help').html(source);					});				});			});		}				self.state = 0;		fm.trigger('helpBuilded', self.dialog);	}).one('open', function() {		var debug = false;		fm.one('backenddebug', function() {			debug =true;		}).one('opendone', function() {			requestAnimationFrame(function() {				if (! debug && useDebug) {					useDebug = false;					tabDebug.hide();					debugDIV.hide();					debugUL.hide();				}			});		});	});		this.getstate = function() {		return 0;	};		this.exec = function(sel, opts) {		var tab = opts? opts.tab : void(0),			debugShow = function() {				if (useDebug) {					debugDIV.tabs();					debugUL.find('a:first').trigger('click');					tabDebug.show();					opened = true;				}			};		debugShow();		this.dialog.trigger('initContents').elfinderdialog('open').find((tab? '.elfinder-help-tab-'+tab : '.ui-tabs-nav li') + ' a:first').trigger('click');		return $.Deferred().resolve();	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/hidden.js *//** * @class  elFinder command "hidden" * Always hidden command for uiCmdMap * * @author Naoki Sawada **/elFinder.prototype.commands.hidden = function() {		this.hidden = true;	this.updateOnSelect = false;	this.getstate = function() {		return -1;	};};/* * File: /js/commands/hide.js *//** * @class elFinder command "hide". * folders/files to hide as personal setting. * * @type  elFinder.command * @author  Naoki Sawada */elFinder.prototype.commands.hide = function() {		var self = this,		nameCache = {},		hideData, hideCnt, cMenuType, sOrigin;	this.syncTitleOnChange = true;	this.shortcuts = [{		pattern : 'ctrl+shift+dot',		description : this.fm.i18n('toggleHidden')	}];	this.init = function() {		var fm = this.fm;				hideData = fm.storage('hide') || {items: {}};		hideCnt = Object.keys(hideData.items).length;		this.title = fm.i18n(hideData.show? 'hideHidden' : 'showHidden');		self.update(void(0), self.title);	};	this.fm.bind('select contextmenucreate closecontextmenu', function(e, fm) {		var sel = (e.data? (e.data.selected || e.data.targets) : null) || fm.selected();		if (e.type === 'select' && e.data) {			sOrigin = e.data.origin;		} else if (e.type === 'contextmenucreate') {			cMenuType = e.data.type;		}		if (!sel.length || (((e.type !== 'contextmenucreate' && sOrigin !== 'navbar') || cMenuType === 'cwd') && sel[0] === fm.cwd().hash)) {			self.title = fm.i18n(hideData.show? 'hideHidden' : 'showHidden');		} else {			self.title = fm.i18n('cmdhide');		}		if (e.type !== 'closecontextmenu') {			self.update(cMenuType === 'cwd'? (hideCnt? 0 : -1) : void(0), self.title);		} else {			cMenuType = '';			requestAnimationFrame(function() {				self.update(void(0), self.title);			});		}	});	this.getstate = function(sel) {		return (cMenuType !== 'cwd' && (sel || this.fm.selected()).length) || hideCnt? 0 : -1;	};	this.exec = function(hashes, opts) {		var fm = this.fm,			dfrd = $.Deferred()				.done(function() {					fm.trigger('hide', {items: items, opts: opts});				})				.fail(function(error) {					fm.error(error);				}),			o = opts || {},			items = o.targets? o.targets : (hashes || fm.selected()),			added = [],			removed = [],			notifyto, files, res;		hideData = fm.storage('hide') || {};		if (!$.isPlainObject(hideData)) {			hideData = {};		}		if (!$.isPlainObject(hideData.items)) {			hideData.items = {};		}		if (opts._currentType === 'shortcut' || !items.length || (opts._currentType !== 'navbar' && sOrigin !=='navbar' && items[0] === fm.cwd().hash)) {			if (hideData.show) {				o.hide = true;			} else if (Object.keys(hideData.items).length) {				o.show = true;			}		}		if (o.reset) {			o.show = true;			hideCnt = 0;		}		if (o.show || o.hide) {			if (o.show) {				hideData.show = true;			} else {				delete hideData.show;			}			if (o.show) {				fm.storage('hide', o.reset? null : hideData);				self.title = fm.i18n('hideHidden');				self.update(o.reset? -1 : void(0), self.title);				$.each(hideData.items, function(h) {					var f = fm.file(h, true);					if (f && (fm.searchStatus.state || !f.phash || fm.file(f.phash))) {						added.push(f);					}				});				if (added.length) {					fm.updateCache({added: added});					fm.add({added: added});				}				if (o.reset) {					hideData = {items: {}};				}				return dfrd.resolve();			}			items = Object.keys(hideData.items);		}		if (items.length) {			$.each(items, function(i, h) {				var f;				if (!hideData.items[h]) {					f = fm.file(h);					if (f) {						nameCache[h] = f.i18 || f.name;					}					hideData.items[h] = nameCache[h]? nameCache[h] : h;				}			});			hideCnt = Object.keys(hideData.items).length;			files = this.files(items);			fm.storage('hide', hideData);			fm.remove({removed: items});			if (hideData.show) {				this.exec(void(0), {hide: true});			}			if (!o.hide) {				res = {};				res.undo = {					cmd : 'hide',					callback : function() {						var nData = fm.storage('hide');						if (nData) {							$.each(items, function(i, h) {								delete nData.items[h];							});							hideCnt = Object.keys(nData.items).length;							fm.storage('hide', nData);							fm.trigger('hide', {items: items, opts: {}});							self.update(hideCnt? 0 : -1);						}						fm.updateCache({added: files});						fm.add({added: files});					}				};				res.redo = {					cmd : 'hide',					callback : function() {						return fm.exec('hide', void(0), {targets: items});					}				};			}		}		return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(res);	};};/* * File: /js/commands/home.js */(elFinder.prototype.commands.home = function() {		this.title = 'Home';	this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.shortcuts = [{		pattern     : 'ctrl+home ctrl+shift+up',		description : 'Home'	}];		this.getstate = function() {		var root = this.fm.root(),			cwd  = this.fm.cwd().hash;					return root && cwd && root != cwd ? 0: -1;	};		this.exec = function() {		return this.fm.exec('open', this.fm.root());	};	}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/info.js *//** * @class elFinder command "info".  * Display dialog with file properties. * * @author Dmitry (dio) Levashov, dio@std42.ru **/(elFinder.prototype.commands.info = function() {		var m   = 'msg',		fm  = this.fm,		spclass = 'elfinder-spinner',		btnclass = 'elfinder-info-button',		msg = {			calc     : fm.i18n('calc'),			size     : fm.i18n('size'),			unknown  : fm.i18n('unknown'),			path     : fm.i18n('path'),			aliasfor : fm.i18n('aliasfor'),			modify   : fm.i18n('modify'),			perms    : fm.i18n('perms'),			locked   : fm.i18n('locked'),			dim      : fm.i18n('dim'),			kind     : fm.i18n('kind'),			files    : fm.i18n('files'),			folders  : fm.i18n('folders'),			roots    : fm.i18n('volumeRoots'),			items    : fm.i18n('items'),			yes      : fm.i18n('yes'),			no       : fm.i18n('no'),			link     : fm.i18n('link'),			owner    : fm.i18n('owner'),			group    : fm.i18n('group'),			perm     : fm.i18n('perm'),			getlink  : fm.i18n('getLink')		},		applyZWSP = function(str, remove) {			if (remove) {				return str.replace(/\u200B/g, '');			} else {				return str.replace(/(\/|\\)/g, "$1\u200B");			}		};		this.items = ['size', 'aliasfor', 'path', 'link', 'dim', 'modify', 'perms', 'locked', 'owner', 'group', 'perm'];	if (this.options.custom && Object.keys(this.options.custom).length) {		$.each(this.options.custom, function(name, details) {			details.label && this.items.push(details.label);		});	}	this.tpl = {		main       : '<div class="ui-helper-clearfix elfinder-info-title {dirclass}"><span class="elfinder-cwd-icon {class} ui-corner-all"{style}/>{title}</div><table class="elfinder-info-tb">{content}</table>',		itemTitle  : '<strong>{name}</strong><span class="elfinder-info-kind">{kind}</span>',		groupTitle : '<strong>{items}: {num}</strong>',		row        : '<tr><td class="elfinder-info-label">{label} : </td><td class="{class}">{value}</td></tr>',		spinner    : '<span>{text}</span> <span class="'+spclass+' '+spclass+'-{name}"/>'	};		this.alwaysEnabled = true;	this.updateOnSelect = false;	this.shortcuts = [{		pattern     : 'ctrl+i'	}];		this.init = function() {		$.each(msg, function(k, v) {			msg[k] = fm.i18n(v);		});	};		this.getstate = function() {		return 0;	};		this.exec = function(hashes) {		var files   = this.files(hashes);		if (! files.length) {			files   = this.files([ this.fm.cwd().hash ]);		}		var self    = this,			fm      = this.fm,			o       = this.options,			tpl     = this.tpl,			row     = tpl.row,			cnt     = files.length,			content = [],			view    = tpl.main,			l       = '{label}',			v       = '{value}',			reqs    = [],			reqDfrd = null,			opts    = {				title : fm.i18n('selectionInfo'),				width : 'auto',				close : function() {					$(this).elfinderdialog('destroy');					if (reqDfrd && reqDfrd.state() === 'pending') {						reqDfrd.reject();					}					$.grep(reqs, function(r) {						r && r.state() === 'pending' && r.reject();					});				}			},			count = [],			replSpinner = function(msg, name, className) {				dialog.find('.'+spclass+'-'+name).parent().html(msg).addClass(className || '');			},			id = fm.namespace+'-info-'+$.map(files, function(f) { return f.hash; }).join('-'),			dialog = fm.getUI().find('#'+id),			customActions = [],			style = '',			hashClass = 'elfinder-font-mono elfinder-info-hash',			size, tmb, file, title, dcnt, rdcnt, path, getHashAlgorisms, hideItems;					if (!cnt) {			return $.Deferred().reject();		}					if (dialog.length) {			dialog.elfinderdialog('toTop');			return $.Deferred().resolve();		}				hideItems = fm.storage('infohides') || fm.arrayFlip(o.hideItems, true);		if (cnt === 1) {			file = files[0];						if (file.icon) {				style = ' '+fm.getIconStyle(file);			}						view  = view.replace('{dirclass}', file.csscls? fm.escape(file.csscls) : '').replace('{class}', fm.mime2class(file.mime)).replace('{style}', style);			title = tpl.itemTitle.replace('{name}', fm.escape(file.i18 || file.name)).replace('{kind}', '<span title="'+fm.escape(file.mime)+'">'+fm.mime2kind(file)+'</span>');			tmb = fm.tmb(file);						if (!file.read) {				size = msg.unknown;			} else if (file.mime != 'directory' || file.alias) {				size = fm.formatSize(file.size);			} else {				size = tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'size');				count.push(file.hash);			}						!hideItems.size && content.push(row.replace(l, msg.size).replace(v, size));			!hideItems.aleasfor && file.alias && content.push(row.replace(l, msg.aliasfor).replace(v, file.alias));			if (!hideItems.path) {				if (path = fm.path(file.hash, true)) {					content.push(row.replace(l, msg.path).replace(v, applyZWSP(fm.escape(path))).replace('{class}', 'elfinder-info-path'));				} else {					content.push(row.replace(l, msg.path).replace(v, tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'path')).replace('{class}', 'elfinder-info-path'));					reqs.push(fm.path(file.hash, true, {notify: null})					.fail(function() {						replSpinner(msg.unknown, 'path');					})					.done(function(path) {						replSpinner(applyZWSP(path), 'path');					}));				}			}			if (!hideItems.link && file.read) {				var href,				name_esc = fm.escape(file.name);				if (file.url == '1') {					content.push(row.replace(l, msg.link).replace(v, '<button class="'+btnclass+' '+spclass+'-url">'+msg.getlink+'</button>'));				} else {					if (file.url) {						href = file.url;					} else if (file.mime === 'directory') {						if (o.nullUrlDirLinkSelf && file.url === null) {							var loc = window.location;							href = loc.pathname + loc.search + '#elf_' + file.hash;						} else if (file.url !== '' && fm.option('url', (!fm.isRoot(file) && file.phash) || file.hash)) {							href = fm.url(file.hash);						}					} else {						href = fm.url(file.hash);					}					href && content.push(row.replace(l, msg.link).replace(v,  '<a href="'+href+'" target="_blank">'+name_esc+'</a>'));				}			}						if (!hideItems.dim) {				if (file.dim) { // old api					content.push(row.replace(l, msg.dim).replace(v, file.dim));				} else if (file.mime.indexOf('image') !== -1) {					if (file.width && file.height) {						content.push(row.replace(l, msg.dim).replace(v, file.width+'x'+file.height));					} else {						content.push(row.replace(l, msg.dim).replace(v, tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'dim')));						reqs.push(fm.request({							data : {cmd : 'dim', target : file.hash},							preventDefault : true						})						.fail(function() {							replSpinner(msg.unknown, 'dim');						})						.done(function(data) {							replSpinner(data.dim || msg.unknown, 'dim');							if (data.dim) {								var dim = data.dim.split('x');								var rfile = fm.file(file.hash);								rfile.width = dim[0];								rfile.height = dim[1];							}						}));					}				}			}						!hideItems.modify && content.push(row.replace(l, msg.modify).replace(v, fm.formatDate(file)));			!hideItems.perms && content.push(row.replace(l, msg.perms).replace(v, fm.formatPermissions(file)));			!hideItems.locked && content.push(row.replace(l, msg.locked).replace(v, file.locked ? msg.yes : msg.no));			!hideItems.owner && file.owner && content.push(row.replace(l, msg.owner).replace(v, file.owner));			!hideItems.group && file.group && content.push(row.replace(l, msg.group).replace(v, file.group));			!hideItems.perm && file.perm && content.push(row.replace(l, msg.perm).replace(v, fm.formatFileMode(file.perm)));						// Get MD5 hash			if (window.ArrayBuffer && (fm.options.cdns.sparkmd5 || fm.options.cdns.jssha) && file.mime !== 'directory' && file.size > 0 && (!o.showHashMaxsize || file.size <= o.showHashMaxsize)) {				getHashAlgorisms = [];				$.each(fm.storage('hashchekcer') || o.showHashAlgorisms, function(i, n) {					if (!file[n]) {					content.push(row.replace(l, fm.i18n(n)).replace(v, tpl.spinner.replace('{text}', msg.calc).replace('{name}', n)));						getHashAlgorisms.push(n);					} else {						content.push(row.replace(l, fm.i18n(n)).replace(v, file[n]).replace('{class}', hashClass));					}				});				reqs.push(					fm.getContentsHashes(file.hash, getHashAlgorisms).progress(function(hashes) {						$.each(getHashAlgorisms, function(i, n) {							if (hashes[n]) {								replSpinner(hashes[n], n, hashClass);							}						});					}).always(function() {						$.each(getHashAlgorisms, function(i, n) {							replSpinner(msg.unknown, n);						});					})				);			}						// Add custom info fields			if (o.custom) {				$.each(o.custom, function(name, details) {					if (					  !hideItems[details.label]					    &&					  (!details.mimes || $.grep(details.mimes, function(m){return (file.mime === m || file.mime.indexOf(m+'/') === 0)? true : false;}).length)					    &&					  (!details.hashRegex || file.hash.match(details.hashRegex))					) {						// Add to the content						content.push(row.replace(l, fm.i18n(details.label)).replace(v , details.tpl.replace('{id}', id)));						// Register the action						if (details.action && (typeof details.action == 'function')) {							customActions.push(details.action);						}					}				});			}		} else {			view  = view.replace('{class}', 'elfinder-cwd-icon-group');			title = tpl.groupTitle.replace('{items}', msg.items).replace('{num}', cnt);			dcnt  = $.grep(files, function(f) { return f.mime == 'directory' ? true : false ; }).length;			if (!dcnt) {				size = 0;				$.each(files, function(h, f) { 					var s = parseInt(f.size);										if (s >= 0 && size >= 0) {						size += s;					} else {						size = 'unknown';					}				});				content.push(row.replace(l, msg.kind).replace(v, msg.files));				!hideItems.size && content.push(row.replace(l, msg.size).replace(v, fm.formatSize(size)));			} else {				rdcnt = $.grep(files, function(f) { return f.mime === 'directory' && (! f.phash || f.isroot)? true : false ; }).length;				dcnt -= rdcnt;				content.push(row.replace(l, msg.kind).replace(v, (rdcnt === cnt || dcnt === cnt)? msg[rdcnt? 'roots' : 'folders'] : $.map({roots: rdcnt, folders: dcnt, files: cnt - rdcnt - dcnt}, function(c, t) { return c? msg[t]+' '+c : null; }).join(', ')));				!hideItems.size && content.push(row.replace(l, msg.size).replace(v, tpl.spinner.replace('{text}', msg.calc).replace('{name}', 'size')));				count = $.map(files, function(f) { return f.hash; });							}		}				view = view.replace('{title}', title).replace('{content}', content.join('').replace(/{class}/g, ''));				dialog = self.fmDialog(view, opts);		dialog.attr('id', id).one('mousedown', '.elfinder-info-path', function() {			$(this).html(applyZWSP($(this).html(), true));		});		if (fm.UA.Mobile && $.fn.tooltip) {			dialog.children('.ui-dialog-content .elfinder-info-title').tooltip({				classes: {					'ui-tooltip': 'elfinder-ui-tooltip ui-widget-shadow'				},				tooltipClass: 'elfinder-ui-tooltip ui-widget-shadow',				track: true			});		}		if (file && file.url == '1') {			dialog.on('click', '.'+spclass+'-url', function(){				$(this).parent().html(tpl.spinner.replace('{text}', fm.i18n('ntfurl')).replace('{name}', 'url'));				fm.request({					data : {cmd : 'url', target : file.hash},					preventDefault : true				})				.fail(function() {					replSpinner(name_esc, 'url');				})				.done(function(data) {					if (data.url) {						replSpinner('<a href="'+data.url+'" target="_blank">'+name_esc+'</a>' || name_esc, 'url');						var rfile = fm.file(file.hash);						rfile.url = data.url;					} else {						replSpinner(name_esc, 'url');					}				});			});		}		// load thumbnail		if (tmb) {			$('<img/>')				.on('load', function() { dialog.find('.elfinder-cwd-icon').addClass(tmb.className).css('background-image', "url('"+tmb.url+"')"); })				.attr('src', tmb.url);		}				// send request to count total size		if (count.length) {			reqDfrd = fm.getSize(count).done(function(data) {				replSpinner(data.formated, 'size');			}).fail(function() {				replSpinner(msg.unknown, 'size');			});		}				// call custom actions		if (customActions.length) {			$.each(customActions, function(i, action) {				try {					action(file, fm, dialog);				} catch(e) {					fm.debug('error', e);				}			});		}				return $.Deferred().resolve();	};	}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/mkdir.js *//** * @class  elFinder command "mkdir" * Create new folder * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.mkdir = function() {		var fm   = this.fm,		self = this,		curOrg;		this.value           = '';	this.disableOnSearch = true;	this.updateOnSelect  = false;	this.syncTitleOnChange = true;	this.mime            = 'directory';	this.prefix          = 'untitled folder';	this.exec            = function(select, cOpts) {		var onCwd;		if (select && select.length && cOpts && cOpts._currentType && cOpts._currentType === 'navbar') {			this.origin = cOpts._currentType;			this.data = {				target: select[0]			};		} else {			onCwd = fm.cwd().hash === select[0];			this.origin = curOrg && !onCwd? curOrg : 'cwd';			delete this.data;		}		if (! select && ! this.options.intoNewFolderToolbtn) {			fm.getUI('cwd').trigger('unselectall');		}		//this.move = (!onCwd && curOrg !== 'navbar' && fm.selected().length)? true : false;		this.move = this.value === fm.i18n('cmdmkdirin');		return $.proxy(fm.res('mixin', 'make'), self)();	};		this.shortcuts = [{		pattern     : 'ctrl+shift+n'	}];	this.init = function() {		if (this.options.intoNewFolderToolbtn) {			this.syncTitleOnChange = true;		}	};		fm.bind('select contextmenucreate closecontextmenu', function(e) {		var sel = (e.data? (e.data.selected || e.data.targets) : null) || fm.selected();				self.className = 'mkdir';		curOrg = e.data && sel.length? (e.data.origin || e.data.type || '') : '';		if (!self.options.intoNewFolderToolbtn && curOrg === '') {			curOrg = 'cwd';		}		if (sel.length && curOrg !== 'navbar' && curOrg !== 'cwd' && fm.cwd().hash !== sel[0]) {			self.title = fm.i18n('cmdmkdirin');			self.className += ' elfinder-button-icon-mkdirin';		} else {			self.title = fm.i18n('cmdmkdir');		}		if (e.type !== 'closecontextmenu') {			self.update(void(0), self.title);		} else {			requestAnimationFrame(function() {				self.update(void(0), self.title);			});		}	});		this.getstate = function(select) {		var cwd = fm.cwd(),			sel = (curOrg === 'navbar' || (select && select[0] !== cwd.hash))? this.files(select || fm.selected()) : [],			cnt = sel.length;		if (curOrg === 'navbar') {			return cnt && sel[0].write && sel[0].read? 0 : -1;  		} else {			return cwd.write && (!cnt || $.grep(sel, function(f) { return f.read && ! f.locked? true : false; }).length == cnt)? 0 : -1;		}	};};/* * File: /js/commands/mkfile.js *//** * @class  elFinder command "mkfile" * Create new empty file * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.mkfile = function() {		var self = this;	this.disableOnSearch = true;	this.updateOnSelect  = false;	this.mime            = 'text/plain';	this.prefix          = 'untitled file.txt';	this.variants        = [];	this.getTypeName = function(mime, type) {		var fm = self.fm,			name;		if (name = fm.messages['kind' + fm.kinds[mime]]) {			name = fm.i18n(['extentiontype', type.toUpperCase(), name]);		} else {			name = fm.i18n(['extentionfile', type.toUpperCase()]);		}		return name;	};	this.fm.bind('open reload canMakeEmptyFile', function() {		var fm = self.fm,			hides = fm.storage('mkfileHides') || {};		self.variants = [];		if (fm.mimesCanMakeEmpty) {			$.each(fm.mimesCanMakeEmpty, function(mime, type) {				type && !hides[mime] && fm.uploadMimeCheck(mime) && self.variants.push([mime, self.getTypeName(mime, type)]);			});		}		self.change();	});	this.getstate = function() {		return this.fm.cwd().write ? 0 : -1;	};	this.exec = function(_dum, mime) {		var fm = self.fm,			type, err;		if (type = fm.mimesCanMakeEmpty[mime]) {			if (fm.uploadMimeCheck(mime)) {				this.mime = mime;				this.prefix = fm.i18n(['untitled file', type]);				return $.proxy(fm.res('mixin', 'make'), self)();			}			err = ['errMkfile', self.getTypeName(mime, type)];		}		return $.Deferred().reject(err);	};};/* * File: /js/commands/netmount.js *//** * @class  elFinder command "netmount" * Mount network volume with user credentials. * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.netmount = function() {		var self = this,		hasMenus = false,		content;	this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.drivers = [];		this.handlers = {		load : function() {			var fm = self.fm;			self.drivers = fm.netDrivers;			if (self.drivers.length) {				requestAnimationFrame(function() {					$.each(self.drivers, function() {						var d = self.options[this];						if (d) {							hasMenus = true;							if (d.integrateInfo) {								fm.trigger('helpIntegration', Object.assign({cmd: 'netmount'}, d.integrateInfo));							}						}					});				});			}		}	};	this.getstate = function() {		return hasMenus ? 0 : -1;	};		this.exec = function() {		var fm = self.fm,			dfrd = $.Deferred(),			o = self.options,			create = function() {				var winFocus = function() {						inputs.protocol.trigger('change', 'winfocus');					},					inputs = {						protocol : $('<select/>')						.on('change', function(e, data){							var protocol = this.value;							content.find('.elfinder-netmount-tr').hide();							content.find('.elfinder-netmount-tr-'+protocol).show();							dialogNode && dialogNode.children('.ui-dialog-buttonpane:first').find('button').show();							if (typeof o[protocol].select == 'function') {								o[protocol].select(fm, e, data);							}							requestAnimationFrame(function() {								content.find('input:text.elfinder-tabstop:visible:first').trigger('focus');							});						})						.addClass('ui-corner-all')					},					opts = {						title          : fm.i18n('netMountDialogTitle'),						resizable      : false,						modal          : true,						destroyOnClose : false,						open           : function() {							$(window).on('focus.'+fm.namespace, winFocus);							inputs.protocol.trigger('change');						},						close          : function() { 							dfrd.state() == 'pending' && dfrd.reject();							$(window).off('focus.'+fm.namespace, winFocus);						},						buttons        : {}					},					doMount = function() {						var protocol = inputs.protocol.val(),							data = {cmd : 'netmount', protocol: protocol},							cur = o[protocol];						$.each(content.find('input.elfinder-netmount-inputs-'+protocol), function(name, input) {							var val, elm;							elm = $(input);							if (elm.is(':radio,:checkbox')) {								if (elm.is(':checked')) {									val = $.trim(elm.val());								}							} else {								val = $.trim(elm.val());							}							if (val) {								data[input.name] = val;							}						});							if (!data.host) {							return fm.trigger('error', {error : 'errNetMountHostReq', opts : {modal: true}});						}							fm.request({data : data, notify : {type : 'netmount', cnt : 1, hideCnt : true}})							.done(function(data) {								var pdir;								if (data.added && data.added.length) {									if (data.added[0].phash) {										if (pdir = fm.file(data.added[0].phash)) {											if (! pdir.dirs) {												pdir.dirs = 1;												fm.change({ changed: [ pdir ] });											}										}									}									fm.one('netmountdone', function() {										fm.exec('open', data.added[0].hash);									});								}								dfrd.resolve();							})							.fail(function(error) {								if (cur.fail && typeof cur.fail == 'function') {									cur.fail(fm, fm.parseError(error));								}								dfrd.reject(error);							});							self.dialog.elfinderdialog('close');					},					form = $('<form autocomplete="off"/>').on('keydown', 'input', function(e) {						var comp = true,							next;						if (e.keyCode === $.ui.keyCode.ENTER) {							$.each(form.find('input:visible:not(.elfinder-input-optional)'), function() {								if ($(this).val() === '') {									comp = false;									next = $(this);									return false;								}							});							if (comp) {								doMount();							} else {								next.trigger('focus');							}						}					}),					hidden  = $('<div/>'),					dialog;				content = $('<table class="elfinder-info-tb elfinder-netmount-tb"/>')					.append($('<tr/>').append($('<td>'+fm.i18n('protocol')+'</td>')).append($('<td/>').append(inputs.protocol)));				$.each(self.drivers, function(i, protocol) {					if (o[protocol]) {						inputs.protocol.append('<option value="'+protocol+'">'+fm.i18n(o[protocol].name || protocol)+'</option>');						$.each(o[protocol].inputs, function(name, input) {							input.attr('name', name);							if (input.attr('type') != 'hidden') {								input.addClass('ui-corner-all elfinder-netmount-inputs-'+protocol);								content.append($('<tr/>').addClass('elfinder-netmount-tr elfinder-netmount-tr-'+protocol).append($('<td>'+fm.i18n(name)+'</td>')).append($('<td/>').append(input)));							} else {								input.addClass('elfinder-netmount-inputs-'+protocol);								hidden.append(input);							}						});						o[protocol].protocol = inputs.protocol;					}				});								content.append(hidden);								content.find('.elfinder-netmount-tr').hide();				opts.buttons[fm.i18n('btnMount')] = doMount;				opts.buttons[fm.i18n('btnCancel')] = function() {					self.dialog.elfinderdialog('close');				};								content.find('select,input').addClass('elfinder-tabstop');								dialog = self.fmDialog(form.append(content), opts);				dialogNode = dialog.closest('.ui-dialog');				dialog.ready(function(){					inputs.protocol.trigger('change');					dialog.elfinderdialog('posInit');				});				return dialog;			},			dialogNode;				if (!self.dialog) {			self.dialog = create();		} else {			self.dialog.elfinderdialog('open');		}		return dfrd.promise();	};	self.fm.bind('netmount', function(e) {		var d = e.data || null,			o = self.options;		if (d && d.protocol) {			if (o[d.protocol] && typeof o[d.protocol].done == 'function') {				o[d.protocol].done(self.fm, d);				content.find('select,input').addClass('elfinder-tabstop');				self.dialog.elfinderdialog('tabstopsInit');			}		}	});};elFinder.prototype.commands.netunmount = function() {	var self = this;	this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.drivers = [];		this.handlers = {		load : function() {			this.drivers = this.fm.netDrivers;		}	};	this.getstate = function(sel) {		var fm = this.fm,			file;		return !!sel && this.drivers.length && !this._disabled && (file = fm.file(sel[0])) && file.netkey ? 0 : -1;	};		this.exec = function(hashes) {		var self   = this,			fm     = this.fm,			dfrd   = $.Deferred()				.fail(function(error) {					error && fm.error(error);				}),			drive  = fm.file(hashes[0]),			childrenRoots = function(hash) {				var roots = [],					work;				if (fm.leafRoots) {					work = [];					$.each(fm.leafRoots, function(phash, hashes) {						var parents = fm.parents(phash),							idx, deep;						if ((idx = $.inArray(hash, parents)) !== -1) {							idx = parents.length - idx;							$.each(hashes, function(i, h) {								work.push({i: idx, hash: h});							});						}					});					if (work.length) {						work.sort(function(a, b) { return a.i < b.i; });						$.each(work, function(i, o) {							roots.push(o.hash);						});					}				}				return roots;			};		if (this._disabled) {			return dfrd.reject();		}		if (dfrd.state() == 'pending') {			fm.confirm({				title  : self.title,				text   : fm.i18n('confirmUnmount', drive.name),				accept : {					label    : 'btnUnmount',					callback : function() {  						var target =  drive.hash,							roots = childrenRoots(target),							requests = [],							removed = [],							doUmount = function() {								$.when(requests).done(function() {									fm.request({										data   : {cmd  : 'netmount', protocol : 'netunmount', host: drive.netkey, user : target, pass : 'dum'}, 										notify : {type : 'netunmount', cnt : 1, hideCnt : true},										preventFail : true									})									.fail(function(error) {										dfrd.reject(error);									})									.done(function(data) {										drive.volumeid && delete fm.volumeExpires[drive.volumeid];										dfrd.resolve();									});								}).fail(function(error) {									if (removed.length) {										fm.remove({ removed: removed });									}									dfrd.reject(error);								});							};												if (roots.length) {							fm.confirm({								title : self.title,								text  : (function() {									var msgs = ['unmountChildren'];									$.each(roots, function(i, hash) {										msgs.push([fm.file(hash).name]);									});									return msgs;								})(),								accept : {									label : 'btnUnmount',									callback : function() {										$.each(roots, function(i, hash) {											var d = fm.file(hash);											if (d.netkey) {												requests.push(fm.request({													data   : {cmd  : 'netmount', protocol : 'netunmount', host: d.netkey, user : d.hash, pass : 'dum'}, 													notify : {type : 'netunmount', cnt : 1, hideCnt : true},													preventDefault : true												}).done(function(data) {													if (data.removed) {														d.volumeid && delete fm.volumeExpires[d.volumeid];														removed = removed.concat(data.removed);													}												}));											}										});										doUmount();									}								},								cancel : {									label : 'btnCancel',									callback : function() {										dfrd.reject();									}								}							});						} else {							requests = null;							doUmount();						}					}				},				cancel : {					label    : 'btnCancel',					callback : function() { dfrd.reject(); }				}			});		}					return dfrd;	};};/* * File: /js/commands/open.js *//** * @class  elFinder command "open" * Enter folder or open files in new windows * * @author Dmitry (dio) Levashov **/  (elFinder.prototype.commands.open = function() {		var fm = this.fm;	this.alwaysEnabled = true;	this.noChangeDirOnRemovedCwd = true;		this._handlers = {		dblclick : function(e) { e.preventDefault(); fm.exec('open', e.data && e.data.file? [ e.data.file ]: void(0)); },		'select enable disable reload' : function(e) { this.update(e.type == 'disable' ? -1 : void(0));  }	};		this.shortcuts = [{		pattern     : 'ctrl+down numpad_enter'+(fm.OS != 'mac' && ' enter')	}];	this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;				return cnt == 1 			? (sel[0].read? 0 : -1) 			: (cnt && !fm.UA.Mobile) ? ($.grep(sel, function(file) { return file.mime == 'directory' || ! file.read ? false : true;}).length == cnt ? 0 : -1) : -1;	};		this.exec = function(hashes, cOpts) {		var dfrd  = $.Deferred().fail(function(error) { error && fm.error(error); }),			files = this.files(hashes),			cnt   = files.length,			thash = (typeof cOpts == 'object')? cOpts.thash : false,			opts  = this.options,			into  = opts.into || 'window',			file, url, s, w, imgW, imgH, winW, winH, reg, link, html5dl, inline,			selAct, cmd;		if (!cnt && !thash) {			{				return dfrd.reject();			}		}		// open folder		if (thash || (cnt == 1 && (file = files[0]) && file.mime == 'directory')) {			if (!thash && file && !file.read) {				return dfrd.reject(['errOpen', file.name, 'errPerm']);			} else {				if (fm.keyState.ctrlKey && (fm.keyState.shiftKey || typeof fm.options.getFileCallback !== 'function')) {					if (fm.getCommand('opennew')) {						return fm.exec('opennew', [thash? thash : file.hash]);					}				}				return fm.request({					data   : {cmd  : 'open', target : thash || file.hash},					notify : {type : 'open', cnt : 1, hideCnt : true},					syncOnFail : true,					lazy : false				});			}		}				files = $.grep(files, function(file) { return file.mime != 'directory' ? true : false; });				// nothing to open or files and folders selected - do nothing		if (cnt != files.length) {			return dfrd.reject();		}				var doOpen = function() {			var wnd, target, getOnly;						try {				reg = new RegExp(fm.option('dispInlineRegex'), 'i');			} catch(e) {				reg = false;			}				// open files			link     = $('<a>').hide().appendTo($('body')),			html5dl  = (typeof link.get(0).download === 'string');			cnt = files.length;			while (cnt--) {				target = 'elf_open_window';				file = files[cnt];								if (!file.read) {					return dfrd.reject(['errOpen', file.name, 'errPerm']);				}								inline = (reg && file.mime.match(reg));				url = fm.openUrl(file.hash, !inline);				if (fm.UA.Mobile || !inline) {					if (html5dl) {						if (!inline) {							link.attr('download', file.name);						} else {							link.attr('target', '_blank');						}						link.attr('href', url).get(0).click();					} else {						wnd = window.open(url);						if (!wnd) {							return dfrd.reject('errPopup');						}					}				} else {					getOnly = (typeof opts.method === 'string' && opts.method.toLowerCase() === 'get');					if (!getOnly						&& url.indexOf(fm.options.url) === 0						&& fm.customData						&& Object.keys(fm.customData).length						// Since playback by POST request can not be done in Chrome, media allows GET request						&& !file.mime.match(/^(?:video|audio)/)					) {						// Send request as 'POST' method to hide custom data at location bar						url = '';					}					if (into === 'window') {						// set window size for image if set						imgW = winW = Math.round(2 * screen.availWidth / 3);						imgH = winH = Math.round(2 * screen.availHeight / 3);						if (parseInt(file.width) && parseInt(file.height)) {							imgW = parseInt(file.width);							imgH = parseInt(file.height);						} else if (file.dim) {							s = file.dim.split('x');							imgW = parseInt(s[0]);							imgH = parseInt(s[1]);						}						if (winW >= imgW && winH >= imgH) {							winW = imgW;							winH = imgH;						} else {							if ((imgW - winW) > (imgH - winH)) {								winH = Math.round(imgH * (winW / imgW));							} else {								winW = Math.round(imgW * (winH / imgH));							}						}						w = 'width='+winW+',height='+winH;						wnd = window.open(url, target, w + ',top=50,left=50,scrollbars=yes,resizable=yes,titlebar=no');					} else {						if (into === 'tabs') {							target = file.hash;						}						wnd = window.open('about:blank', target);					}										if (!wnd) {						return dfrd.reject('errPopup');					}										if (url === '') {						var form = document.createElement("form");						form.action = fm.options.url;						form.method = 'POST';						form.target = target;						form.style.display = 'none';						var params = Object.assign({}, fm.customData, {							cmd: 'file',							target: file.hash,							_t: file.ts || parseInt(+new Date()/1000)						});						$.each(params, function(key, val)						{							var input = document.createElement("input");							input.name = key;							input.value = val;							form.appendChild(input);						});												document.body.appendChild(form);						form.submit();					} else if (into !== 'window') {						wnd.location = url;					}					$(wnd).trigger('focus');				}			}			link.remove();			return dfrd.resolve(hashes);		};				if (cnt > 1) {			fm.confirm({				title: 'openMulti',				text : ['openMultiConfirm', cnt + ''],				accept : {					label : 'cmdopen',					callback : function() { doOpen(); }				},				cancel : {					label : 'btnCancel',					callback : function() { 						dfrd.reject();					}				},				buttons : (fm.getCommand('zipdl') && fm.isCommandEnabled('zipdl', fm.cwd().hash))? [					{						label : 'cmddownload',						callback : function() {							fm.exec('download', hashes);							dfrd.reject();						}					}				] : []			});		} else {			selAct = fm.storage('selectAction') || opts.selectAction;			if (selAct) {				$.each(selAct.split('/'), function() {					var cmdName = this.valueOf();					if (cmdName !== 'open' && (cmd = fm.getCommand(cmdName)) && cmd.enabled()) {						return false;					}					cmd = null;				});				if (cmd) {					return fm.exec(cmd.name);				}			}			doOpen();		}				return dfrd;	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/opendir.js *//** * @class  elFinder command "opendir" * Enter parent folder * * @author Naoki Sawada **/  elFinder.prototype.commands.opendir = function() {		this.alwaysEnabled = true;		this.getstate = function() {		var sel = this.fm.selected(),			cnt = sel.length,			wz;		if (cnt !== 1) {			return -1;		}		wz = this.fm.getUI('workzone');		return wz.hasClass('elfinder-search-result')? 0 : -1;	};		this.exec = function(hashes) {		var fm    = this.fm,			dfrd  = $.Deferred(),			files = this.files(hashes),			cnt   = files.length,			hash, pcheck = null;		if (!cnt || !files[0].phash) {			return dfrd.reject();		}		hash = files[0].phash;		fm.trigger('searchend', { noupdate: true });		fm.request({			data   : {cmd  : 'open', target : hash},			notify : {type : 'open', cnt : 1, hideCnt : true},			syncOnFail : false		});				return dfrd;	};};/* * File: /js/commands/opennew.js *//** * @class  elFinder command "opennew" * Open folder in new window * * @author Naoki Sawada **/  elFinder.prototype.commands.opennew = function() {		var fm = this.fm;	this.shortcuts = [{		pattern  : (typeof(fm.options.getFileCallback) === 'function'? 'shift+' : '') + 'ctrl+enter'	}];	this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length;				return cnt === 1 			? (sel[0].mime === 'directory' && sel[0].read? 0 : -1) 			: -1;	};		this.exec = function(hashes) {		var dfrd  = $.Deferred(),			files = this.files(hashes),			cnt   = files.length,			opts  = this.options,			file, loc, url, win;		// open folder to new tab (window)		if (cnt === 1 && (file = files[0]) && file.mime === 'directory') {			loc = window.location;			if (opts.url) {				url = opts.url;			} else {				url = loc.pathname;			}			if (opts.useOriginQuery) {				if (!url.match(/\?/)) {					url += loc.search;				} else if (loc.search) {					url += '&' + loc.search.substr(1);				}			}			url += '#elf_' + file.hash;			win = window.open(url, '_blank');			setTimeout(function() {				win.focus();			}, 1000);			return dfrd.resolve();		} else {			return dfrd.reject();		}	};};/* * File: /js/commands/paste.js *//** * @class  elFinder command "paste" * Paste filesfrom clipboard into directory. * If files pasted in its parent directory - files duplicates will created * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.paste = function() {		this.updateOnSelect  = false;		this.handlers = {		changeclipboard : function() { this.update(); }	};	this.shortcuts = [{		pattern     : 'ctrl+v shift+insert'	}];		this.getstate = function(dst) {		if (this._disabled) {			return -1;		}		if (dst) {			if (Array.isArray(dst)) {				if (dst.length != 1) {					return -1;				}				dst = this.fm.file(dst[0]);			}		} else {			dst = this.fm.cwd();		}		return this.fm.clipboard().length && dst.mime == 'directory' && dst.write ? 0 : -1;	};		this.exec = function(select, cOpts) {		var self   = this,			fm     = self.fm,			opts   = cOpts || {},			dst    = select ? this.files(select)[0] : fm.cwd(),			files  = fm.clipboard(),			cnt    = files.length,			cut    = cnt ? files[0].cut : false,			cmd    = opts._cmd? opts._cmd : (cut? 'move' : 'copy'),			error  = 'err' + cmd.charAt(0).toUpperCase() + cmd.substr(1),			fpaste = [],			fcopy  = [],			dfrd   = $.Deferred()				.fail(function(error) {					error && fm.error(error);				})				.always(function() {					fm.unlockfiles({files : $.map(files, function(f) { return f.hash; })});				}),			copy  = function(files) {				return files.length && fm._commands.duplicate					? fm.exec('duplicate', files)					: $.Deferred().resolve();			},			paste = function(files) {				var dfrd      = $.Deferred(),					existed   = [],					hashes  = {},					intersect = function(files, names) {						var ret = [], 							i   = files.length;						while (i--) {							$.inArray(files[i].name, names) !== -1 && ret.unshift(i);						}						return ret;					},					confirm   = function(ndx) {						var i    = existed[ndx],							file = files[i],							last = ndx == existed.length-1;						if (!file) {							return;						}						fm.confirm({							title  : fm.i18n(cmd + 'Files'),							text   : ['errExists', file.name, cmd === 'restore'? 'confirmRest' : 'confirmRepl'], 							all    : !last,							accept : {								label    : 'btnYes',								callback : function(all) {									!last && !all										? confirm(++ndx)										: paste(files);								}							},							reject : {								label    : 'btnNo',								callback : function(all) {									var i;									if (all) {										i = existed.length;										while (ndx < i--) {											files[existed[i]].remove = true;										}									} else {										files[existed[ndx]].remove = true;									}									!last && !all										? confirm(++ndx)										: paste(files);								}							},							cancel : {								label    : 'btnCancel',								callback : function() {									dfrd.resolve();								}							},							buttons : [								{									label : 'btnBackup',									callback : function(all) {										var i;										if (all) {											i = existed.length;											while (ndx < i--) {												files[existed[i]].rename = true;											}										} else {											files[existed[ndx]].rename = true;										}										!last && !all											? confirm(++ndx)											: paste(files);									}								}							]						});					},					valid     = function(names) {						var exists = {}, existedArr;						if (names) {							if (Array.isArray(names)) {								if (names.length) {									if (typeof names[0] == 'string') {										// elFinder <= 2.1.6 command `is` results										existed = intersect(files, names);									} else {										$.each(names, function(i, v) {											exists[v.name] = v.hash;										});										existed = intersect(files, $.map(exists, function(h, n) { return n; }));										$.each(files, function(i, file) {											if (exists[file.name]) {												hashes[exists[file.name]] = file.name;											}										});									}								}							} else {								existedArr = [];								existed = $.map(names, function(n) {									if (typeof n === 'string') {										return n;									} else {										// support to >=2.1.11 plugin Normalizer, Sanitizer										existedArr = existedArr.concat(n);										return false;									}								});								if (existedArr.length) {									existed = existed.concat(existedArr);								}								existed = intersect(files, existed);								hashes = names;							}						}						existed.length ? confirm(0) : paste(files);					},					paste     = function(selFiles) {						var renames = [],							files  = $.grep(selFiles, function(file) { 								if (file.rename) {									renames.push(file.name);								}								return !file.remove ? true : false;							}),							cnt    = files.length,							groups = {},							args   = [],							targets, reqData;						if (!cnt) {							return dfrd.resolve();						}						targets = $.map(files, function(f) { return f.hash; });												reqData = {cmd : 'paste', dst : dst.hash, targets : targets, cut : cut ? 1 : 0, renames : renames, hashes : hashes, suffix : fm.options.backupSuffix};						if (fm.api < 2.1) {							reqData.src = files[0].phash;						}												fm.request({								data   : reqData,								notify : {type : cmd, cnt : cnt},								navigate : { 									toast  : opts.noToast? {} : {										inbuffer : {msg: fm.i18n(['complete', fm.i18n('cmd' + cmd)]), action: {											cmd: 'open',											msg: 'cmdopendir',											data: [dst.hash],											done: 'select',											cwdNot: dst.hash										}}									}								}							})							.done(function(data) {								var dsts = {},									added = data.added && data.added.length? data.added : null;								if (cut && added) {									// undo/redo									$.each(files, function(i, f) {										var phash = f.phash,											srcHash = function(name) {												var hash;												$.each(added, function(i, f) {													if (f.name === name) {														hash = f.hash;														return false;													}												});												return hash;											},											shash = srcHash(f.name);										if (shash) {											if (dsts[phash]) {												dsts[phash].push(shash);											} else {												dsts[phash] = [ shash ];											}										}									});									if (Object.keys(dsts).length) {										data.undo = {											cmd : 'move',											callback : function() {												var reqs = [];												$.each(dsts, function(dst, targets) {													reqs.push(fm.request({														data : {cmd : 'paste', dst : dst, targets : targets, cut : 1},														notify : {type : 'undo', cnt : targets.length}													}));												});												return $.when.apply(null, reqs);											}										};										data.redo = {											cmd : 'move',											callback : function() {												return fm.request({													data : reqData,													notify : {type : 'redo', cnt : cnt}												});											}										};									}								}								dfrd.resolve(data);							})							.fail(function() {								dfrd.reject();							})							.always(function() {								fm.unlockfiles({files : files});							});					},					internames;				if (!fm.isCommandEnabled(self.name, dst.hash) || !files.length) {					return dfrd.resolve();				}								if (fm.oldAPI) {					paste(files);				} else {										if (!fm.option('copyOverwrite', dst.hash)) {						paste(files);					} else {						internames = $.map(files, function(f) { return f.name; });						dst.hash == fm.cwd().hash							? valid($.map(fm.files(), function(file) { return file.phash == dst.hash ? {hash: file.hash, name: file.name} : null; }))							: fm.request({								data : {cmd : 'ls', target : dst.hash, intersect : internames},								notify : {type : 'prepare', cnt : 1, hideCnt : true},								preventFail : true							})							.always(function(data) {								valid(data.list);							});					}				}								return dfrd;			},			parents, fparents;		if (!cnt || !dst || dst.mime != 'directory') {			return dfrd.reject();		}					if (!dst.write)	{			return dfrd.reject([error, files[0].name, 'errPerm']);		}				parents = fm.parents(dst.hash);				$.each(files, function(i, file) {			if (!file.read) {				return !dfrd.reject([error, file.name, 'errPerm']);			}						if (cut && file.locked) {				return !dfrd.reject(['errLocked', file.name]);			}						if ($.inArray(file.hash, parents) !== -1) {				return !dfrd.reject(['errCopyInItself', file.name]);			}						if (file.mime && file.mime !== 'directory' && ! fm.uploadMimeCheck(file.mime, dst.hash)) {				return !dfrd.reject([error, file.name, 'errUploadMime']);			}						fparents = fm.parents(file.hash);			fparents.pop();			if ($.inArray(dst.hash, fparents) !== -1) {								if ($.grep(fparents, function(h) { var d = fm.file(h); return d.phash == dst.hash && d.name == file.name ? true : false; }).length) {					return !dfrd.reject(['errReplByChild', file.name]);				}			}						if (file.phash == dst.hash) {				fcopy.push(file.hash);			} else {				fpaste.push({					hash  : file.hash,					phash : file.phash,					name  : file.name				});			}		});		if (dfrd.state() == 'rejected') {			return dfrd;		}		$.when(			copy(fcopy),			paste(fpaste)		)		.done(function(cr, pr) {			dfrd.resolve(pr && pr.undo? pr : void(0));		})		.fail(function() {			dfrd.reject();		})		.always(function() {			cut && fm.clipboard([]);		});				return dfrd;	};};/* * File: /js/commands/places.js *//** * @class  elFinder command "places" * Regist to Places * * @author Naoki Sawada **/elFinder.prototype.commands.places = function() {		var self   = this,	fm     = this.fm,	filter = function(hashes) {		return $.grep(self.files(hashes), function(f) { return f.mime == 'directory' ? true : false; });	},	places = null;		this.getstate = function(select) {		var sel = this.hashes(select),		cnt = sel.length;				return  places && cnt && cnt == filter(sel).length ? 0 : -1;	};		this.exec = function(hashes) {		var files = this.files(hashes);		places.trigger('regist', [ files ]);		return $.Deferred().resolve();	};		fm.one('load', function(){		places = fm.ui.places;	});};/* * File: /js/commands/preference.js *//** * @class  elFinder command "preference" * "Preference" dialog * * @author Naoki Sawada **/elFinder.prototype.commands.preference = function() {	var self    = this,		fm      = this.fm,		r       = 'replace',		tab     = '<li class="' + fm.res('class', 'tabstab') + ' elfinder-preference-tab-{id}"><a href="#'+fm.namespace+'-preference-{id}" id="'+fm.namespace+'-preference-tab-{id}" class="ui-tabs-anchor {class}">{title}</a></li>',		base    = $('<div class="ui-tabs ui-widget ui-widget-content ui-corner-all elfinder-preference">'), 		ul      = $('<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-top">'),		tabs    = $('<div class="elfinder-preference-tabs ui-tabs-panel ui-widget-content ui-corner-bottom"/>'),		sep     = '<div class="elfinder-preference-separator"/>',		selfUrl = $('base').length? document.location.href.replace(/#.*$/, '') : '',		selectTab = function(tab) {			$('#'+fm.namespace+'-preference-tab-'+tab).trigger('mouseover').trigger('click');			openTab = tab;		},		clTabActive = fm.res('class', 'tabsactive'),		build   = function() {			var cats = self.options.categories || {					'language' : ['language'],					'theme' : ['theme'],					'toolbar' : ['toolbarPref'],					'workspace' : ['iconSize','columnPref', 'selectAction', 'makefileTypes', 'useStoredEditor', 'editorMaximized', 'showHidden'],					'dialog' : ['autoFocusDialog'],					'selectionInfo' : ['infoItems', 'hashChecker'],					'reset' : ['clearBrowserData'],					'all' : true				},				forms = self.options.prefs || ['language', 'theme', 'toolbarPref', 'iconSize', 'columnPref', 'selectAction', 'makefileTypes', 'useStoredEditor', 'editorMaximized', 'showHidden', 'infoItems', 'hashChecker', 'autoFocusDialog', 'clearBrowserData'];						forms = fm.arrayFlip(forms, true);						if (fm.options.getFileCallback) {				delete forms.selectAction;			}						forms.language && (forms.language = (function() {				var langSel = $('<select/>').on('change', function() {						var lang = $(this).val();						fm.storage('lang', lang);						$('#'+fm.id).elfinder('reload');					}),					optTags = [],					langs = self.options.langs || {						ar: 'اللغة العربية',						bg: 'Български',						ca: 'Català',						cs: 'Čeština',						da: 'Dansk',						de: 'Deutsch',						el: 'Ελληνικά',						en: 'English',						es: 'Español',						fa: 'فارسی',						fo: 'Føroyskt',						fr: 'Français',						he: 'עברית',						hr: 'Hrvatski',						hu: 'Magyar',						id: 'Bahasa Indonesia',						it: 'Italiano',						ja: '日本語',						ko: '한국어',						nl: 'Nederlands',						no: 'Norsk',						pl: 'Polski',						pt_BR: 'Português',						ro: 'Română',						ru: 'Pусский',						si: 'සිංහල',						sk: 'Slovenčina',						sl: 'Slovenščina',						sr: 'Srpski',						sv: 'Svenska',						tr: 'Türkçe',						ug_CN: 'ئۇيغۇرچە',						uk: 'Український',						vi: 'Tiếng Việt',						zh_CN: '简体中文',						zh_TW: '正體中文'					};				$.each(langs, function(lang, name) {					optTags.push('<option value="'+lang+'">'+name+'</option>');				});				return langSel.append(optTags.join('')).val(fm.lang);			})());						forms.theme && (forms.theme = (function() {				if (!fm.options.themes || !Object.keys(fm.options.themes).length) {					return null;				}				var themeSel = $('<select/>').on('change', function() {						var theme = $(this).val();						fm.changeTheme(theme).storage('theme', theme);					}),					optTags = [],					tpl = {						image: '<img class="elfinder-preference-theme elfinder-preference-theme-image" src="$2" />',						link: '<a href="$1" target="_blank" title="$3">$2</a>',						data: '<dt>$1</dt><dd><span class="elfinder-preference-theme elfinder-preference-theme-$0">$2</span></dd>'					},					items = ['image', 'description', 'author', 'email', 'license'],					render = function(key, data) {					},					defBtn = $('<button class="ui-button ui-corner-all ui-widget elfinder-preference-theme-default"/>').text(fm.i18n('default')).on('click', function(e) {						themeSel.val('default').trigger('change');					}),					list = $('<div class="elfinder-reference-hide-taball"/>').on('click', 'button', function() {							var val = $(this).data('themeid')							themeSel.val(val).trigger('change');					});				themeSel.append('<option value="default">'+fm.i18n('default')+'</option>');				$.each(fm.options.themes, function(id, val) {					var opt = $('<option class="elfinder-theme-option-'+id+'" value="'+id+'">'+fm.i18n(id)+'</option>'),						dsc = $('<fieldset class="ui-widget ui-widget-content ui-corner-all elfinder-theme-list-'+id+'"><legend>'+fm.i18n(id)+'</legend><div><span class="elfinder-spinner"/></div></fieldset>'),						tm;					themeSel.append(opt);					list.append(dsc);					tm = setTimeout(function() {						dsc.find('span.elfinder-spinner').replaceWith(fm.i18n(['errRead', id]));					}, 10000);					fm.getTheme(id).always(function() {						tm && clearTimeout(tm);					}).done(function(data) {						var link, val = $(), dl = $('<dl/>');						link = data.link? tpl.link.replace(/\$1/g, data.link).replace(/\$3/g, fm.i18n('website')) : '$2';						if (data.name) {							opt.html(fm.i18n(data.name));						}						dsc.children('legend').html(link.replace(/\$2/g, fm.i18n(data.name) || id));						$.each(items, function(i, key) {							var t = tpl[key] || tpl.data,								elm;							if (data[key]) {								elm = t.replace(/\$0/g, fm.escape(key)).replace(/\$1/g, fm.i18n(key)).replace(/\$2/g, fm.i18n(data[key]));								if (key === 'image' && data.link) {									elm = $(elm).on('click', function() {										themeSel.val(id).trigger('change');									}).attr('title', fm.i18n('select'));								}								dl.append(elm);							}						});						val = val.add(dl);						val = val.add($('<div class="elfinder-preference-theme-btn"/>').append($('<button class="ui-button ui-corner-all ui-widget"/>').data('themeid', id).html(fm.i18n('select'))));						dsc.find('span.elfinder-spinner').replaceWith(val);					}).fail(function() {						dsc.find('span.elfinder-spinner').replaceWith(fm.i18n(['errRead', id]));					});				});				return $('<div/>').append(themeSel.val(fm.theme && fm.theme.id? fm.theme.id : 'default'), defBtn, list);			})());			forms.toolbarPref && (forms.toolbarPref = (function() {				var pnls = $.map(fm.options.uiOptions.toolbar, function(v) {						return $.isArray(v)? v : null;					}),					tags = [],					hides = fm.storage('toolbarhides') || {};				$.each(pnls, function() {					var cmd = this,						name = fm.i18n('cmd'+cmd);					if (name === 'cmd'+cmd) {						name = fm.i18n(cmd);					}					tags.push('<span class="elfinder-preference-toolbar-item"><label><input type="checkbox" value="'+cmd+'" '+(hides[cmd]? '' : 'checked')+'/>'+name+'</label></span>');				});				return $(tags.join(' ')).on('change', 'input', function() {					var v = $(this).val(),						o = $(this).is(':checked');					if (!o && !hides[v]) {						hides[v] = true;					} else if (o && hides[v]) {						delete hides[v];					}					fm.storage('toolbarhides', hides);					fm.trigger('toolbarpref');				});			})());						forms.iconSize && (forms.iconSize = (function() {				var max = fm.options.uiOptions.cwd.iconsView.sizeMax || 3,					size = fm.storage('iconsize') || 0,					sld = $('<div class="touch-punch"/>').slider({						classes: {							'ui-slider-handle': 'elfinder-tabstop',						},						value: size,						max: max,						slide: function(e, ui) {							fm.getUI('cwd').trigger('iconpref', {size: ui.value});						},						change: function(e, ui) {							fm.storage('iconsize', ui.value);						}					});				fm.getUI('cwd').on('iconpref', function(e, data) {					sld.slider('option', 'value', data.size);				});				return sld;			})());			forms.columnPref && (forms.columnPref = (function() {				var cols = fm.options.uiOptions.cwd.listView.columns,					tags = [],					hides = fm.storage('columnhides') || {};				$.each(cols, function() {					var key = this,						name = fm.getColumnName(key);					tags.push('<span class="elfinder-preference-column-item"><label><input type="checkbox" value="'+key+'" '+(hides[key]? '' : 'checked')+'/>'+name+'</label></span>');				});				return $(tags.join(' ')).on('change', 'input', function() {					var v = $(this).val(),						o = $(this).is(':checked');					if (!o && !hides[v]) {						hides[v] = true;					} else if (o && hides[v]) {						delete hides[v];					}					fm.storage('columnhides', hides);					fm.trigger('columnpref', { repaint: true });				});			})());						forms.selectAction && (forms.selectAction = (function() {				var actSel = $('<select/>').on('change', function() {						var act = $(this).val();						fm.storage('selectAction', act === 'default'? null : act);					}),					optTags = [],					acts = self.options.selectActions,					defAct = fm.getCommand('open').options.selectAction || 'open';								if ($.inArray(defAct, acts) === -1) {					acts.unshift(defAct);				}				$.each(acts, function(i, act) {					var names = $.map(act.split('/'), function(cmd) {						var name = fm.i18n('cmd'+cmd);						if (name === 'cmd'+cmd) {							name = fm.i18n(cmd);						}						return name;					});					optTags.push('<option value="'+act+'">'+names.join('/')+'</option>');				});				return actSel.append(optTags.join('')).val(fm.storage('selectAction') || defAct);			})());						forms.makefileTypes && (forms.makefileTypes = (function() {				var hides = fm.storage('mkfileHides') || {},					getTag = function() {						var tags = [];						// re-assign hides						hides = fm.storage('mkfileHides') || {};						$.each(fm.mimesCanMakeEmpty, function(mime, type) {							var name = fm.getCommand('mkfile').getTypeName(mime, type);							tags.push('<span class="elfinder-preference-column-item" title="'+fm.escape(name)+'"><label><input type="checkbox" value="'+mime+'" '+(hides[mime]? '' : 'checked')+'/>'+type+'</label></span>');						});						return tags.join(' ');					},					elm = $('<div/>').on('change', 'input', function() {						var v = $(this).val(),							o = $(this).is(':checked');						if (!o && !hides[v]) {							hides[v] = true;						} else if (o && hides[v]) {							delete hides[v];						}						fm.storage('mkfileHides', hides);						fm.trigger('canMakeEmptyFile');					}).append(getTag()),					add = $('<div/>').append(						$('<input type="text" placeholder="'+fm.i18n('typeOfTextfile')+'"/>').on('keydown', function(e) {							(e.keyCode === $.ui.keyCode.ENTER) && $(this).next().trigger('click');						}),						$('<button class="ui-button"/>').html(fm.i18n('add')).on('click', function() {							var input = $(this).prev(),								val = input.val(),								uiToast = fm.getUI('toast'),								err = function() {									uiToast.appendTo(input.closest('.ui-dialog'));									fm.toast({										msg: fm.i18n('errUsupportType'),										mode: 'warning',										onHidden: function() {											uiToast.children().length === 1 && uiToast.appendTo(fm.getUI());										}									});									input.trigger('focus');									return false;								},								tmpMimes;							if (!val.match(/\//)) {								val = fm.arrayFlip(fm.mimeTypes)[val];								if (!val) {									return err();								}								input.val(val);							}							if (!fm.mimeIsText(val) || !fm.mimeTypes[val]) {								return err();							}							fm.trigger('canMakeEmptyFile', {mimes: [val], unshift: true});							tmpMimes = {};							tmpMimes[val] = fm.mimeTypes[val];							fm.storage('mkfileTextMimes', Object.assign(tmpMimes, fm.storage('mkfileTextMimes') || {}));							input.val('');							uiToast.appendTo(input.closest('.ui-dialog'));							fm.toast({								msg: fm.i18n(['complete', val + ' (' + tmpMimes[val] + ')']),								onHidden: function() {									uiToast.children().length === 1 && uiToast.appendTo(fm.getUI());								}							});						}),						$('<button class="ui-button"/>').html(fm.i18n('reset')).on('click', function() {							fm.one('canMakeEmptyFile', {done: function() {								elm.empty().append(getTag());							}});							fm.trigger('canMakeEmptyFile', {resetTexts: true});						})					),					tm;				fm.bind('canMakeEmptyFile', {done: function(e) {					if (e.data && e.data.mimes && e.data.mimes.length) {						elm.empty().append(getTag());					}				}});				return $('<div/>').append(elm, add);			})());			forms.useStoredEditor && (forms.useStoredEditor = $('<input type="checkbox"/>').prop('checked', (function() {				var s = fm.storage('useStoredEditor');				return s? (s > 0) : fm.options.commandsOptions.edit.useStoredEditor;			})()).on('change', function(e) {				fm.storage('useStoredEditor', $(this).is(':checked')? 1 : -1);			}));			forms.editorMaximized && (forms.editorMaximized = $('<input type="checkbox"/>').prop('checked', (function() {				var s = fm.storage('editorMaximized');				return s? (s > 0) : fm.options.commandsOptions.edit.editorMaximized;			})()).on('change', function(e) {				fm.storage('editorMaximized', $(this).is(':checked')? 1 : -1);			}));			if (forms.showHidden) {				(function() {					var setTitle = function() {							var s = fm.storage('hide'),								t = [],								v;							if (s && s.items) {								$.each(s.items, function(h, n) {									t.push(fm.escape(n));								});							}							elms.prop('disabled', !t.length)[t.length? 'removeClass' : 'addClass']('ui-state-disabled');							v = t.length? t.join('\n') : '';							forms.showHidden.attr('title',v);							useTooltip && forms.showHidden.tooltip('option', 'content', v.replace(/\n/g, '<br>')).tooltip('close');						},						chk = $('<input type="checkbox"/>').prop('checked', (function() {							var s = fm.storage('hide');							return s && s.show;						})()).on('change', function(e) {							var o = {};							o[$(this).is(':checked')? 'show' : 'hide'] = true;							fm.exec('hide', void(0), o);						}),						btn = $('<button class="ui-button ui-corner-all ui-widget"/>').append(fm.i18n('reset')).on('click', function() {							fm.exec('hide', void(0), {reset: true});							$(this).parent().find('input:first').prop('checked', false);							setTitle();						}),						elms = $().add(chk).add(btn),						useTooltip;										forms.showHidden = $('<div/>').append(chk, btn);					fm.bind('hide', function(e) {						var d = e.data;						if (!d.opts || (!d.opts.show && !d.opts.hide)) {							setTitle();						}					});					if (fm.UA.Mobile && $.fn.tooltip) {						useTooltip = true;						forms.showHidden.tooltip({							classes: {								'ui-tooltip': 'elfinder-ui-tooltip ui-widget-shadow'							},							tooltipClass: 'elfinder-ui-tooltip ui-widget-shadow',							track: true						}).css('user-select', 'none');						btn.css('user-select', 'none');					}					setTitle();				})();			}						forms.infoItems && (forms.infoItems = (function() {				var items = fm.getCommand('info').items,					tags = [],					hides = fm.storage('infohides') || fm.arrayFlip(fm.options.commandsOptions.info.hideItems, true);				$.each(items, function() {					var key = this,						name = fm.i18n(key);					tags.push('<span class="elfinder-preference-info-item"><label><input type="checkbox" value="'+key+'" '+(hides[key]? '' : 'checked')+'/>'+name+'</label></span>');				});				return $(tags.join(' ')).on('change', 'input', function() {					var v = $(this).val(),						o = $(this).is(':checked');					if (!o && !hides[v]) {						hides[v] = true;					} else if (o && hides[v]) {						delete hides[v];					}					fm.storage('infohides', hides);					fm.trigger('infopref', { repaint: true });				});			})());						forms.hashChecker && fm.hashCheckers.length && (forms.hashChecker = (function() {				var tags = [],					enabled = fm.arrayFlip(fm.storage('hashchekcer') || fm.options.commandsOptions.info.showHashAlgorisms, true);				$.each(fm.hashCheckers, function() {					var cmd = this,						name = fm.i18n(cmd);					tags.push('<span class="elfinder-preference-hashchecker-item"><label><input type="checkbox" value="'+cmd+'" '+(enabled[cmd]? 'checked' : '')+'/>'+name+'</label></span>');				});				return $(tags.join(' ')).on('change', 'input', function() {					var v = $(this).val(),						o = $(this).is(':checked');					if (o) {						enabled[v] = true;					} else if (enabled[v]) {						delete enabled[v];					}					fm.storage('hashchekcer', $.grep(fm.hashCheckers, function(v) {						return enabled[v];					}));				});			})());			forms.autoFocusDialog && (forms.autoFocusDialog = $('<input type="checkbox"/>').prop('checked', (function() {				var s = fm.storage('autoFocusDialog');				return s? (s > 0) : fm.options.uiOptions.dialog.focusOnMouseOver;			})()).on('change', function(e) {				fm.storage('autoFocusDialog', $(this).is(':checked')? 1 : -1);			}));						forms.clearBrowserData && (forms.clearBrowserData = $('<button/>').text(fm.i18n('reset')).button().on('click', function(e) {				e.preventDefault();				fm.storage();				$('#'+fm.id).elfinder('reload');			}));						$.each(cats, function(id, prefs) {				var dls, found;				if (prefs === true) {					found = 1;				} else if (prefs) {					dls = $();					$.each(prefs, function(i, n) {						var f, title, chks = '', cbox;						if (f = forms[n]) {							found = 2;							title = fm.i18n(n);							cbox = $(f).filter('input[type="checkbox"]');							if (!cbox.length) {								cbox = $(f).find('input[type="checkbox"]');							}							if (cbox.length === 1) {								if (!cbox.attr('id')) {									cbox.attr('id', 'elfinder-preference-'+n+'-checkbox');								}								title = '<label for="'+cbox.attr('id')+'">'+title+'</label>';							} else if (cbox.length > 1) {								chks = ' elfinder-preference-checkboxes';							}							dls = dls.add($('<dt class="elfinder-preference-'+n+chks+'">'+title+'</dt>')).add($('<dd class="elfinder-preference-'+n+chks+'"/>').append(f));						}					});				}				if (found) {					ul.append(tab[r](/\{id\}/g, id)[r](/\{title\}/, fm.i18n(id))[r](/\{class\}/, openTab === id? 'elfinder-focus' : ''));					if (found === 2) {						tabs.append(							$('<div id="'+fm.namespace+'-preference-'+id+'" class="elfinder-preference-content"/>')							.hide()							.append($('<dl/>').append(dls))						);					}				}			});			ul.on('click', 'a', function(e) {				var t = $(e.target),					h = t.attr('href');				e.preventDefault();				e.stopPropagation();				ul.children().removeClass(clTabActive);				t.removeClass('ui-state-hover').parent().addClass(clTabActive);				if (h.match(/all$/)) {					tabs.addClass('elfinder-preference-taball').children().show();				} else {					tabs.removeClass('elfinder-preference-taball').children().hide();					$(h).show();				}			}).on('focus blur', 'a', function(e) {				$(this).parent().toggleClass('ui-state-focus', e.type === 'focusin');			}).on('mouseenter mouseleave', 'li', function(e) {				$(this).toggleClass('ui-state-hover', e.type === 'mouseenter');			});			tabs.find('a,input,select,button').addClass('elfinder-tabstop');			base.append(ul, tabs);			dialog = self.fmDialog(base, {				title : self.title,				width : self.options.width || 600,				height: self.options.height || 400,				maxWidth: 'window',				maxHeight: 'window',				autoOpen : false,				destroyOnClose : false,				allowMinimize : false,				open : function() {					openTab && selectTab(openTab);					openTab = null;				},				resize : function() {					tabs.height(dialog.height() - ul.outerHeight(true) - (tabs.outerHeight(true) - tabs.height()) - 5);				}			})			.on('click', function(e) {				e.stopPropagation();			})			.css({				overflow: 'hidden'			});			dialog.closest('.ui-dialog')			.css({				overflow: 'hidden'			})			.addClass('elfinder-bg-translucent');						openTab = 'all';		},		dialog, openTab;	this.shortcuts = [{		pattern     : 'ctrl+comma',		description : this.title	}];	this.alwaysEnabled  = true;		this.getstate = function() {		return 0;	};		this.exec = function(sel, cOpts) {		!dialog && build();		if (cOpts) {			if (cOpts.tab) {				selectTab(cOpts.tab);			} else if (cOpts._currentType === 'cwd') {				selectTab('workspace');			}		}		dialog.elfinderdialog('open');		return $.Deferred().resolve();	};};/* * File: /js/commands/quicklook.js *//** * @class  elFinder command "quicklook" * Fast preview for some files types * * @author Dmitry (dio) Levashov **/(elFinder.prototype.commands.quicklook = function() {		var self       = this,		fm         = self.fm,		/**		 * window closed state		 *		 * @type Number		 **/		closed     = 0,		/**		 * window animated state		 *		 * @type Number		 **/		animated   = 1,		/**		 * window opened state		 *		 * @type Number		 **/		opened     = 2,		/**		 * window docked state		 *		 * @type Number		 **/		docked     = 3,		/**		 * window docked and hidden state		 *		 * @type Number		 **/		dockedhidden = 4,		/**		 * window state		 *		 * @type Number		 **/		state      = closed,		/**		 * Event name of update		 * for fix conflicts with Prototype.JS		 * 		 * `@see https://github.com/Studio-42/elFinder/pull/2346		 * @type String		 **/		evUpdate = Element.update? 'quicklookupdate' : 'update',		/**		 * navbar icon class		 *		 * @type String		 **/		navicon    = 'elfinder-quicklook-navbar-icon',		/**		 * navbar "fullscreen" icon class		 *		 * @type String		 **/		fullscreen = 'elfinder-quicklook-fullscreen',		/**		 * info wrapper class		 * 		 * @type String		 */		infocls    = 'elfinder-quicklook-info-wrapper',		/**		 * Triger keydown/keypress event with left/right arrow key code		 *		 * @param  Number  left/right arrow key code		 * @return void		 **/		navtrigger = function(code) {			$(document).trigger($.Event('keydown', { keyCode: code, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));		},		/**		 * Return css for closed window		 *		 * @param  jQuery  file node in cwd		 * @return void		 **/		closedCss = function(node) {			var elf = fm.getUI().offset(),				base = (function() {					var target = node.find('.elfinder-cwd-file-wrapper');					return target.length? target : node;				})(),				baseOffset = base.offset() || { top: 0, left: 0 };			return {				opacity : 0,				width   : base.width(),				height  : base.height() - 30,				top     : baseOffset.top - elf.top,				left    : baseOffset.left  - elf.left			};		},		/**		 * Return css for opened window		 *		 * @return void		 **/		openedCss = function() {			var contain = self.options.contain,				win = contain? fm.getUI() : $(window),				elf = fm.getUI().offset(),				w = Math.min(width, win.width()-10),				h = Math.min(height, win.height()-80);			return {				opacity : 1,				width  : w,				height : h,				top    : parseInt((win.height() - h - 60) / 2 + (contain? 0 : win.scrollTop() - elf.top)),				left   : parseInt((win.width() - w) / 2 + (contain? 0 : win.scrollLeft() - elf.left))			};		},				mediaNode = {},		support = function(codec, name) {			var node  = name || codec.substr(0, codec.indexOf('/')),				media = mediaNode[node]? mediaNode[node] : (mediaNode[node] = document.createElement(node)),				value = false;						try {				value = media.canPlayType && media.canPlayType(codec);			} catch(e) {}						return (value && value !== '' && value != 'no')? true : false;		},				platformWin = (window.navigator.platform.indexOf('Win') != -1),				/**		 * Opened window width (from config)		 *		 * @type Number		 **/		width, 		/**		 * Opened window height (from config)		 *		 * @type Number		 **/		height, 		/**		 * Previous style before docked		 *		 * @type String		 **/		prevStyle,		/**		 * elFinder node		 *		 * @type jQuery		 **/		parent, 		/**		 * elFinder current directory node		 *		 * @type jQuery		 **/		cwd, 		/**		 * Current directory hash		 *		 * @type String		 **/		cwdHash,		dockEnabled = false,		navdrag = false,		navmove = false,		navtm   = null,		leftKey = $.ui.keyCode.LEFT,		rightKey = $.ui.keyCode.RIGHT,		coverEv = 'mousemove touchstart ' + ('onwheel' in document? 'wheel' : 'onmousewheel' in document? 'mousewheel' : 'DOMMouseScroll'),		title   = $('<span class="elfinder-dialog-title elfinder-quicklook-title"/>'),		icon    = $('<div/>'),		info    = $('<div class="elfinder-quicklook-info"/>'),//.hide(),		cover   = $('<div class="ui-front elfinder-quicklook-cover"/>'),		fsicon  = $('<div class="'+navicon+' '+navicon+'-fullscreen"/>')			.on('click touchstart', function(e) {				if (navmove) {					return;				}								var win     = self.window,					full    = win.hasClass(fullscreen),					$window = $(window),					resize  = function() { self.preview.trigger('changesize'); };									e.stopPropagation();				e.preventDefault();								if (full) {					navStyle = '';					navShow();					win.toggleClass(fullscreen)					.css(win.data('position'));					$window.trigger(self.resize).off(self.resize, resize);					navbar.off('mouseenter mouseleave');					cover.off(coverEv);				} else {					win.toggleClass(fullscreen)					.data('position', {						left   : win.css('left'), 						top    : win.css('top'), 						width  : win.width(), 						height : win.height(),						display: 'block'					})					.removeAttr('style');					$(window).on(self.resize, resize)					.trigger(self.resize);					cover.on(coverEv, function(e) {						if (! navdrag) {							if (e.type === 'mousemove' || e.type === 'touchstart') {								navShow();								navtm = setTimeout(function() {									if (fm.UA.Mobile || navbar.parent().find('.elfinder-quicklook-navbar:hover').length < 1) {										navbar.fadeOut('slow', function() {											cover.show();										});									}								}, 3000);							}							if (cover.is(':visible')) {								coverHide();								cover.data('tm', setTimeout(function() {									cover.show();								}, 3000));							}						}					}).show().trigger('mousemove');										navbar.on('mouseenter mouseleave', function(e) {						if (! navdrag) {							if (e.type === 'mouseenter') {								navShow();							} else {								cover.trigger('mousemove');							}						}					});				}				if (fm.zIndex) {					win.css('z-index', fm.zIndex + 1);				}				if (fm.UA.Mobile) {					navbar.attr('style', navStyle);				} else {					navbar.attr('style', navStyle).draggable(full ? 'destroy' : {						start: function() {							navdrag = true;							navmove = true;							cover.show();							navShow();						},						stop: function() {							navdrag = false;							navStyle = self.navbar.attr('style');							requestAnimationFrame(function() {								navmove = false;							});						}					});				}				$(this).toggleClass(navicon+'-fullscreen-off');				var collection = win;				if (parent.is('.ui-resizable')) {					collection = collection.add(parent);				}				collection.resizable(full ? 'enable' : 'disable').removeClass('ui-state-disabled');				win.trigger('viewchange');			}		),				updateOnSel = function() {			self.update(void(0), (function() {				var fm = self.fm,					files = fm.selectedFiles(),					cnt = files.length,					inDock = self.docked(),					getInfo = function() {						var ts = 0;						$.each(files, function(i, f) {							var t = parseInt(f.ts);							if (ts >= 0) {								if (t > ts) {									ts = t;								}							} else {								ts = 'unknown';							}						});						return {							hash : files[0].hash  + '/' + (+new Date()),							name : fm.i18n('items') + ': ' + cnt,							mime : 'group',							size : spinner,							ts   : ts,							files : $.map(files, function(f) { return f.hash; }),							getSize : true						};					};				if (! cnt) {					cnt = 1;					files = [fm.cwd()];				}				return (cnt === 1)? files[0] : getInfo();			})());		},				navShow = function() {			if (self.window.hasClass(fullscreen)) {				navtm && clearTimeout(navtm);				navtm = null;				// if use `show()` it make infinite loop with old jQuery (jQuery/jQuery UI: 1.8.0/1.9.0)				// see #1478 https://github.com/Studio-42/elFinder/issues/1478				navbar.stop(true, true).css('display', 'block');				coverHide();			}		},				coverHide = function() {			cover.data('tm') && clearTimeout(cover.data('tm'));			cover.removeData('tm');			cover.hide();		},					prev = $('<div class="'+navicon+' '+navicon+'-prev"/>').on('click touchstart', function(e) { ! navmove && navtrigger(leftKey); return false; }),		next = $('<div class="'+navicon+' '+navicon+'-next"/>').on('click touchstart', function(e) { ! navmove && navtrigger(rightKey); return false; }),		navbar  = $('<div class="elfinder-quicklook-navbar"/>')			.append(prev)			.append(fsicon)			.append(next)			.append('<div class="elfinder-quicklook-navbar-separator"/>')			.append($('<div class="'+navicon+' '+navicon+'-close"/>').on('click touchstart', function(e) { ! navmove && self.window.trigger('close'); return false; }))		,		titleClose = $('<span class="ui-front ui-icon elfinder-icon-close ui-icon-closethick"/>').on('mousedown', function(e) {			e.stopPropagation();			self.window.trigger('close');		}),		titleDock = $('<span class="ui-front ui-icon elfinder-icon-minimize ui-icon-minusthick"/>').on('mousedown', function(e) {			e.stopPropagation();			if (! self.docked()) {				self.window.trigger('navdockin');			} else {				self.window.trigger('navdockout');			}		}),		spinner = '<span class="elfinder-spinner-text">' + fm.i18n('calc') + '</span>' + '<span class="elfinder-spinner"/>',		navStyle = '',		init = true,		dockHeight,	getSize, tm4cwd, dockedNode, selectTm;	this.cover = cover;	this.evUpdate = evUpdate;	(this.navbar = navbar)._show = navShow;	this.resize = 'resize.'+fm.namespace;	this.info = $('<div/>').addClass(infocls)		.append(icon)		.append(info);	this.autoPlay = function() {		if (self.opened()) {			return !! self.options[self.docked()? 'dockAutoplay' : 'autoplay'];		}		return false;	};	this.preview = $('<div class="elfinder-quicklook-preview ui-helper-clearfix"/>')		// clean info/icon		.on('change', function() {			navShow();			navbar.attr('style', navStyle);			self.docked() && navbar.hide();			self.preview.attr('style', '').removeClass('elfinder-overflow-auto');			self.info.attr('style', '').hide();			self.cover.removeClass('elfinder-quicklook-coverbg');			icon.removeAttr('class').attr('style', '');			info.html('');		})		// update info/icon		.on(evUpdate, function(e) {			var preview = self.preview,				file    = e.file,				tpl     = '<div class="elfinder-quicklook-info-data">{value}</div>',				update  = function() {					var win = self.window.css('overflow', 'hidden');					name = fm.escape(file.i18 || file.name);					!file.read && e.stopImmediatePropagation();					self.window.data('hash', file.hash);					self.preview.off('changesize').trigger('change').children().remove();					title.html(name);										prev.css('visibility', '');					next.css('visibility', '');					if (file.hash === fm.cwdId2Hash(cwd.find('[id]:not(.elfinder-cwd-parent):first').attr('id'))) {						prev.css('visibility', 'hidden');					}					if (file.hash === fm.cwdId2Hash(cwd.find('[id]:last').attr('id'))) {						next.css('visibility', 'hidden');					}										if (file.mime === 'directory') {						getSizeHashes = [ file.hash ];					} else if (file.mime === 'group' && file.getSize) {						getSizeHashes = file.files;					}										info.html(						tpl.replace(/\{value\}/, name)						+ tpl.replace(/\{value\}/, fm.mime2kind(file))						+ tpl.replace(/\{value\}/, getSizeHashes.length ? spinner : fm.formatSize(file.size))						+ tpl.replace(/\{value\}/, fm.i18n('modify')+': '+ fm.formatDate(file))					);										if (getSizeHashes.length) {						getSize = fm.getSize(getSizeHashes).done(function(data) {							info.find('span.elfinder-spinner').parent().html(data.formated);						}).fail(function() {							info.find('span.elfinder-spinner').parent().html(fm.i18n('unknown'));						}).always(function() {							getSize = null;						});						getSize._hash = file.hash;					}										icon.addClass('elfinder-cwd-icon ui-corner-all '+fm.mime2class(file.mime));										if (file.icon) {						icon.css(fm.getIconStyle(file, true));					}										self.info.attr('class', infocls);					if (file.csscls) {						self.info.addClass(file.csscls);					}						if (file.read && (tmb = fm.tmb(file))) {						$('<img/>')							.hide()							.appendTo(self.preview)							.on('load', function() {								icon.addClass(tmb.className).css('background-image', "url('"+tmb.url+"')");								$(this).remove();							})							.attr('src', tmb.url);					}					self.info.delay(100).fadeIn(10);					if (self.window.hasClass(fullscreen)) {						cover.trigger('mousemove');					}					win.css('overflow', '');				},				tmb, name, getSizeHashes = [];			if (file && ! Object.keys(file).length) {				file = fm.cwd();			}			if (file && getSize && getSize.state() === 'pending' && getSize._hash !== file.hash) {				getSize.reject();			}			if (file && (e.forceUpdate || self.window.data('hash') !== file.hash)) {				update();			} else { 				e.stopImmediatePropagation();			}		});	this.window = $('<div class="ui-front ui-helper-reset ui-widget elfinder-quicklook touch-punch" style="position:absolute"/>')		.hide()		.addClass(fm.UA.Touch? 'elfinder-touch' : '')		.on('click', function(e) {			var win = this;			e.stopPropagation();			if (state === opened) {				requestAnimationFrame(function() {					state === opened && fm.toFront(win);				});			}		})		.append(			$('<div class="ui-dialog-titlebar ui-widget-header ui-corner-top ui-helper-clearfix elfinder-quicklook-titlebar"/>')			.append(				$('<span class="ui-widget-header ui-dialog-titlebar-close ui-corner-all elfinder-titlebar-button elfinder-quicklook-titlebar-icon'+(platformWin? ' elfinder-titlebar-button-right' : '')+'"/>').append(					titleClose, titleDock				),				title			),			this.preview,			self.info.hide(),			cover.hide(),			navbar		)		.draggable({handle : 'div.elfinder-quicklook-titlebar'})		.on('open', function(e, clcss) {			var win  = self.window, 				file = self.value,				node = fm.getUI('cwd'),				open = function(status) {					state = status;					self.update(1, self.value);					self.change();					win.trigger('resize.' + fm.namespace);				};			if (!init && state === closed) {				if (file && file.hash !== cwdHash) {					node = $('#'+fm.cwdHash2Id(file.hash.split('/', 2)[0]));				}				navStyle = '';				navbar.attr('style', '');				state = animated;				node.trigger('scrolltoview');				coverHide();				win.css(clcss || closedCss(node))					.show()					.animate(openedCss(), 550, function() {						open(opened);						navShow();					});				fm.toFront(win);			} else if (state === dockedhidden) {				fm.getUI('navdock').data('addNode')(dockedNode);				open(docked);				self.preview.trigger('changesize');				fm.storage('previewDocked', '1');				if (fm.getUI('navdock').width() === 0) {					win.trigger('navdockout');				}			}		})		.on('close', function(e, dfd) {			var win     = self.window,				preview = self.preview.trigger('change'),				file    = self.value,				hash    = (win.data('hash') || '').split('/', 2)[0],				close   = function(status, winhide) {					state = status;					winhide && fm.toHide(win);					preview.children().remove();					self.update(0, self.value);					win.data('hash', '');					dfd && dfd.resolve();				},				node;							if (self.opened()) {				getSize && getSize.state() === 'pending' && getSize.reject();				if (! self.docked()) {					state = animated;					win.hasClass(fullscreen) && fsicon.click();					(hash && (node = cwd.find('#'+hash)).length)						? win.animate(closedCss(node), 500, function() { close(closed, true); })						: close(closed, true);				} else {					dockedNode = fm.getUI('navdock').data('removeNode')(self.window.attr('id'), 'detach');					close(dockedhidden);					fm.storage('previewDocked', '2');				}			}		})		.on('navdockin', function(e, data) {			var w      = self.window,				box    = fm.getUI('navdock'),				height = dockHeight || box.width(),				opts   = data || {};						if (init) {				opts.init = true;			}			state = docked;			prevStyle = w.attr('style');			w.toggleClass('ui-front').removeClass('ui-widget').draggable('disable').resizable('disable').removeAttr('style').css({				width: '100%',				height: height,				boxSizing: 'border-box',				paddingBottom: 0,				zIndex: 'unset'			});			navbar.hide();			titleDock.toggleClass('ui-icon-plusthick ui-icon-minusthick elfinder-icon-full elfinder-icon-minimize');						fm.toHide(w, true);			box.data('addNode')(w, opts);						self.preview.trigger('changesize');						fm.storage('previewDocked', '1');		})		.on('navdockout', function(e) {			var w   = self.window,				box = fm.getUI('navdock'),				dfd = $.Deferred(),				clcss = closedCss(self.preview);						dockHeight = w.outerHeight();			box.data('removeNode')(w.attr('id'), fm.getUI());			w.toggleClass('ui-front').addClass('ui-widget').draggable('enable').resizable('enable').attr('style', prevStyle);			titleDock.toggleClass('ui-icon-plusthick ui-icon-minusthick elfinder-icon-full elfinder-icon-minimize');						state = closed;			w.trigger('open', clcss);						fm.storage('previewDocked', '0');		})		.on('resize.' + fm.namespace, function() {			self.preview.trigger('changesize'); 		});	/**	 * This command cannot be disable by backend	 *	 * @type Boolean	 **/	this.alwaysEnabled = true;		/**	 * Selected file	 *	 * @type Object	 **/	this.value = null;		this.handlers = {		// save selected file		select : function(e, d) {			selectTm && cancelAnimationFrame(selectTm);			if (! e.data || ! e.data.selected || ! e.data.selected.length) {				selectTm = requestAnimationFrame(function() {					self.opened() && updateOnSel();				});			} else {				self.opened() && updateOnSel();			}		},		error  : function() { self.window.is(':visible') && self.window.trigger('close'); },		'searchshow searchhide' : function() { this.opened() && this.window.trigger('close'); },		navbarshow : function() {			requestAnimationFrame(function() {				self.docked() && self.preview.trigger('changesize');			});		},		destroy : function() { self.window.remove(); }	};		this.shortcuts = [{		pattern     : 'space'	}];		this.support = {		audio : {			ogg : support('audio/ogg;'),			webm: support('audio/webm;'),			mp3 : support('audio/mpeg;'),			wav : support('audio/wav;'),			m4a : support('audio/mp4;') || support('audio/x-m4a;') || support('audio/aac;'),			flac: support('audio/flac;'),			amr : support('audio/amr;')		},		video : {			ogg  : support('video/ogg;'),			webm : support('video/webm;'),			mp4  : support('video/mp4;'),			mkv  : support('video/x-matroska;') || support('video/webm;'),			'3gp': support('video/3gpp;') || support('video/mp4;'), // try as mp4			m3u8 : support('application/x-mpegURL', 'video') || support('application/vnd.apple.mpegURL', 'video'),			mpd  : support('application/dash+xml', 'video')		}	};	// for GC	mediaNode = {};		/**	 * Return true if quickLoock window is hiddenReturn true if quickLoock window is visible and not animated	 *	 * @return Boolean	 **/	this.closed = function() {		return (state == closed || state == dockedhidden);	};		/**	 * Return true if quickLoock window is visible and not animated	 *	 * @return Boolean	 **/	this.opened = function() {		return state == opened || state == docked;	};		/**	 * Return true if quickLoock window is in NavDock	 *	 * @return Boolean	 **/	this.docked = function() {		return state == docked;	};		/**	 * Adds an integration into help dialog.	 *	 * @param Object opts  options	 */	this.addIntegration = function(opts) {		requestAnimationFrame(function() {			fm.trigger('helpIntegration', Object.assign({cmd: 'quicklook'}, opts));		});	};	/**	 * Init command.	 * Add default plugins and init other plugins	 *	 * @return Object	 **/	this.init = function() {		var o       = this.options, 			win     = this.window,			preview = this.preview,			i, p, cwdDispInlineRegex;				width  = o.width  > 0 ? parseInt(o.width)  : 450;			height = o.height > 0 ? parseInt(o.height) : 300;		if (o.dockHeight !== 'auto') {			dockHeight = parseInt(o.dockHeight);			if (! dockHeight) {				dockHeight = void(0);			}		}		fm.one('load', function() {						dockEnabled = fm.getUI('navdock').data('dockEnabled');						! dockEnabled && titleDock.hide();						parent = fm.getUI();			cwd    = fm.getUI('cwd');			if (fm.zIndex) {				win.css('z-index', fm.zIndex + 1);			}						win.appendTo(parent);						// close window on escape			$(document).on('keydown.'+fm.namespace, function(e) {				e.keyCode == $.ui.keyCode.ESCAPE && self.opened() && ! self.docked() && win.hasClass('elfinder-frontmost') && win.trigger('close');			});						win.resizable({ 				handles   : 'se', 				minWidth  : 350, 				minHeight : 120, 				resize    : function() { 					// use another event to avoid recursion in fullscreen mode					// may be there is clever solution, but i cant find it :(					preview.trigger('changesize'); 				}			});						self.change(function() {				if (self.opened()) {					if (self.value) {						if (self.value.tmb && self.value.tmb == 1) {							// try re-get file object							self.value = Object.assign({}, fm.file(self.value.hash));						}						preview.trigger($.Event(evUpdate, {file : self.value}));					}				}			});						preview.on(evUpdate, function(e) {				var file, hash, serach;								if (file = e.file) {					hash = file.hash;					serach = (fm.searchStatus.mixed && fm.searchStatus.state > 1);									if (file.mime !== 'directory') {						if (parseInt(file.size) || file.mime.match(o.mimeRegexNotEmptyCheck)) {							// set current dispInlineRegex							self.dispInlineRegex = cwdDispInlineRegex;							if (serach || fm.optionsByHashes[hash]) {								try {									self.dispInlineRegex = new RegExp(fm.option('dispInlineRegex', hash), 'i');								} catch(e) {									try {										self.dispInlineRegex = new RegExp(!fm.isRoot(file)? fm.option('dispInlineRegex', file.phash) : fm.options.dispInlineRegex, 'i');									} catch(e) {										self.dispInlineRegex = /^$/;									}								}							}						} else {							//  do not preview of file that size = 0							e.stopImmediatePropagation();						}					} else {						self.dispInlineRegex = /^$/;					}										self.info.show();				} else {					e.stopImmediatePropagation();				}			});			$.each(fm.commands.quicklook.plugins || [], function(i, plugin) {				if (typeof(plugin) == 'function') {					new plugin(self);				}			});		}).one('open', function() {			var dock = Number(fm.storage('previewDocked') || o.docked),				win;			if (dockEnabled && dock >= 1) {				win = self.window;				self.exec();				win.trigger('navdockin', { init : true });				if (dock === 2) {					win.trigger('close');				} else {					self.update(void(0), fm.cwd());					self.change();				}			}			init = false;		}).bind('open', function() {			cwdHash = fm.cwd().hash;			self.value = fm.cwd();			// set current volume dispInlineRegex			try {				cwdDispInlineRegex = new RegExp(fm.option('dispInlineRegex'), 'i');			} catch(e) {				cwdDispInlineRegex = /^$/;			}		}).bind('change', function(e) {			if (e.data && e.data.changed && self.opened()) {				$.each(e.data.changed, function() {					if (self.window.data('hash') === this.hash) {						self.window.data('hash', null);						self.preview.trigger(evUpdate);						return false;					}				});			}		}).bind('navdockresizestart navdockresizestop', function(e) {			cover[e.type === 'navdockresizestart'? 'show' : 'hide']();		});	};		this.getstate = function() {		return self.opened()? 1 : 0;	};		this.exec = function() {		self.closed() && updateOnSel();		self.enabled() && self.window.trigger(self.opened() ? 'close' : 'open');		return $.Deferred().resolve();	};	this.hideinfo = function() {		this.info.stop(true, true).hide();	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/quicklook.plugins.js */elFinder.prototype.commands.quicklook.plugins = [		/**	 * Images preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var mimes   = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'image/x-ms-bmp'],			preview = ql.preview,			WebP, flipMime;				// webp support		WebP = new Image();		WebP.onload = WebP.onerror = function() {			if (WebP.height == 2) {				mimes.push('image/webp');			}		};		WebP.src='data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';				// what kind of images we can display		$.each(navigator.mimeTypes, function(i, o) {			var mime = o.type;						if (mime.indexOf('image/') === 0 && $.inArray(mime, mimes)) {				mimes.push(mime);			} 		});					preview.on(ql.evUpdate, function(e) {			var fm   = ql.fm,				file = e.file,				showed = false,				dimreq = null,				setdim  = function(dim) {					var rfile = fm.file(file.hash);					rfile.width = dim[0];					rfile.height = dim[1];				},				show = function() {					var elm, varelm, memSize, width, height, prop;										dimreq && dimreq.state && dimreq.state() === 'pending' && dimreq.reject();					if (showed) {						return;					}					showed = true;										elm = img.get(0);					memSize = file.width && file.height? {w: file.width, h: file.height} : (elm.naturalWidth? null : {w: img.width(), h: img.height()});									memSize && img.removeAttr('width').removeAttr('height');										width  = file.width || elm.naturalWidth || elm.width || img.width();					height = file.height || elm.naturalHeight || elm.height || img.height();					if (!file.width || !file.height) {						setdim([width, height]);					}										memSize && img.width(memSize.w).height(memSize.h);					prop = (width/height).toFixed(2);					preview.on('changesize', function() {						var pw = parseInt(preview.width()),							ph = parseInt(preview.height()),							w, h;											if (prop < (pw/ph).toFixed(2)) {							h = ph;							w = Math.floor(h * prop);						} else {							w = pw;							h = Math.floor(w/prop);						}						img.width(w).height(h).css('margin-top', h < ph ? Math.floor((ph - h)/2) : 0);										})					.trigger('changesize');										//show image					img.fadeIn(100);				},				hideInfo = function() {					loading.remove();					// hide info/icon					ql.hideinfo();				},				url, img, loading, m;			if (!flipMime) {				flipMime = fm.arrayFlip(mimes);			}			if (flipMime[file.mime] && ql.dispInlineRegex.test(file.mime)) {				// this is our file - stop event propagation				e.stopImmediatePropagation();				loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));				url = fm.openUrl(file.hash);								img = $('<img/>')					.hide()					.appendTo(preview)					.on('load', function() {						hideInfo();						show();					})					.on('error', function() {						loading.remove();					})					.attr('src', url);								if (file.width && file.height) {					show();				} else if (file.size > (ql.options.getDimThreshold || 0)) {					dimreq = fm.request({						data : {cmd : 'dim', target : file.hash},						preventDefault : true					})					.done(function(data) {						if (data.dim) {							var dim = data.dim.split('x');							file.width = dim[0];							file.height = dim[1];							setdim(dim);							show();						}					});				}			}					});	},		/**	 * PSD(Adobe Photoshop data) preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = fm.arrayFlip(['image/vnd.adobe.photoshop', 'image/x-photoshop']),			preview = ql.preview,			load    = function(url, img, loading) {				try {					fm.replaceXhrSend();					PSD.fromURL(url).then(function(psd) {						var prop;						img.attr('src', psd.image.toBase64());						requestAnimationFrame(function() {							prop = (img.width()/img.height()).toFixed(2);							preview.on('changesize', function() {								var pw = parseInt(preview.width()),									ph = parseInt(preview.height()),									w, h;															if (prop < (pw/ph).toFixed(2)) {									h = ph;									w = Math.floor(h * prop);								} else {									w = pw;									h = Math.floor(w/prop);								}								img.width(w).height(h).css('margin-top', h < ph ? Math.floor((ph - h)/2) : 0);							}).trigger('changesize');														loading.remove();							// hide info/icon							ql.hideinfo();							//show image							img.fadeIn(100);						});					}, function() {						loading.remove();						img.remove();					});					fm.restoreXhrSend();				} catch(e) {					fm.restoreXhrSend();					loading.remove();					img.remove();				}			},			PSD;				preview.on(ql.evUpdate, function(e) {			var file = e.file,				url, img, loading, m,				_define, _require;			if (mimes[file.mime] && fm.options.cdns.psd && ! fm.UA.ltIE10 && ql.dispInlineRegex.test(file.mime)) {				// this is our file - stop event propagation				e.stopImmediatePropagation();				loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));				url = fm.openUrl(file.hash);				if (!fm.isSameOrigin(url)) {					url = fm.openUrl(file.hash, true);				}				img = $('<img/>').hide().appendTo(preview);								if (PSD) {					load(url, img, loading);				} else {					_define = window.define;					_require = window.require;					window.require = null;					window.define = null;					fm.loadScript(						[ fm.options.cdns.psd ],						function() {							PSD = require('psd');							_define? (window.define = _define) : (delete window.define);							_require? (window.require = _require) : (delete window.require);							load(url, img, loading);						}					);				}			}		});	},		/**	 * HTML preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = fm.arrayFlip(['text/html', 'application/xhtml+xml']),			preview = ql.preview;					preview.on(ql.evUpdate, function(e) {			var file = e.file, jqxhr, loading;						if (mimes[file.mime] && ql.dispInlineRegex.test(file.mime) && (!ql.options.getSizeMax || file.size <= ql.options.getSizeMax)) {				e.stopImmediatePropagation();				loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));				// stop loading on change file if not loaded yet				preview.one('change', function() {					jqxhr.state() == 'pending' && jqxhr.reject();				}).addClass('elfinder-overflow-auto');								jqxhr = fm.request({					data           : {cmd : 'get', target : file.hash, conv : 1, _t : file.ts},					options        : {type: 'get', cache : true},					preventDefault : true				})				.done(function(data) {					ql.hideinfo();					var doc = $('<iframe class="elfinder-quicklook-preview-html"/>').appendTo(preview)[0].contentWindow.document;					doc.open();					doc.write(data.content);					doc.close();				})				.always(function() {					loading.remove();				});			}		});	},		/**	 * MarkDown preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = fm.arrayFlip(['text/x-markdown']),			preview = ql.preview,			marked  = null,			show = function(data, loading) {				ql.hideinfo();				var doc = $('<iframe class="elfinder-quicklook-preview-html"/>').appendTo(preview)[0].contentWindow.document;				doc.open();				doc.write(marked(data.content));				doc.close();				loading.remove();			},			error = function(loading) {				marked = false;				loading.remove();			};					preview.on(ql.evUpdate, function(e) {			var file = e.file, jqxhr, loading;						if (mimes[file.mime] && fm.options.cdns.marked && marked !== false && ql.dispInlineRegex.test(file.mime) && (!ql.options.getSizeMax || file.size <= ql.options.getSizeMax)) {				e.stopImmediatePropagation();				loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));				// stop loading on change file if not loaded yet				preview.one('change', function() {					jqxhr.state() == 'pending' && jqxhr.reject();				}).addClass('elfinder-overflow-auto');								jqxhr = fm.request({					data           : {cmd : 'get', target : file.hash, conv : 1, _t : file.ts},					options        : {type: 'get', cache : true},					preventDefault : true				})				.done(function(data) {					if (marked || window.marked) {						if (!marked) {							marked = window.marked;						}						show(data, loading);					} else {						fm.loadScript([fm.options.cdns.marked],							function(res) { 								marked = res || window.marked || false;								delete window.marked;								if (marked) {									show(data, loading);								} else {									error(loading);								}							},							{								tryRequire: true,								error: function() {									error(loading);								}							}						);					}				})				.fail(function() {					error(loading);				});			}		});	},	/**	 * PDF/ODT/ODS/ODP preview with ViewerJS	 * 	 * @param elFinder.commands.quicklook	 */	 function(ql) {		if (ql.options.viewerjs) {			var fm      = ql.fm,				preview = ql.preview,				opts    = ql.options.viewerjs,				mimes   = opts.url? fm.arrayFlip(opts.mimes || []) : [];			if (opts.url) {				preview.on('update', function(e) {					var win  = ql.window,						file = e.file, node, loading;					if (mimes[file.mime]) {						var url = fm.openUrl(file.hash);						if (url && fm.isSameOrigin(url)) {							e.stopImmediatePropagation();							loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));							node = $('<iframe class="elfinder-quicklook-preview-iframe"/>')								.css('background-color', 'transparent')								.on('load', function() {									ql.hideinfo();									loading.remove();									node.css('background-color', '#fff');								})								.on('error', function() {									loading.remove();									node.remove();								})								.appendTo(preview)								.attr('src', opts.url + '#' + url);							preview.one('change', function() {								loading.remove();								node.off('load').remove();							});						}					}				});			}		}	},	/**	 * PDF preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mime    = 'application/pdf',			preview = ql.preview,			active  = false,			urlhash = '',			firefox, toolbar;					if ((fm.UA.Safari && fm.OS === 'mac' && !fm.UA.iOS) || fm.UA.IE || fm.UA.Firefox) {			active = true;		} else {			$.each(navigator.plugins, function(i, plugins) {				$.each(plugins, function(i, plugin) {					if (plugin.type === mime) {						return !(active = true);					}				});			});		}		if (active) {			if (typeof ql.options.pdfToolbar !== 'undefined' && !ql.options.pdfToolbar) {				urlhash = '#toolbar=0';			}			preview.on(ql.evUpdate, function(e) {				var file = e.file;								if (active && file.mime === mime && ql.dispInlineRegex.test(file.mime)) {					e.stopImmediatePropagation();					ql.hideinfo();					ql.cover.addClass('elfinder-quicklook-coverbg');					$('<object class="elfinder-quicklook-preview-pdf" data="'+fm.openUrl(file.hash)+urlhash+'" type="application/pdf" />')						.on('error', function(e) {							active = false;							ql.update(void(0), fm.cwd());							ql.update(void(0), file);						})						.appendTo(preview);				}							});		}	},		/**	 * Flash preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mime    = 'application/x-shockwave-flash',			preview = ql.preview,			active  = false;		$.each(navigator.plugins, function(i, plugins) {			$.each(plugins, function(i, plugin) {				if (plugin.type === mime) {					return !(active = true);				}			});		});				active && preview.on(ql.evUpdate, function(e) {			var file = e.file,				node;							if (file.mime === mime && ql.dispInlineRegex.test(file.mime)) {				e.stopImmediatePropagation();				ql.hideinfo();				node = $('<embed class="elfinder-quicklook-preview-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="'+fm.openUrl(file.hash)+'" quality="high" type="application/x-shockwave-flash" wmode="transparent" />')					.appendTo(preview);			}		});	},		/**	 * HTML5 audio preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm       = ql.fm,			preview  = ql.preview,			mimes    = {				'audio/mpeg'    : 'mp3',				'audio/mpeg3'   : 'mp3',				'audio/mp3'     : 'mp3',				'audio/x-mpeg3' : 'mp3',				'audio/x-mp3'   : 'mp3',				'audio/x-wav'   : 'wav',				'audio/wav'     : 'wav',				'audio/x-m4a'   : 'm4a',				'audio/aac'     : 'm4a',				'audio/mp4'     : 'm4a',				'audio/x-mp4'   : 'm4a',				'audio/ogg'     : 'ogg',				'audio/webm'    : 'webm',				'audio/flac'    : 'flac',				'audio/x-flac'  : 'flac',				'audio/amr'     : 'amr'			},			node, curHash,			win  = ql.window,			navi = ql.navbar,			AMR, autoplay,			controlsList = typeof ql.options.mediaControlsList === 'string' && ql.options.mediaControlsList? ' controlsList="' + fm.escape(ql.options.mediaControlsList) + '"' : '',			setNavi = function() {				navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? '50px' : '');			},			getNode = function(src, hash) {				return $('<audio class="elfinder-quicklook-preview-audio ui-front" controls' + controlsList + ' preload="auto" autobuffer><source src="'+src+'" /></audio>')					.on('change', function(e) {						// Firefox fire change event on seek or volume change						e.stopPropagation();					})					.on('error', function(e) {						node && node.data('hash') === hash && reset();					})					.data('hash', hash)					.appendTo(preview);			},			amrToWavUrl = function(hash) {				var dfd = $.Deferred(),					loader = $.Deferred().done(function() {						fm.getContents(hash).done(function(data) {							try {								var buffer = AMR.toWAV(new Uint8Array(data));								if (buffer) {									dfd.resolve(URL.createObjectURL(new Blob([buffer], { type: 'audio/x-wav' })));								} else {									dfd.reject();								}							} catch(e) {								dfd.reject();							}						}).fail(function() {							dfd.reject();						});					}).fail(function() {						AMR = false;						dfd.reject();					}),					_AMR;				if (window.TextEncoder && window.URL && URL.createObjectURL && typeof AMR === 'undefined') {					// previous window.AMR					_AMR = window.AMR;					delete window.AMR;					fm.loadScript(						[ fm.options.cdns.amr ],						function() { 							AMR = window.AMR? window.AMR : false;							// restore previous window.AMR							window.AMR = _AMR;							loader[AMR? 'resolve':'reject']();						},						{							error: function() {								loader.reject();							}						}					);				} else {					loader[AMR? 'resolve':'reject']();				}				return dfd;			},			play = function(player) {				var hash = node.data('hash'),					playPromise;				autoplay && (playPromise = player.play());				// uses "playPromise['catch']" instead "playPromise.catch" to support Old IE				if (playPromise && playPromise['catch']) {					playPromise['catch'](function(e) {						if (!player.paused) {							node && node.data('hash') === hash && reset();						}					});				}			},			reset = function() {				if (node && node.parent().length) {					var elm = node[0],						url = node.children('source').attr('src');					win.off('viewchange.audio');					try {						elm.pause();						node.empty();						if (url.match(/^blob:/)) {							URL.revokeObjectURL(url);						}						elm.src = '';						elm.load();					} catch(e) {}					node.remove();					node = null;				}			};		preview.on(ql.evUpdate, function(e) {			var file = e.file,				type = mimes[file.mime],				html5, srcUrl;			if (mimes[file.mime] && ql.dispInlineRegex.test(file.mime) && ((html5 = ql.support.audio[type]) || (type === 'amr'))) {				autoplay = ql.autoPlay();				curHash = file.hash;				srcUrl = html5? fm.openUrl(curHash) : '';				if (!html5) {					if (fm.options.cdns.amr && type === 'amr' && AMR !== false) {						e.stopImmediatePropagation();						node = getNode(srcUrl, curHash);						amrToWavUrl(file.hash).done(function(url) {							if (curHash === file.hash) {								var elm = node[0];								try {									node.children('source').attr('src', url);									elm.pause();									elm.load();									play(elm);									win.on('viewchange.audio', setNavi);									setNavi();								} catch(e) {									URL.revokeObjectURL(url);									node.remove();								}							} else {								URL.revokeObjectURL(url);							}						}).fail(function() {							node.remove();						});					}				} else {					e.stopImmediatePropagation();					node = getNode(srcUrl, curHash);					play(node[0]);					win.on('viewchange.audio', setNavi);					setNavi();				}			}		}).on('change', reset);	},		/**	 * HTML5 video preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm       = ql.fm,			preview  = ql.preview,			mimes    = {				'video/mp4'       : 'mp4',				'video/x-m4v'     : 'mp4',				'video/quicktime' : 'mp4',				'video/ogg'       : 'ogg',				'application/ogg' : 'ogg',				'video/webm'      : 'webm',				'video/x-matroska': 'mkv',				'video/3gpp'      : '3gp',				'application/vnd.apple.mpegurl' : 'm3u8',				'application/x-mpegurl' : 'm3u8',				'application/dash+xml'  : 'mpd',				'video/x-flv'     : 'flv'			},			node,			win  = ql.window,			navi = ql.navbar,			cHls, cDash, pDash, cFlv, autoplay, tm,			controlsList = typeof ql.options.mediaControlsList === 'string' && ql.options.mediaControlsList? ' controlsList="' + fm.escape(ql.options.mediaControlsList) + '"' : '',			setNavi = function() {				if (fm.UA.iOS) {					if (win.hasClass('elfinder-quicklook-fullscreen')) {						preview.css('height', '-webkit-calc(100% - 50px)');						navi._show();					} else {						preview.css('height', '');					}				} else {					navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? '50px' : '');				}			},			render = function(file, opts) {				var errTm = function(e) {						if (err > 1) {							tm && clearTimeout(tm);							tm = setTimeout(function() {								!canPlay && reset(true);							}, 800);						}					},					err = 0, 					canPlay;				//reset();				pDash = null;				opts = opts || {};				ql.hideinfo();				node = $('<video class="elfinder-quicklook-preview-video" controls' + controlsList + ' preload="auto" autobuffer playsinline>'						+'</video>')					.on('change', function(e) {						// Firefox fire change event on seek or volume change						e.stopPropagation();					})					.on('timeupdate progress', errTm)					.on('canplay', function() {						canPlay = true;					})					.data('hash', file.hash);				// can not handling error event with jQuery `on` event handler				node[0].addEventListener('error', function(e) {					if (opts.src && fm.convAbsUrl(opts.src) === fm.convAbsUrl(e.target.src)) {						++err;						errTm();					}				}, true);				if (opts.src) {					node.append('<source src="'+opts.src+'" type="'+file.mime+'"/><source src="'+opts.src+'"/>');				}								node.appendTo(preview);				win.on('viewchange.video', setNavi);				setNavi();			},			loadHls = function(file) {				var hls;				render(file);				hls = new cHls();				hls.loadSource(fm.openUrl(file.hash));				hls.attachMedia(node[0]);				if (autoplay) {					hls.on(cHls.Events.MANIFEST_PARSED, function() {						play(node[0]);					});				}			},			loadDash = function(file) {				render(file);				pDash = window.dashjs.MediaPlayer().create();				pDash.getDebug().setLogToBrowserConsole(false);				pDash.initialize(node[0], fm.openUrl(file.hash), autoplay);				pDash.on('error', function(e) {					reset(true);				});			},			loadFlv = function(file) {				if (!cFlv.isSupported()) {					cFlv = false;					return;				}				var player = cFlv.createPlayer({					type: 'flv',					url: fm.openUrl(file.hash)				});				render(file);				player.on(cFlv.Events.ERROR, function() {					player.destroy();					reset(true);				});				player.attachMediaElement(node[0]);				player.load();				play(player);			},			play = function(player) {				var hash = node.data('hash'),					playPromise;				autoplay && (playPromise = player.play());				// uses "playPromise['catch']" instead "playPromise.catch" to support Old IE				if (playPromise && playPromise['catch']) {					playPromise['catch'](function(e) {						if (!player.paused) {							node && node.data('hash') === hash && reset(true);						}					});				}			},			reset = function(showInfo) {				tm && clearTimeout(tm);				if (node && node.parent().length) {					var elm = node[0];					win.off('viewchange.video');					pDash && pDash.reset();					try {						elm.pause();						node.empty();						elm.src = '';						elm.load();					} catch(e) {}					node.remove();					node = null;				}				showInfo && ql.info.show();			};		preview.on(ql.evUpdate, function(e) {			var file = e.file,				mime = file.mime.toLowerCase(),				type = mimes[mime],				stock, playPromise;						if (mimes[mime] && ql.dispInlineRegex.test(file.mime) && (((type === 'm3u8' || (type === 'mpd' && !fm.UA.iOS) || type === 'flv') && !fm.UA.ltIE10) || ql.support.video[type])) {				autoplay = ql.autoPlay();				if (ql.support.video[type] && (type !== 'm3u8' || fm.UA.Safari)) {					e.stopImmediatePropagation();					render(file, { src: fm.openUrl(file.hash) });					play(node[0]);				} else {					if (cHls !== false && fm.options.cdns.hls && type === 'm3u8') {						e.stopImmediatePropagation();						if (cHls) {							loadHls(file);						} else {							stock = window.Hls;							delete window.Hls;							fm.loadScript(								[ fm.options.cdns.hls ],								function(res) { 									cHls = res || window.Hls || false;									window.Hls = stock;									cHls && loadHls(file);								},								{									tryRequire: true,									error : function() {										cHls = false;									}								}							);						}					} else if (cDash !== false && fm.options.cdns.dash && type === 'mpd') {						e.stopImmediatePropagation();						if (cDash) {							loadDash(file);						} else {							fm.loadScript(								[ fm.options.cdns.dash ],								function() {									// dashjs require window.dashjs in global scope									cDash = window.dashjs? true : false;									cDash && loadDash(file);								},								{									tryRequire: true,									error : function() {										cDash = false;									}								}							);						}					} else if (cFlv !== false && fm.options.cdns.flv && type === 'flv') {						e.stopImmediatePropagation();						if (cFlv) {							loadFlv(file);						} else {							stock = window.flvjs;							delete window.flvjs;							fm.loadScript(								[ fm.options.cdns.flv ],								function(res) { 									cFlv = res || window.flvjs || false;									window.flvjs = stock;									cFlv && loadFlv(file);								},								{									tryRequire: true,									error : function() {										cFlv = false;									}								}							);						}					}				}			}		}).on('change', reset);	},		/**	 * Audio/video preview plugin using browser plugins	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var preview = ql.preview,			mimes   = [],			node,			win  = ql.window,			navi = ql.navbar;					$.each(navigator.plugins, function(i, plugins) {			$.each(plugins, function(i, plugin) {				(plugin.type.indexOf('audio/') === 0 || plugin.type.indexOf('video/') === 0) && mimes.push(plugin.type);			});		});		mimes = ql.fm.arrayFlip(mimes);				preview.on(ql.evUpdate, function(e) {			var file  = e.file,				mime  = file.mime,				video,				setNavi = function() {					navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? '50px' : '');				};						if (mimes[file.mime] && ql.dispInlineRegex.test(file.mime)) {				e.stopImmediatePropagation();				(video = mime.indexOf('video/') === 0) && ql.hideinfo();				node = $('<embed src="'+ql.fm.openUrl(file.hash)+'" type="'+mime+'" class="elfinder-quicklook-preview-'+(video ? 'video' : 'audio')+'"/>')					.appendTo(preview);								win.on('viewchange.embed', setNavi);				setNavi();			}		}).on('change', function() {			if (node && node.parent().length) {				win.off('viewchange.embed');				node.remove();				node= null;			}		});			},	/**	 * Archive(zip|gzip|tar) preview plugin using https://github.com/imaya/zlib.js	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = fm.arrayFlip(['application/zip', 'application/x-gzip', 'application/x-tar']),			preview = ql.preview,			unzipFiles = function() {				/** @type {Array.<string>} */				var filenameList = [];				/** @type {number} */				var i;				/** @type {number} */				var il;				/** @type {Array.<Zlib.Unzip.FileHeader>} */				var fileHeaderList;				// need check this.Y when update cdns.zlibUnzip				this.Y();				fileHeaderList = this.i;				for (i = 0, il = fileHeaderList.length; i < il; ++i) {					// need check fileHeaderList[i].J when update cdns.zlibUnzip					filenameList[i] = fileHeaderList[i].filename + (fileHeaderList[i].J? ' (' + fm.formatSize(fileHeaderList[i].J) + ')' : '');				}				return filenameList;			},			tarFiles = function(tar) {				var filenames = [],					tarlen = tar.length,					offset = 0,					toStr = function(arr) {						return String.fromCharCode.apply(null, arr).replace(/\0+$/, '');					},					h, name, prefix, size, dbs;				while (offset < tarlen && tar[offset] !== 0) {					h = tar.subarray(offset, offset + 512);					name = toStr(h.subarray(0, 100));					if (prefix = toStr(h.subarray(345, 500))) {						name = prefix + name;					}					size = parseInt(toStr(h.subarray(124, 136)), 8);					dbs = Math.ceil(size / 512) * 512;					if (name === '././@LongLink') {						name = toStr(tar.subarray(offset + 512, offset + 512 + dbs));					}					(name !== 'pax_global_header') && filenames.push(name + (size? ' (' + fm.formatSize(size) + ')': ''));					offset = offset + 512 + dbs;				}				return filenames;			},			Zlib;		if (window.Uint8Array && window.DataView && fm.options.cdns.zlibUnzip && fm.options.cdns.zlibGunzip) {			preview.on(ql.evUpdate, function(e) {				var file  = e.file,					isTar = (file.mime === 'application/x-tar');				if (mimes[file.mime] && (						isTar						|| ((typeof Zlib === 'undefined' || Zlib) && (file.mime === 'application/zip' || file.mime === 'application/x-gzip'))					)) {					var jqxhr, loading, url,						req = function() {							url = fm.openUrl(file.hash);							if (!fm.isSameOrigin(url)) {								url = fm.openUrl(file.hash, true);							}							jqxhr = fm.request({								data    : {cmd : 'get'},								options : {									url: url,									type: 'get',									cache : true,									dataType : 'binary',									responseType :'arraybuffer',									processData: false								}							})							.fail(function() {								loading.remove();							})							.done(function(data) {								var unzip, filenames;								try {									if (file.mime === 'application/zip') {										unzip = new Zlib.Unzip(new Uint8Array(data));										//filenames = unzip.getFilenames();										filenames = unzipFiles.call(unzip);									} else if (file.mime === 'application/x-gzip') {										unzip = new Zlib.Gunzip(new Uint8Array(data));										filenames = tarFiles(unzip.decompress());									} else if (file.mime === 'application/x-tar') {										filenames = tarFiles(new Uint8Array(data));									}									makeList(filenames);								} catch (e) {									loading.remove();									fm.debug('error', e);								}							});						},						makeList = function(filenames) {							var header, doc;							if (filenames && filenames.length) {								filenames = $.map(filenames, function(str) {									return fm.decodeRawString(str);								});								filenames.sort();								loading.remove();								header = '<strong>'+fm.escape(file.mime)+'</strong> ('+fm.formatSize(file.size)+')'+'<hr/>';								doc = $('<div class="elfinder-quicklook-preview-archive-wrapper">'+header+'<pre class="elfinder-quicklook-preview-text">'+fm.escape(filenames.join("\n"))+'</pre></div>')									.on('touchstart', function(e) {										if ($(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {											e.originalEvent._preventSwipeX = true;										}									})									.appendTo(preview);								ql.hideinfo();							}						},						_Zlib;					// this is our file - stop event propagation					e.stopImmediatePropagation();										loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));										// stop loading on change file if not loaded yet					preview.one('change', function() {						jqxhr.state() === 'pending' && jqxhr.reject();						loading.remove();					});										if (Zlib) {						req();					} else {						if (window.Zlib) {							_Zlib = window.Zlib;							delete window.Zlib;						}						fm.loadScript(							[ fm.options.cdns.zlibUnzip, fm.options.cdns.zlibGunzip ],							function() {								if (window.Zlib && (Zlib = window.Zlib)) {									if (_Zlib) {										window.Zlib = _Zlib;									} else {										delete window.Zlib;									}									req();								} else {									error();								}							}						);					}				}			});		}	},	/**	 * RAR Archive preview plugin using https://github.com/43081j/rar.js	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = fm.arrayFlip(['application/x-rar']),			preview = ql.preview,			RAR;		if (window.DataView) {			preview.on(ql.evUpdate, function(e) {				var file = e.file;				if (mimes[file.mime] && fm.options.cdns.rar && RAR !== false) {					var loading, url, archive, abort,						getList = function(url) {							if (abort) {								loading.remove();								return;							}							try {								archive = RAR({									file: url,									type: 2,									xhrHeaders: fm.customHeaders,									xhrFields: fm.xhrFields								}, function(err) {									loading.remove();									var filenames = [],										header, doc;									if (abort || err) {										// An error occurred (not a rar, read error, etc)										err && fm.debug('error', err);										return;									}									$.each(archive.entries, function() {										filenames.push(this.path + (this.size? ' (' + fm.formatSize(this.size) + ')' : ''));									});									if (filenames.length) {										filenames = $.map(filenames, function(str) {											return fm.decodeRawString(str);										});										filenames.sort();										header = '<strong>'+fm.escape(file.mime)+'</strong> ('+fm.formatSize(file.size)+')'+'<hr/>';										doc = $('<div class="elfinder-quicklook-preview-archive-wrapper">'+header+'<pre class="elfinder-quicklook-preview-text">'+fm.escape(filenames.join("\n"))+'</pre></div>')											.on('touchstart', function(e) {												if ($(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {													e.originalEvent._preventSwipeX = true;												}											})											.appendTo(preview);										ql.hideinfo();									}								});							} catch(e) {								loading.remove();							}						},						error = function() {							RAR = false;							loading.remove();						},						_RAR;					// this is our file - stop event propagation					e.stopImmediatePropagation();										loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));										// stop loading on change file if not loaded yet					preview.one('change', function() {						archive && (archive.abort = true);						loading.remove();						abort = true;					});										url = fm.openUrl(file.hash);					if (!fm.isSameOrigin(url)) {						url = fm.openUrl(file.hash, true);					}					if (RAR) {						getList(url);					} else {						if (window.RarArchive) {							_RAR = window.RarArchive;							delete window.RarArchive;						}						fm.loadScript(							[ fm.options.cdns.rar ],							function() {								if (fm.hasRequire) {									require(['rar'], function(RarArchive) {										RAR = RarArchive;										getList(url);									}, error);								} else {									if (RAR = window.RarArchive) {										if (_RAR) {											window.RarArchive = _RAR;										} else {											delete window.RarArchive;										}										getList(url);									} else {										error();									}								}							},							{								tryRequire: true,								error : error							}						);					}				}			});		}	},	/**	 * CAD-Files and 3D-Models online viewer on sharecad.org	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = fm.arrayFlip(ql.options.sharecadMimes || []),			preview = ql.preview,			win     = ql.window,			node;					if (ql.options.sharecadMimes.length) {			ql.addIntegration({				title: 'ShareCAD.org CAD and 3D-Models viewer',				link: 'https://sharecad.org/DWGOnlinePlugin'			});		}		preview.on(ql.evUpdate, function(e) {			var file = e.file;			if (mimes[file.mime.toLowerCase()]) {				var win     = ql.window,					loading, url;								e.stopImmediatePropagation();				if (file.url == '1') {					preview.hide();					$('<div class="elfinder-quicklook-info-data"><button class="elfinder-info-button">'+fm.i18n('getLink')+'</button></div>').appendTo(ql.info.find('.elfinder-quicklook-info'))					.on('click', function() {						var self = $(this);						self.html('<span class="elfinder-spinner">');						fm.request({							data : {cmd : 'url', target : file.hash},							preventDefault : true						})						.always(function() {							self.html('');						})						.done(function(data) {							var rfile = fm.file(file.hash);							file.url = rfile.url = data.url || '';							if (file.url) {								preview.trigger({									type: ql.evUpdate,									file: file,									forceUpdate: true								});							}						});					});				}				if (file.url !== '' && file.url != '1') {					preview.one('change', function() {						loading.remove();						node.off('load').remove();						node = null;					}).addClass('elfinder-overflow-auto');										loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));										url = fm.convAbsUrl(fm.url(file.hash));					node = $('<iframe class="elfinder-quicklook-preview-iframe" scrolling="no"/>')						.css('background-color', 'transparent')						.appendTo(preview)						.on('load', function() {							ql.hideinfo();							loading.remove();							ql.preview.after(ql.info);							$(this).css('background-color', '#fff').show();						})						.on('error', function() {							loading.remove();							ql.preview.after(ql.info);						})						.attr('src', '//sharecad.org/cadframe/load?url=' + encodeURIComponent(url));										ql.info.after(ql.preview);				}			}					});	},	/**	 * KML preview with GoogleMaps API	 *	 * @param elFinder.commands.quicklook	 */	function(ql) {				var fm      = ql.fm,			mimes   = {				'application/vnd.google-earth.kml+xml' : true,				'application/vnd.google-earth.kmz' : true			},			preview = ql.preview,			gMaps, loadMap, wGmfail, fail, mapScr;		if (ql.options.googleMapsApiKey) {			ql.addIntegration({				title: 'Google Maps',				link: 'https://www.google.com/intl/' + fm.lang.replace('_', '-') + '/help/terms_maps.html'			});			gMaps = (window.google && google.maps);			// start load maps			loadMap = function(file, node) {				var mapsOpts = ql.options.googleMapsOpts.maps;				ql.hideinfo();				try {					new gMaps.KmlLayer(fm.convAbsUrl(fm.url(file.hash)), Object.assign({						map: new gMaps.Map(node.get(0), mapsOpts)					}, ql.options.googleMapsOpts.kml));				} catch(e) {					fail();				}			};			// keep stored error handler if exists			wGmfail = window.gm_authFailure;			// on error function			fail = function() {				mapScr = null;			};			// API script url			mapScr = 'https://maps.googleapis.com/maps/api/js?key=' + ql.options.googleMapsApiKey;			// error handler			window.gm_authFailure = function() {				fail();				wGmfail && wGmfail();			};			preview.on(ql.evUpdate, function(e) {				var file = e.file;				if (mapScr && mimes[file.mime.toLowerCase()]) {					var win     = ql.window,						loading, url, node;									e.stopImmediatePropagation();					if (file.url == '1') {						preview.hide();						$('<div class="elfinder-quicklook-info-data"><button class="elfinder-info-button">'+fm.i18n('getLink')+'</button></div>').appendTo(ql.info.find('.elfinder-quicklook-info'))						.on('click', function() {							var self = $(this);							self.html('<span class="elfinder-spinner">');							fm.request({								data : {cmd : 'url', target : file.hash},								preventDefault : true							})							.always(function() {								self.html('');							})							.done(function(data) {								var rfile = fm.file(file.hash);								file.url = rfile.url = data.url || '';								if (file.url) {									preview.trigger({										type: ql.evUpdate,										file: file,										forceUpdate: true									});								}							});						});					}					if (file.url !== '' && file.url != '1') {						node = $('<div style="width:100%;height:100%;"/>').appendTo(preview);						preview.one('change', function() {							node.remove();							node = null;						});						if (!gMaps) {							fm.loadScript([mapScr], function() {								gMaps = window.google && google.maps;								gMaps && loadMap(file, node);							});						} else {							loadMap(file, node);						}					}				}			});		}	},	/**	 * Any supported files preview plugin using (Google docs | MS Office) online viewer	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			mimes   = Object.assign(fm.arrayFlip(ql.options.googleDocsMimes || [], 'g'), fm.arrayFlip(ql.options.officeOnlineMimes || [], 'm')),			preview = ql.preview,			win     = ql.window,			navi    = ql.navbar,			urls    = {				g: 'docs.google.com/gview?embedded=true&url=',				m: 'view.officeapps.live.com/op/embed.aspx?wdStartOn=0&src='			},			navBottom = {				g: '56px',				m: '24px'			},			mLimits = {				xls  : 5242880, // 5MB				xlsb : 5242880,				xlsx : 5242880,				xlsm : 5242880,				other: 10485760 // 10MB			},			node, enable;				if (ql.options.googleDocsMimes.length) {			enable = true;			ql.addIntegration({				title: 'Google Docs Viewer',				link: 'https://docs.google.com/'			});		}		if (ql.options.officeOnlineMimes.length) {			enable = true;			ql.addIntegration({				title: 'MS Online Doc Viewer',				link: 'https://products.office.com/office-online/view-office-documents-online'			});		}		if (enable) {			preview.on(ql.evUpdate, function(e) {				var file = e.file,					type;				// 25MB is maximum filesize of Google Docs prevew				if (file.size <= 26214400 && (type = mimes[file.mime])) {					var win     = ql.window,						setNavi = function() {							navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? navBottom[type] : '');						},						ext     = fm.mimeTypes[file.mime],						loading, url;										if (type === 'm') {						if ((mLimits[ext] && file.size > mLimits[ext]) || file.size > mLimits.other) {							type = 'g';						}					}					if (file.url == '1') {						preview.hide();						$('<div class="elfinder-quicklook-info-data"><button class="elfinder-info-button">'+fm.i18n('getLink')+'</button></div>').appendTo(ql.info.find('.elfinder-quicklook-info'))						.on('click', function() {							var self = $(this);							self.html('<span class="elfinder-spinner">');							fm.request({								data : {cmd : 'url', target : file.hash},								preventDefault : true							})							.always(function() {								self.html('');							})							.done(function(data) {								var rfile = fm.file(file.hash);								file.url = rfile.url = data.url || '';								if (file.url) {									preview.trigger({										type: ql.evUpdate,										file: file,										forceUpdate: true									});								}							});						});					}					if (file.url !== '' && file.url != '1') {						e.stopImmediatePropagation();						preview.one('change', function() {							win.off('viewchange.googledocs');							loading.remove();							node.off('load').remove();							node = null;						}).addClass('elfinder-overflow-auto');												loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));												url = fm.convAbsUrl(fm.url(file.hash));						if (file.ts) {							url += (url.match(/\?/)? '&' : '?') + '_t=' + file.ts;						}						node = $('<iframe class="elfinder-quicklook-preview-iframe"/>')							.css('background-color', 'transparent')							.appendTo(preview)							.on('load', function() {								ql.hideinfo();								loading.remove();								ql.preview.after(ql.info);								$(this).css('background-color', '#fff').show();							})							.on('error', function() {								loading.remove();								ql.preview.after(ql.info);							})							.attr('src', 'https://' + urls[type] + encodeURIComponent(url));												win.on('viewchange.googledocs', setNavi);						setNavi();						ql.info.after(ql.preview);					}				}							});		}	},	/**	 * Texts preview plugin	 *	 * @param elFinder.commands.quicklook	 **/	function(ql) {				var fm      = ql.fm,			preview = ql.preview,			textMaxlen = parseInt(ql.options.textMaxlen) || 2000,			prettify = function() {				if (fm.options.cdns.prettify) {					fm.loadScript([fm.options.cdns.prettify + (fm.options.cdns.prettify.match(/\?/)? '&' : '?') + 'autorun=false']);					prettify = function() { return true; };				} else {					prettify = function() { return false; };				}			},			PRcheck = function(node, cnt) {				if (prettify()) {					if (typeof window.PR === 'undefined' && cnt--) {						setTimeout(function() { PRcheck(node, cnt); }, 100);					} else {						if (typeof window.PR === 'object') {							node.css('cursor', 'wait');							requestAnimationFrame(function() {								PR.prettyPrint && PR.prettyPrint(null, node.get(0));								node.css('cursor', '');							});						} else {							prettify = function() { return false; };						}					}				}			};				preview.on(ql.evUpdate, function(e) {			var file = e.file,				mime = file.mime,				jqxhr, loading;						if (fm.mimeIsText(file.mime) && (!ql.options.getSizeMax || file.size <= ql.options.getSizeMax)) {				e.stopImmediatePropagation();								(typeof window.PR === 'undefined') && prettify();								loading = $('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"/></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));				// stop loading on change file if not loadin yet				preview.one('change', function() {					jqxhr.state() == 'pending' && jqxhr.reject();				});								jqxhr = fm.request({					data           : {cmd : 'get', target : file.hash, conv : 1, _t : file.ts},					options        : {type: 'get', cache : true},					preventDefault : true				})				.done(function(data) {					var reg = new RegExp('^(data:'+file.mime.replace(/([.+])/g, '\\$1')+';base64,)', 'i'),						text = data.content,						part, more, node, m;					ql.hideinfo();					if (window.atob && (m = text.match(reg))) {						text = atob(text.substr(m[1].length));					}										more = text.length - textMaxlen;					if (more > 100) {						part = text.substr(0, textMaxlen) + '...';					} else {						more = 0;					}										node = $('<div class="elfinder-quicklook-preview-text-wrapper"><pre class="elfinder-quicklook-preview-text prettyprint"></pre></div>');										if (more) {						node.append($('<div class="elfinder-quicklook-preview-charsleft"><hr/><span>' + fm.i18n('charsLeft', fm.toLocaleString(more)) + '</span></div>')							.on('click', function() {								var top = node.scrollTop();								$(this).remove();								node.children('pre').removeClass('prettyprinted').text(text).scrollTop(top);								PRcheck(node, 100);							})						);					}					node.children('pre').text(part || text);										node.on('touchstart', function(e) {						if ($(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {							e.originalEvent._preventSwipeX = true;						}					}).appendTo(preview);										PRcheck(node, 100);				})				.always(function() {					loading.remove();				});			}		});	}];/* * File: /js/commands/reload.js *//** * @class  elFinder command "reload" * Sync files and folders * * @author Dmitry (dio) Levashov **/(elFinder.prototype.commands.reload = function() {	"use strict";	var self   = this,		search = false;		this.alwaysEnabled = true;	this.updateOnSelect = true;		this.shortcuts = [{		pattern     : 'ctrl+shift+r f5'	}];		this.getstate = function() {		return 0;	};		this.init = function() {		this.fm.bind('search searchend', function() {			search = this.type == 'search';		});	};		this.fm.bind('contextmenu', function(){		var fm = self.fm;		if (fm.options.sync >= 1000) {			self.extra = {				icon: 'accept',				node: $('<span/>')					.attr({title: fm.i18n('autoSync')})					.on('click touchstart', function(e){						if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {							return;						}						e.stopPropagation();						e.preventDefault();						$(this).parent()							.toggleClass('ui-state-disabled', fm.options.syncStart)							.parent().removeClass('ui-state-hover');						fm.options.syncStart = !fm.options.syncStart;						fm.autoSync(fm.options.syncStart? null : 'stop');					}).on('ready', function(){						$(this).parent().toggleClass('ui-state-disabled', !fm.options.syncStart).css('pointer-events', 'auto');					})			};		}	});		this.exec = function() {		var fm = this.fm;		if (!search) {			var dfrd    = fm.sync(),				timeout = setTimeout(function() {					fm.notify({type : 'reload', cnt : 1, hideCnt : true});					dfrd.always(function() { fm.notify({type : 'reload', cnt  : -1}); });				}, fm.notifyDelay);							return dfrd.always(function() { 				clearTimeout(timeout); 				fm.trigger('reload');			});		} else {			$('div.elfinder-toolbar > div.'+fm.res('class', 'searchbtn') + ' > span.ui-icon-search').click();		}	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/rename.js *//** * @class elFinder command "rename".  * Rename selected file. * * @author Dmitry (dio) Levashov, dio@std42.ru * @author Naoki Sawada **/elFinder.prototype.commands.rename = function() {	"use strict";	// set alwaysEnabled to allow root rename on client size	this.alwaysEnabled = true;	this.syncTitleOnChange = true;	var self = this,		fm = self.fm,		request = function(dfrd, targtes, file, name) {			var sel = targtes? [file.hash].concat(targtes) : [file.hash],				cnt = sel.length,				data = {}, rootNames;						fm.lockfiles({files : sel});						if (fm.isRoot(file)) {				if (!(rootNames = fm.storage('rootNames'))) {					rootNames = {};				}				if (name === '') {					if (rootNames[file.hash]) {						file.name = file._name;						file.i18 = file._i18;						delete rootNames[file.hash];						delete file._name;						delete file._i18;					} else {						dfrd && dfrd.reject();						fm.unlockfiles({files : sel}).trigger('selectfiles', {files : sel});						return;					}				} else {					if (typeof file._name === 'undefined') {						file._name = file.name;						file._i18 = file.i18;					}					file.name = rootNames[file.hash] = name;					delete file.i18;				}				fm.storage('rootNames', rootNames);				data = { changed: [file] };				fm.updateCache(data);				fm.change(data);				dfrd && dfrd.resolve(data);				fm.unlockfiles({files : sel}).trigger('selectfiles', {files : sel});				return;			}			data = {				cmd : 'rename',				name : name,				target : file.hash			};			if (cnt > 1) {				data['targets'] = targtes;				if (name.match(/\*/)) {					data['q'] = name;				}			}						fm.request({					data   : data,					notify : {type : 'rename', cnt : cnt},					navigate : {}				})				.fail(function(error) {					var err = fm.parseError(error);					dfrd && dfrd.reject();					if (! err || ! Array.isArray(err) || err[0] !== 'errRename') {						fm.sync();					}				})				.done(function(data) {					var cwdHash;					if (data.added && data.added.length && cnt === 1) {						data.undo = {							cmd : 'rename',							callback : function() {								return fm.request({									data   : {cmd : 'rename', target : data.added[0].hash, name : file.name},									notify : {type : 'undo', cnt : 1}								});							}						};						data.redo = {							cmd : 'rename',							callback : function() {								return fm.request({									data   : {cmd : 'rename', target : file.hash, name : name},									notify : {type : 'rename', cnt : 1}								});							}						};					}					dfrd && dfrd.resolve(data);					if (!(cwdHash = fm.cwd().hash) || cwdHash === file.hash) {						fm.exec('open', $.map(data.added, function(f) {							return (f.mime === 'directory')? f.hash : null;						})[0]);					}				})				.always(function() {					fm.unlockfiles({files : sel}).trigger('selectfiles', {files : sel});				}			);		},		getHint = function(name, target) {			var sel = target || fm.selected(),				splits = fm.splitFileExtention(name),				f1 = fm.file(sel[0]),				f2 = fm.file(sel[1]),				ext, hint, add;						ext = splits[1]? ('.' + splits[1]) : '';			if (splits[1] && splits[0] === '*') {				// change extention				hint =  '"' + fm.splitFileExtention(f1.name)[0] + ext + '", ';				hint += '"' + fm.splitFileExtention(f2.name)[0] + ext + '"';			} else if (splits[0].length > 1) {				if (splits[0].substr(-1) === '*') {					// add prefix					add = splits[0].substr(0, splits[0].length - 1);					hint =  '"' + add + f1.name+'", ';					hint += '"' + add + f2.name+'"';				} else if (splits[0].substr(0, 1) === '*') {					// add suffix					add = splits[0].substr(1);					hint =  '"'+fm.splitFileExtention(f1.name)[0] + add + ext + '", ';					hint += '"'+fm.splitFileExtention(f2.name)[0] + add + ext + '"';				}			}			if (!hint) {				hint = '"'+splits[0] + '1' + ext + '", "' + splits[0] + '2' + ext + '"';			}			if (sel.length > 2) {				hint += ' ...';			}			return hint;		},		batchRename = function() {			var sel = fm.selected(),				tplr = '<input name="type" type="radio" class="elfinder-tabstop">',				mkChk = function(node, label) {					return $('<label class="elfinder-rename-batch-checks">' + fm.i18n(label) + '</label>').prepend(node);				},				name = $('<input type="text" class="ui-corner-all elfinder-tabstop">'),				num  = $(tplr),				prefix  = $(tplr),				suffix  = $(tplr),				extention  = $(tplr),				checks = $('<div/>').append(					mkChk(num, 'plusNumber'),					mkChk(prefix, 'asPrefix'),					mkChk(suffix, 'asSuffix'),					mkChk(extention, 'changeExtention')				),				preview = $('<div class="elfinder-rename-batch-preview"/>'),				node = $('<div class="elfinder-rename-batch"/>').append(						$('<div class="elfinder-rename-batch-name"/>').append(name),						$('<div class="elfinder-rename-batch-type"/>').append(checks),						preview					),				opts = {					title : fm.i18n('batchRename'),					modal : true,					destroyOnClose : true,					width: Math.min(380, fm.getUI().width() - 20),					buttons : {},					open : function() {						name.on('input', mkPrev).trigger('focus');					}				},				getName = function() {					var vName = name.val(),						ext = fm.splitFileExtention(fm.file(sel[0]).name)[1];					if (vName !== '' || num.is(':checked')) {						if (prefix.is(':checked')) {							vName += '*';						} else if (suffix.is(':checked')) {							vName = '*' + vName + '.' + ext;						} else if (extention.is(':checked')) {							vName = '*.' + vName;						} else if (ext) {							vName += '.' + ext;						}					}					return vName;				},				mkPrev = function() {					var vName = getName();					if (vName !== '') {						preview.html(fm.i18n(['renameMultiple', sel.length, getHint(vName)]));					} else {						preview.empty();					}				},				radios = checks.find('input:radio').on('change', mkPrev),				dialog;						opts.buttons[fm.i18n('btnApply')] = function() {				var vName = getName(),					file, targets;				if (vName !== '') {					dialog.elfinderdialog('close');					targets = sel;					file = fm.file(targets.shift());					request(void(0), targets, file, vName);				}			};			opts.buttons[fm.i18n('btnCancel')] = function() {				dialog.elfinderdialog('close');			};			if ($.fn.checkboxradio) {				radios.checkboxradio({					create: function(e, ui) {						if (this === num.get(0)) {							num.prop('checked', true).change();						}					}				});			} else {				checks.buttonset({					create: function(e, ui) {						num.prop('checked', true).change();					}				});			}			dialog = self.fmDialog(node, opts);		};		this.noChangeDirOnRemovedCwd = true;		this.shortcuts = [{		pattern : 'f2' + (fm.OS == 'mac' ? ' enter' : '')	}, {		pattern : 'shift+f2',		description : 'batchRename',		callback : function() {			fm.selected().length > 1 && batchRename();		}	}];		this.getstate = function(select) {		var sel = this.files(select),			cnt = sel.length,			phash, ext, mime, brk, state, isRoot;				if (!cnt) {			return -1;		}				if (cnt > 1 && sel[0].phash) {			phash = sel[0].phash;			ext = fm.splitFileExtention(sel[0].name)[1].toLowerCase();			mime = sel[0].mime;		}		if (cnt === 1) {			isRoot = fm.isRoot(sel[0]);		}		state = (cnt === 1 && (isRoot || !sel[0].locked) || (fm.api > 2.1030 && cnt === $.grep(sel, function(f) {			if (!brk && !f.locked && f.phash === phash && !fm.isRoot(f) && (mime === f.mime || ext === fm.splitFileExtention(f.name)[1].toLowerCase())) {				return true;			} else {				brk && (brk = true);				return false;			}		}).length)) ? 0 : -1;				// because alwaysEnabled = true, it need check disabled on connector 		if (!isRoot && state === 0 && fm.option('disabledFlip', sel[0].hash)['rename']) {			state = -1;		}		if (state !== -1 && cnt > 1) {			self.extra = {				icon: 'preference',				node: $('<span/>')					.attr({title: fm.i18n('batchRename')})					.on('click touchstart', function(e){						if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {							return;						}						e.stopPropagation();						e.preventDefault();						fm.getUI().trigger('click'); // to close the context menu immediately						batchRename();					})			};		} else {			delete self.extra;		}					return state;	};		this.exec = function(hashes, cOpts) {		var cwd      = fm.getUI('cwd'),			sel      = hashes || (fm.selected().length? fm.selected() : false) || [fm.cwd().hash],			cnt      = sel.length,			file     = fm.file(sel.shift()),			filename = '.elfinder-cwd-filename',			opts     = cOpts || {},			incwd    = (fm.cwd().hash == file.hash),			type     = (opts._currentType === 'navbar' || opts._currentType === 'files')? opts._currentType : (incwd? 'navbar' : 'files'),			navbar   = (type !== 'files'),			target   = $('#'+fm[navbar? 'navHash2Id' : 'cwdHash2Id'](file.hash)),			tarea    = (!navbar && fm.storage('view') != 'list'),			split    = function(name) {				var ext = fm.splitFileExtention(name)[1];				return [name.substr(0, name.length - ext.length - 1), ext];			},			unselect = function() {				requestAnimationFrame(function() {					input && input.trigger('blur');				});			},			rest     = function(){				if (!overlay.is(':hidden')) {					overlay.elfinderoverlay('hide').off('click close', cancel);				}				pnode.removeClass('ui-front')					.css('position', '')					.off('unselect.'+fm.namespace, unselect);				if (tarea) {					node && node.css('max-height', '');				} else if (!navbar) {					pnode.css('width', '')						.parent('td').css('overflow', '');				}			}, colwidth,			dfrd     = $.Deferred()				.fail(function(error) {					var parent = input.parent(),						name   = fm.escape(file.i18 || file.name);					input.off();					if (tarea) {						name = name.replace(/([_.])/g, '​$1');					}					requestAnimationFrame(function() {						if (navbar) {							input.replaceWith(name);						} else {							if (parent.length) {								input.remove();								parent.html(name);							} else {								target.find(filename).html(name);							}						}					});					error && fm.error(error);				})				.always(function() {					rest();					fm.unbind('resize', resize);					fm.enable();				}),			blur = function(e) {				var name   = $.trim(input.val()),				splits = fm.splitFileExtention(name),				valid  = true,				req = function() {					input.off();					rest();					if (navbar) {						input.replaceWith(fm.escape(name));					} else {						node.html(fm.escape(name));					}					request(dfrd, sel, file, name);				};				if (!overlay.is(':hidden')) {					pnode.css('z-index', '');				}				if (name === '') {					if (!fm.isRoot(file)) {						return cancel();					}					if (navbar) {						input.replaceWith(fm.escape(file.name));					} else {						node.html(fm.escape(file.name));					}				}				if (!inError && pnode.length) {										input.off('blur');										if (cnt === 1 && name === file.name) {						return dfrd.reject();					}					if (fm.options.validName && fm.options.validName.test) {						try {							valid = fm.options.validName.test(name);						} catch(e) {							valid = false;						}					}					if (name === '.' || name === '..' || !valid) {						inError = true;						fm.error(file.mime === 'directory'? 'errInvDirname' : 'errInvName', {modal: true, close: function(){setTimeout(select, 120);}});						return false;					}					if (cnt === 1 && fm.fileByName(name, file.phash)) {						inError = true;						fm.error(['errExists', name], {modal: true, close: function(){setTimeout(select, 120);}});						return false;					}										if (cnt === 1) {						req();					} else {						fm.confirm({							title : 'cmdrename',							text  : ['renameMultiple', cnt, getHint(name, [file.hash].concat(sel))],							accept : {								label : 'btnYes',								callback : req							},							cancel : {								label : 'btnCancel',								callback : function() {									setTimeout(function() {										inError = true;										select();									}, 120);								}							}						});						setTimeout(function() {							fm.trigger('unselectfiles', {files: fm.selected()})								.trigger('selectfiles', {files : [file.hash].concat(sel)});						}, 120);					}				}			},			input = $(tarea? '<textarea/>' : '<input type="text"/>')				.on('keyup text', function(){					if (tarea) {						this.style.height = '1px';						this.style.height = this.scrollHeight + 'px';					} else if (colwidth) {						this.style.width = colwidth + 'px';						if (this.scrollWidth > colwidth) {							this.style.width = this.scrollWidth + 10 + 'px';						}					}				})				.on('keydown', function(e) {					e.stopImmediatePropagation();					if (e.keyCode == $.ui.keyCode.ESCAPE) {						dfrd.reject();					} else if (e.keyCode == $.ui.keyCode.ENTER) {						e.preventDefault();						input.trigger('blur');					}				})				.on('mousedown click dblclick', function(e) {					e.stopPropagation();					if (e.type === 'dblclick') {						e.preventDefault();					}				})				.on('blur', blur)				.on('dragenter dragleave dragover drop', function(e) {					// stop bubbling to prevent upload with native drop event					e.stopPropagation();				}),			select = function() {				var name = fm.splitFileExtention(input.val())[0];				if (!inError && fm.UA.Mobile && !fm.UA.iOS) { // since iOS has a bug? (z-index not effect) so disable it					overlay.on('click close', cancel).elfinderoverlay('show');					pnode.css('z-index', overlay.css('z-index') + 1);				}				! fm.enabled() && fm.enable();				if (inError) {					inError = false;					input.on('blur', blur);				}				input.trigger('focus').trigger('select');				input[0].setSelectionRange && input[0].setSelectionRange(0, name.length);			},			node = navbar? target.contents().filter(function(){ return this.nodeType==3 && $(this).parent().attr('id') === fm.navHash2Id(file.hash); })					: target.find(filename),			pnode = node.parent(),			overlay = fm.getUI('overlay'),			cancel = function(e) { 				if (!overlay.is(':hidden')) {					pnode.css('z-index', '');				}				if (! inError) {					dfrd.reject();					if (e) {						e.stopPropagation();						e.preventDefault();					}				}			},			resize = function() {				target.trigger('scrolltoview', {blink : false});			},			inError = false;				pnode.addClass('ui-front')			.css('position', 'relative')			.on('unselect.'+fm.namespace, unselect);		fm.bind('resize', resize);		if (navbar) {			node.replaceWith(input.val(file.name));		} else {			if (tarea) {				node.css('max-height', 'none');			} else if (!navbar) {				colwidth = pnode.width();				pnode.width(colwidth - 15)					.parent('td').css('overflow', 'visible');			}			node.empty().append(input.val(file.name));		}				if (cnt > 1 && fm.api <= 2.1030) {			return dfrd.reject();		}				if (!file || !node.length) {			return dfrd.reject('errCmdParams', this.title);		}				if (file.locked && !fm.isRoot(file)) {			return dfrd.reject(['errLocked', file.name]);		}				fm.one('select', function() {			input.parent().length && file && $.inArray(file.hash, fm.selected()) === -1 && input.trigger('blur');		});				input.trigger('keyup');				select();				return dfrd;	};	fm.bind('select contextmenucreate closecontextmenu', function(e) {		var sel = (e.data? (e.data.selected || e.data.targets) : null) || fm.selected(),			file;		if (sel && sel.length === 1 && (file = fm.file(sel[0])) && fm.isRoot(file)) {			self.title = fm.i18n('kindAlias') + ' (' + fm.i18n('preference') + ')';		} else {			self.title = fm.i18n('cmdrename');		}		if (e.type !== 'closecontextmenu') {			self.update(void(0), self.title);		} else {			requestAnimationFrame(function() {				self.update(void(0), self.title);			});		}	}).remove(function(e) {		var rootNames;		if (e.data && e.data.removed && (rootNames = fm.storage('rootNames'))) {			$.each(e.data.removed, function(i, h) {				if (rootNames[h]) {					delete rootNames[h];				}			});			fm.storage('rootNames', rootNames);		}	});};/* * File: /js/commands/resize.js *//** * @class  elFinder command "resize" * Open dialog to resize image * * @author Dmitry (dio) Levashov * @author Alexey Sukhotin * @author Naoki Sawada * @author Sergio Jovani **/elFinder.prototype.commands.resize = function() {	"use strict";	var losslessRotate = 0,		getBounceBox = function(w, h, theta) {			var srcPts = [					{x: w/2, y: h/2},					{x: -w/2, y: h/2},					{x: -w/2, y: -h/2},					{x: w/2, y: -h/2}				],				dstPts = [],				min = {x: Number.MAX_VALUE, y: Number.MAX_VALUE},				max = {x: Number.MIN_VALUE, y: Number.MIN_VALUE};			$.each(srcPts, function(i, srcPt){				dstPts.push({					x: srcPt.x * Math.cos(theta) - srcPt.y * Math.sin(theta),					y: srcPt.x * Math.sin(theta) + srcPt.y * Math.cos(theta)				});			});			$.each(dstPts, function(i, pt) {				min.x = Math.min(min.x, pt.x);				min.y = Math.min(min.y, pt.y);				max.x = Math.max(max.x, pt.x);				max.y = Math.max(max.y, pt.y);			});			return {				width: max.x - min.x, height: max.y - min.y			};		};		this.updateOnSelect = false;		this.getstate = function() {		var sel = this.fm.selectedFiles();		return sel.length == 1 && sel[0].read && sel[0].write && sel[0].mime.indexOf('image/') !== -1 ? 0 : -1;	};		this.resizeRequest = function(data, f, dfrd) {		var fm   = this.fm,			file = f || fm.file(data.target),			tmb  = file? file.tmb : null,			enabled = fm.isCommandEnabled('resize', data.target);				if (enabled && (! file || (file && file.read && file.write && file.mime.indexOf('image/') !== -1 ))) {			return fm.request({				data : Object.assign(data, {					cmd : 'resize'				}),				notify : {type : 'resize', cnt : 1}			})			.fail(function(error) {				if (dfrd) {					dfrd.reject(error);				}			})			.done(function() {				if (data.quality) {					fm.storage('jpgQuality', data.quality === fm.option('jpgQuality')? null : data.quality);				}				dfrd && dfrd.resolve();			});		} else {			var error;						if (file) {				if (file.mime.indexOf('image/') === -1) {					error = ['errResize', file.name, 'errUsupportType'];				} else {					error = ['errResize', file.name, 'errPerm'];				}			} else {				error = ['errResize', data.target, 'errPerm'];			}						if (dfrd) {				dfrd.reject(error);			} else {				fm.error(error);			}			return $.Deferred().reject(error);		}	};		this.exec = function(hashes) {		var self  = this,			fm    = this.fm,			files = this.files(hashes),			dfrd  = $.Deferred(),			api2  = (fm.api > 1),			options = this.options,			dialogWidth = 650,			fmnode = fm.getUI(),			ctrgrup = $().controlgroup? 'controlgroup' : 'buttonset',			grid8Def = typeof options.grid8px === 'undefined' || options.grid8px !== 'disable'? true : false,			presetSize = Array.isArray(options.presetSize)? options.presetSize : [],			clactive = 'elfinder-dialog-active',			clsediting = fm.res('class', 'editing'),			open = function(file, id) {				var isJpeg   = (file.mime === 'image/jpeg'),					dialog   = $('<div class="elfinder-resize-container"/>'),					input    = '<input type="number" class="ui-corner-all"/>',					row      = '<div class="elfinder-resize-row"/>',					label    = '<div class="elfinder-resize-label"/>',					changeTm = null,					operate  = false,					opStart  = function() { operate = true; },					opStop   = function() {						if (operate) {							operate = false;							control.trigger('change');						}					},					control  = $('<div class="elfinder-resize-control"/>')						.on('focus', 'input[type=text],input[type=number]', function() {							$(this).trigger('select');						})						.on('change', function() {							changeTm && cancelAnimationFrame(changeTm);							changeTm = requestAnimationFrame(function() {								var panel, quty, canvas, ctx, img, sx, sy, sw, sh, deg, theta, bb;								if (sizeImg && ! operate && (canvas = sizeImg.data('canvas'))) {									panel = control.children('div.elfinder-resize-control-panel:visible');									quty = panel.find('input.elfinder-resize-quality');									if (quty.is(':visible')) {										ctx = sizeImg.data('ctx');										img = sizeImg.get(0);										if (panel.hasClass('elfinder-resize-uiresize')) {											// resize											sw = canvas.width = width.val();											sh = canvas.height = height.val();											ctx.drawImage(img, 0, 0, sw, sh);										} else if (panel.hasClass('elfinder-resize-uicrop')) {											// crop											sx = pointX.val();											sy = pointY.val();											sw = offsetX.val();											sh = offsetY.val();											canvas.width = sw;											canvas.height = sh;											ctx.drawImage(img, sx, sy, sw, sh, 0, 0, sw, sh);										} else {											// rotate											deg = degree.val();											theta = (degree.val() * Math.PI) / 180;											bb = getBounceBox(owidth, oheight, theta);											sw = canvas.width = bb.width;											sh = canvas.height = bb.height;											ctx.save();											if (deg % 90 !== 0) {												ctx.fillStyle = bg.val() || '#FFF';												ctx.fillRect(0, 0, sw, sh);											}											ctx.translate(sw / 2, sh / 2);											ctx.rotate(theta);											ctx.drawImage(img, -img.width/2, -img.height/2, owidth, oheight);											ctx.restore();										}										canvas.toBlob(function(blob) {											blob && quty.next('span').text(' (' + fm.formatSize(blob.size) + ')');										}, 'image/jpeg', Math.max(Math.min(quty.val(), 100), 1) / 100);									}								}							});						})						.on('mouseup', 'input', function(e) {							$(e.target).trigger('change');						}),					preview  = $('<div class="elfinder-resize-preview"/>')						.on('touchmove', function(e) {							if ($(e.target).hasClass('touch-punch')) {								e.stopPropagation();								e.preventDefault();							}						}),					spinner  = $('<div class="elfinder-resize-loading">'+fm.i18n('ntfloadimg')+'</div>'),					rhandle  = $('<div class="elfinder-resize-handle touch-punch"/>'),					rhandlec = $('<div class="elfinder-resize-handle touch-punch"/>'),					uiresize = $('<div class="elfinder-resize-uiresize elfinder-resize-control-panel"/>'),					uicrop   = $('<div class="elfinder-resize-uicrop elfinder-resize-control-panel"/>'),					uirotate = $('<div class="elfinder-resize-rotate elfinder-resize-control-panel"/>'),					uideg270 = $('<button/>').attr('title',fm.i18n('rotate-cw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-l"/>')),					uideg90  = $('<button/>').attr('title',fm.i18n('rotate-ccw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-r"/>')),					uiprop   = $('<span />'),					reset    = $('<button class="elfinder-resize-reset">').text(fm.i18n('reset'))						.on('click', function() {							resetView();						})						.button({							icons: {								primary: 'ui-icon-arrowrefresh-1-n'							},							text: false						}),					uitype   = $('<div class="elfinder-resize-type"/>')						.append('<input type="radio" name="type" id="'+id+'-resize" value="resize" checked="checked" /><label for="'+id+'-resize">'+fm.i18n('resize')+'</label>',						'<input class="api2" type="radio" name="type" id="'+id+'-crop" value="crop" /><label class="api2" for="'+id+'-crop">'+fm.i18n('crop')+'</label>',						'<input class="api2" type="radio" name="type" id="'+id+'-rotate" value="rotate" /><label class="api2" for="'+id+'-rotate">'+fm.i18n('rotate')+'</label>'),					mode     = 'resize',					type     = uitype[ctrgrup]()[ctrgrup]('disable').find('input')						.on('change', function() {							mode = $(this).val();														resetView();							resizable(true);							croppable(true);							rotateable(true);														if (mode == 'resize') {								uiresize.show();								uirotate.hide();								uicrop.hide();								resizable();								isJpeg && grid8px.insertAfter(uiresize.find('.elfinder-resize-grid8'));							}							else if (mode == 'crop') {								uirotate.hide();								uiresize.hide();								uicrop.show();								croppable();								isJpeg && grid8px.insertAfter(uicrop.find('.elfinder-resize-grid8'));							} else if (mode == 'rotate') {								uiresize.hide();								uicrop.hide();								uirotate.show();								rotateable();							}						}),					width   = $(input)						.on('change', function() {							var w = round(parseInt(width.val())),								h = round(cratio ? w/ratio : parseInt(height.val()));							if (w > 0 && h > 0) {								resize.updateView(w, h);								width.val(w);								height.val(h);							}						}).addClass('elfinder-focus'),					height  = $(input)						.on('change', function() {							var h = round(parseInt(height.val())),								w = round(cratio ? h*ratio : parseInt(width.val()));							if (w > 0 && h > 0) {								resize.updateView(w, h);								width.val(w);								height.val(h);							}						}),					pointX  = $(input).on('change', function(){crop.updateView();}),					pointY  = $(input).on('change', function(){crop.updateView();}),					offsetX = $(input).on('change', function(){crop.updateView('w');}),					offsetY = $(input).on('change', function(){crop.updateView('h');}),					quality = isJpeg && api2?						$(input).val(fm.storage('jpgQuality') > 0? fm.storage('jpgQuality') : fm.option('jpgQuality'))							.addClass('elfinder-resize-quality')							.attr('min', '1').attr('max', '100').attr('title', '1 - 100')							.on('blur', function(){								var q = Math.min(100, Math.max(1, parseInt(this.value)));								control.find('input.elfinder-resize-quality').val(q);							})						: null,					degree = $('<input type="number" class="ui-corner-all" maxlength="3" value="0" />')						.on('change', function() {							rotate.update();						}),					uidegslider = $('<div class="elfinder-resize-rotate-slider touch-punch"/>')						.slider({							min: 0,							max: 360,							value: degree.val(),							animate: true,							start: opStart,							stop: opStop,							change: function(event, ui) {								if (ui.value != uidegslider.slider('value')) {									rotate.update(ui.value);								}							},							slide: function(event, ui) {								rotate.update(ui.value, false);							}						}).find('.ui-slider-handle')							.addClass('elfinder-tabstop')							.off('keydown')							.on('keydown', function(e) {								if (e.keyCode == $.ui.keyCode.LEFT || e.keyCode == $.ui.keyCode.RIGHT) {									e.stopPropagation();									e.preventDefault();									rotate.update(Number(degree.val()) + (e.keyCode == $.ui.keyCode.RIGHT? 1 : -1), false);								}							})						.end(),					pickimg,					pickcanv,					pickctx,					pickc = {},					pick = function(e) {						var color, r, g, b, h, s, l;						try {							color = pickc[Math.round(e.offsetX)][Math.round(e.offsetY)];						} catch(e) {}						if (!color) return;						r = color[0]; g = color[1]; b = color[2];						h = color[3]; s = color[4]; l = color[5];						setbg(r, g, b, (e.type === 'click'));					},					palpick = function(e) {						setbg($(this).css('backgroundColor'), '', '', (e.type === 'click'));					},					setbg = function(r, g, b, off) {						var s, m, cc;						if (typeof r === 'string') {							g = '';							if (r && (s = $('<span>').css('backgroundColor', r).css('backgroundColor')) && (m = s.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i))) {								r = Number(m[1]);								g = Number(m[2]);								b = Number(m[3]);							}						}						cc = (g === '')? r : '#' + getColorCode(r, g, b);						bg.val(cc).css({ backgroundColor: cc, backgroundImage: 'none', color: (r+g+b < 384? '#fff' : '#000') });						preview.css('backgroundColor', cc);						if (off) {							imgr.off('.picker').removeClass('elfinder-resize-picking');							pallet.off('.picker').removeClass('elfinder-resize-picking');						}					},					getColorCode = function(r, g, b) {						return $.map([r,g,b], function(c){return ('0'+parseInt(c).toString(16)).slice(-2);}).join('');					},					picker = $('<button>').text(fm.i18n('colorPicker'))					.on('click', function() { 						imgr.on('mousemove.picker click.picker', pick).addClass('elfinder-resize-picking');						pallet.on('mousemove.picker click.picker', 'span', palpick).addClass('elfinder-resize-picking');					})					.button({						icons: {							primary: 'ui-icon-pin-s'						},						text: false					}),					reseter = $('<button>').text(fm.i18n('reset'))						.on('click', function() { 							setbg('', '', '', true);						})						.button({							icons: {								primary: 'ui-icon-arrowrefresh-1-n'							},							text: false						}),					bg = $('<input class="ui-corner-all elfinder-resize-bg" type="text">')						.on('focus', function() {							$(this).attr('style', '');						})						.on('blur', function() {							setbg($(this).val());						}),					pallet  = $('<div class="elfinder-resize-pallet">').on('click', 'span', function() {						setbg($(this).css('backgroundColor'));					}),					ratio   = 1,					prop    = 1,					owidth  = 0,					oheight = 0,					cratio  = true,					cratioc = false,					pwidth  = 0,					pheight = 0,					rwidth  = 0,					rheight = 0,					rdegree = 0,					grid8   = isJpeg? grid8Def : false,					constr  = $('<button>').html(fm.i18n('aspectRatio'))						.on('click', function() {							cratio = ! cratio;							constr.button('option', {								icons : { primary: cratio? 'ui-icon-locked' : 'ui-icon-unlocked'}							});							resize.fixHeight();							rhandle.resizable('option', 'aspectRatio', cratio).data('uiResizable')._aspectRatio = cratio;						})						.button({							icons : {								primary: cratio? 'ui-icon-locked' : 'ui-icon-unlocked'							},							text: false						}),					constrc = $('<button>').html(fm.i18n('aspectRatio'))						.on('click', function() {							cratioc = ! cratioc;							constrc.button('option', {								icons : { primary: cratioc? 'ui-icon-locked' : 'ui-icon-unlocked'}							});							rhandlec.resizable('option', 'aspectRatio', cratioc).data('uiResizable')._aspectRatio = cratioc;						})						.button({							icons : {								primary: cratioc? 'ui-icon-locked' : 'ui-icon-unlocked'							},							text: false						}),					grid8px = $('<button>').html(fm.i18n(grid8? 'enabled' : 'disabled')).toggleClass('ui-state-active', grid8)						.on('click', function() {							grid8 = ! grid8;							grid8px.html(fm.i18n(grid8? 'enabled' : 'disabled')).toggleClass('ui-state-active', grid8);							setStep8();						})						.button(),					setStep8 = function() {						var step = grid8? 8 : 1;						$.each([width, height, offsetX, offsetY, pointX, pointY], function() {							this.attr('step', step);						});						if (grid8) {							width.val(round(width.val()));							height.val(round(height.val()));							offsetX.val(round(offsetX.val()));							offsetY.val(round(offsetY.val()));							pointX.val(round(pointX.val()));							pointY.val(round(pointY.val()));							if (uiresize.is(':visible')) {								resize.updateView(width.val(), height.val());							} else if (uicrop.is(':visible')) {								crop.updateView();							}						}					},					setuprimg = function() {						var r_scale,							fail = function() {								bg.parent().hide();								pallet.hide();							};						r_scale = Math.min(pwidth, pheight) / Math.sqrt(Math.pow(owidth, 2) + Math.pow(oheight, 2));						rwidth = Math.ceil(owidth * r_scale);						rheight = Math.ceil(oheight * r_scale);						imgr.width(rwidth)							.height(rheight)							.css('margin-top', (pheight-rheight)/2 + 'px')							.css('margin-left', (pwidth-rwidth)/2 + 'px');						if (imgr.is(':visible') && bg.is(':visible')) {							if (file.mime !== 'image/png') {								preview.css('backgroundColor', bg.val());								pickimg = $('<img>');								if (fm.isCORS) {									pickimg.attr('crossorigin', 'use-credentials');								}								pickimg.on('load', function() {									if (pickcanv && pickcanv.width !== rwidth) {										setColorData();									}								})								.on('error', fail)								.attr('src', canvSrc);							} else {								fail();							}						}					},					setupimg = function() {						resize.updateView(owidth, oheight);						setuprimg();						basec							.width(img.width())							.height(img.height());						imgc							.width(img.width())							.height(img.height());						crop.updateView();						jpgCalc();					},					setColorData = function() {						if (pickctx) {							var n, w, h, r, g, b, a, s, l, hsl, hue,								data, scale, tx1, tx2, ty1, ty2, rgb,								domi = {},								domic = [],								domiv, palc,								rgbToHsl = function (r, g, b) {									var h, s, l,										max = Math.max(Math.max(r, g), b),										min = Math.min(Math.min(r, g), b);											// Hue, 0 ~ 359									if (max === min) {										h = 0;									} else if (r === max) {										h = ((g - b) / (max - min) * 60 + 360) % 360;									} else if (g === max) {										h = (b - r) / (max - min) * 60 + 120;									} else if (b === max) {										h = (r - g) / (max - min) * 60 + 240;									}									// Saturation, 0 ~ 1									s = (max - min) / max;									// Lightness, 0 ~ 1									l = (r *  0.3 + g * 0.59 + b * 0.11) / 255;											return [h, s, l, 'hsl'];								},								rgbRound = function(c) {									return Math.round(c / 8) * 8;								};														calc:							try {								w = pickcanv.width = imgr.width();								h = pickcanv.height = imgr.height();								scale = w / owidth;								pickctx.scale(scale, scale);								pickctx.drawImage(pickimg.get(0), 0, 0);											data = pickctx.getImageData(0, 0, w, h).data;											// Range to detect the dominant color								tx1 = w * 0.1;								tx2 = w * 0.9;								ty1 = h * 0.1;								ty2 = h * 0.9;											for (var y = 0; y < h - 1; y++) {									for (var x = 0; x < w - 1; x++) {										n = x * 4 + y * w * 4;										// RGB										r = data[n]; g = data[n + 1]; b = data[n + 2]; a = data[n + 3];										// check alpha ch										if (a !== 255) {											bg.parent().hide();											pallet.hide();											break calc;										}										// HSL										hsl = rgbToHsl(r, g, b);										hue = Math.round(hsl[0]); s = Math.round(hsl[1] * 100); l = Math.round(hsl[2] * 100);										if (! pickc[x]) {											pickc[x] = {};										}										// set pickc										pickc[x][y] = [r, g, b, hue, s, l];										// detect the dominant color										if ((x < tx1 || x > tx2) && (y < ty1 || y > ty2)) {											rgb = rgbRound(r) + ',' + rgbRound(g) + ',' + rgbRound(b);											if (! domi[rgb]) {												domi[rgb] = 1;											} else {												++domi[rgb];											}										}									}								}																if (! pallet.children(':first').length) {									palc = 1;									$.each(domi, function(c, v) {										domic.push({c: c, v: v});									});									$.each(domic.sort(function(a, b) {										return (a.v > b.v)? -1 : 1;									}), function() {										if (this.v < 2 || palc > 10) {											return false;										}										pallet.append($('<span style="width:20px;height:20px;display:inline-block;background-color:rgb('+this.c+');">'));										++palc;									});								}							} catch(e) {								picker.hide();								pallet.hide();							}						}					},					setupPicker = function() {						try {							pickcanv = document.createElement('canvas');							pickctx = pickcanv.getContext('2d');						} catch(e) {							picker.hide();							pallet.hide();						}					},					setupPreset = function() {						preset.on('click', 'span.elfinder-resize-preset', function() {							var btn = $(this),								w = btn.data('s')[0],								h = btn.data('s')[1],								r = owidth / oheight;							btn.data('s', [h, w]).text(h + 'x' + w);							if (owidth > w || oheight > h) {								if (owidth <= w) {									w = round(h * r);								} else if (oheight <= h) {									h = round(w / r);								} else {									if (owidth - w > oheight - h) {										h = round(w / r);									} else {										w = round(h * r);									}								}							} else {								w = owidth;								h = oheight;							}							width.val(w);							height.val(h);							resize.updateView(w, h);							jpgCalc();						});						presetc.on('click', 'span.elfinder-resize-preset', function() {							var btn = $(this),								w = btn.data('s')[0],								h = btn.data('s')[1],								x = pointX.val(),								y = pointY.val();														btn.data('s', [h, w]).text(h + 'x' + w);							if (owidth >= w && oheight >= h) {								if (owidth - w - x < 0) {									x = owidth - w;								}								if (oheight - h - y < 0) {									y = oheight - h;								}								pointX.val(x);								pointY.val(y);								offsetX.val(w);								offsetY.val(h);								crop.updateView();								jpgCalc();							}						});						presetc.children('span.elfinder-resize-preset').each(function() {							var btn = $(this),								w = btn.data('s')[0],								h = btn.data('s')[1];														btn[(owidth >= w && oheight >= h)? 'show' : 'hide']();						});					},					dimreq  = null,					inited  = false,					setdim  = function(dim) {						var rfile = fm.file(file.hash);						rfile.width = dim[0];						rfile.height = dim[1];					},					init    = function() {						var elm, memSize, r_scale, imgRatio;												if (inited) {							return;						}						inited = true;						dimreq && dimreq.state && dimreq.state() === 'pending' && dimreq.reject();												// check lossless rotete						if (fm.api >= 2.1030) {							if (losslessRotate === 0) {								fm.request({									data: {										cmd    : 'resize',										target : file.hash,										degree : 0,										mode   : 'rotate'									},									preventDefault : true								}).done(function(data) {									losslessRotate = data.losslessRotate? 1 : -1;									if (losslessRotate === 1 && (degree.val() % 90 === 0)) {										uirotate.children('div.elfinder-resize-quality').hide();									}								}).fail(function() {									losslessRotate = -1;								});							}						} else {							losslessRotate = -1;						}												elm = img.get(0);						memSize = file.width && file.height? {w: file.width, h: file.height} : (elm.naturalWidth? null : {w: img.width(), h: img.height()});											memSize && img.removeAttr('width').removeAttr('height');												owidth  = file.width || elm.naturalWidth || elm.width || img.width();						oheight = file.height || elm.naturalHeight || elm.height || img.height();						if (!file.width || !file.height) {							setdim([owidth, oheight]);						}												memSize && img.width(memSize.w).height(memSize.h);												dMinBtn.show();							imgRatio = oheight / owidth;												if (imgRatio < 1 && preview.height() > preview.width() * imgRatio) {							preview.height(preview.width() * imgRatio);						}												if (preview.height() > img.height() + 20) {							preview.height(img.height() + 20);						}												pheight = preview.height() - (rhandle.outerHeight() - rhandle.height());												spinner.remove();												ratio = owidth/oheight;							rhandle.append(img.show()).show();						width.val(owidth);						height.val(oheight);							setupPicker();						setupPreset();						setupimg();												uitype[ctrgrup]('enable');						control.find('input,select').prop('disabled', false)							.filter(':text').on('keydown', function(e) {								var cOpts;								if (e.keyCode == $.ui.keyCode.ENTER) {									e.stopPropagation();									e.preventDefault();									cOpts = {										title  : $('input:checked', uitype).val(),										text   : 'confirmReq',										accept : {											label    : 'btnApply',											callback : function() {  												save();											}										},										cancel : {											label    : 'btnCancel',											callback : function(){												$(this).trigger('focus');											}										}									};																			if (useSaveAs) {										cOpts['buttons'] = [{											label    : 'btnSaveAs',											callback : function() {												requestAnimationFrame(saveAs);											}										}];									}									fm.confirm(cOpts);									return;								}							})							.on('keyup', function() {								var $this = $(this);								if (! $this.hasClass('elfinder-resize-bg')) {									requestAnimationFrame(function() {										$this.val($this.val().replace(/[^0-9]/g, ''));									});								}							})							.filter(':first');												setStep8();						!fm.UA.Mobile && width.trigger('focus');						resizable();					},					img     = $('<img/>')						.on('load', init)						.on('error', function() {							spinner.text('Unable to load image').css('background', 'transparent');						}),					basec = $('<div/>'),					imgc = $('<img/>'),					coverc = $('<div/>'),					imgr = $('<img class="elfinder-resize-imgrotate" />'),					round = function(v, max) {						v = grid8? Math.round(v/8)*8 : Math.round(v);						v = Math.max(0, v);						if (max && v > max) {							v = grid8? Math.floor(max/8)*8 : max;						}						return v;					},					resetView = function() {						width.val(owidth);						height.val(oheight);						resize.updateView(owidth, oheight);						pointX.val(0);						pointY.val(0);						offsetX.val(owidth);						offsetY.val(oheight);						crop.updateView();						jpgCalc();					},					resize = {						update : function() {							width.val(round(img.width()/prop));							height.val(round(img.height()/prop));							jpgCalc();						},												updateView : function(w, h) {							if (w > pwidth || h > pheight) {								if (w / pwidth > h / pheight) {									prop = pwidth / w;									img.width(pwidth).height(round(h*prop));								} else {									prop = pheight / h;									img.height(pheight).width(round(w*prop));								}							} else {								img.width(round(w)).height(round(h));							}														prop = img.width()/w;							uiprop.text('1 : '+(1/prop).toFixed(2));							resize.updateHandle();						},												updateHandle : function() {							rhandle.width(img.width()).height(img.height());						},						fixHeight : function() {							var w, h;							if (cratio) {								w = width.val();								h = round(w/ratio);								resize.updateView(w, h);								height.val(h);							}						}					},					crop = {						update : function(change) {							pointX.val(round(((rhandlec.data('x')||rhandlec.position().left))/prop, owidth));							pointY.val(round(((rhandlec.data('y')||rhandlec.position().top))/prop, oheight));							if (change !== 'xy') {								offsetX.val(round((rhandlec.data('w')||rhandlec.width())/prop, owidth - pointX.val()));								offsetY.val(round((rhandlec.data('h')||rhandlec.height())/prop, oheight - pointY.val()));							}							jpgCalc();						},						updateView : function(change) {							var r, x, y, w, h;														pointX.val(round(pointX.val(), owidth - (grid8? 8 : 1)));							pointY.val(round(pointY.val(), oheight - (grid8? 8 : 1)));							offsetX.val(round(offsetX.val(), owidth - pointX.val()));							offsetY.val(round(offsetY.val(), oheight - pointY.val()));														if (cratioc) {								r = coverc.width() / coverc.height();								if (change === 'w') {									offsetY.val(round(parseInt(offsetX.val()) / r));								} else if (change === 'h') {									offsetX.val(round(parseInt(offsetY.val()) * r));								}							}							x = Math.round(parseInt(pointX.val()) * prop);							y = Math.round(parseInt(pointY.val()) * prop);							if (change !== 'xy') {								w = Math.round(parseInt(offsetX.val()) * prop);								h = Math.round(parseInt(offsetY.val()) * prop);							} else {								w = rhandlec.data('w');								h = rhandlec.data('h');							}							rhandlec.data({x: x, y: y, w: w, h: h})								.width(w)								.height(h)								.css({left: x, top: y});							coverc.width(w)								.height(h);						},						resize_update : function(e, ui) {							rhandlec.data({x: ui.position.left, y: ui.position.top, w: ui.size.width, h: ui.size.height});							crop.update();							crop.updateView();						},						drag_update : function(e, ui) {							rhandlec.data({x: ui.position.left, y: ui.position.top});							crop.update('xy');						}					},					rotate = {						mouseStartAngle : 0,						imageStartAngle : 0,						imageBeingRotated : false,												setQuality : function() {							uirotate.children('div.elfinder-resize-quality')[(losslessRotate > 0 && (degree.val() % 90) === 0)? 'hide' : 'show']();						},												update : function(value, animate) {							if (typeof value == 'undefined') {								rdegree = value = parseInt(degree.val());							}							if (typeof animate == 'undefined') {								animate = true;							}							if (! animate || fm.UA.Opera || fm.UA.ltIE8) {								imgr.rotate(value);							} else {								imgr.animate({rotate: value + 'deg'});							}							value = value % 360;							if (value < 0) {								value += 360;							}							degree.val(parseInt(value));							uidegslider.slider('value', degree.val());														rotate.setQuality();						},												execute : function ( e ) {														if ( !rotate.imageBeingRotated ) return;														var imageCentre = rotate.getCenter( imgr );							var ev = e.originalEvent.touches? e.originalEvent.touches[0] : e;							var mouseXFromCentre = ev.pageX - imageCentre[0];							var mouseYFromCentre = ev.pageY - imageCentre[1];							var mouseAngle = Math.atan2( mouseYFromCentre, mouseXFromCentre );														var rotateAngle = mouseAngle - rotate.mouseStartAngle + rotate.imageStartAngle;							rotateAngle = Math.round(parseFloat(rotateAngle) * 180 / Math.PI);														if ( e.shiftKey ) {								rotateAngle = Math.round((rotateAngle + 6)/15) * 15;							}														imgr.rotate(rotateAngle);														rotateAngle = rotateAngle % 360;							if (rotateAngle < 0) {								rotateAngle += 360;							}							degree.val(rotateAngle);							uidegslider.slider('value', degree.val());														rotate.setQuality();														return false;						},												start : function ( e ) {							if (imgr.hasClass('elfinder-resize-picking')) {								return;							}														opStart();							rotate.imageBeingRotated = true;														var imageCentre = rotate.getCenter( imgr );							var ev = e.originalEvent.touches? e.originalEvent.touches[0] : e;							var mouseStartXFromCentre = ev.pageX - imageCentre[0];							var mouseStartYFromCentre = ev.pageY - imageCentre[1];							rotate.mouseStartAngle = Math.atan2( mouseStartYFromCentre, mouseStartXFromCentre );														rotate.imageStartAngle = parseFloat(imgr.rotate()) * Math.PI / 180.0;														$(document).on('mousemove', rotate.execute);							imgr.on('touchmove', rotate.execute);														return false;						},													stop : function ( e ) {														if ( !rotate.imageBeingRotated ) return;														$(document).off('mousemove', rotate.execute);							imgr.off('touchmove', rotate.execute);														requestAnimationFrame(function() { rotate.imageBeingRotated = false; });							opStop();														return false;						},												getCenter : function ( image ) {														var currentRotation = imgr.rotate();							imgr.rotate(0);														var imageOffset = imgr.offset();							var imageCentreX = imageOffset.left + imgr.width() / 2;							var imageCentreY = imageOffset.top + imgr.height() / 2;														imgr.rotate(currentRotation);														return Array( imageCentreX, imageCentreY );						}					},					resizable = function(destroy) {						if (destroy) {							rhandle.filter(':ui-resizable').resizable('destroy');							rhandle.hide();						}						else {							rhandle.show();							rhandle.resizable({								alsoResize  : img,								aspectRatio : cratio,								resize      : resize.update,								start       : opStart,								stop        : function(e) {									resize.fixHeight;									resize.updateView(width.val(), height.val());									opStop();								}							});							dinit();						}					},					croppable = function(destroy) {						if (destroy) {							rhandlec.filter(':ui-resizable').resizable('destroy')								.filter(':ui-draggable').draggable('destroy');							basec.hide();						}						else {							basec.show();														rhandlec								.resizable({									containment : basec,									aspectRatio : cratioc,									resize      : crop.resize_update,									start       : opStart,									stop        : opStop,									handles     : 'all'								})								.draggable({									handle      : coverc,									containment : imgc,									drag        : crop.drag_update,									start       : opStart,									stop        : function() {										crop.updateView('xy');										opStop();									}								});														dinit();							crop.update();						}					},					rotateable = function(destroy) {						if (destroy) {							imgr.hide();						}						else {							imgr.show();							dinit();						}					},					checkVals = function() {						var w, h, x, y, d, q, b = '';												if (mode == 'resize') {							w = parseInt(width.val()) || 0;							h = parseInt(height.val()) || 0;						} else if (mode == 'crop') {							w = parseInt(offsetX.val()) || 0;							h = parseInt(offsetY.val()) || 0;							x = parseInt(pointX.val()) || 0;							y = parseInt(pointY.val()) || 0;						} else if (mode == 'rotate') {							w = owidth;							h = oheight;							d = parseInt(degree.val()) || 0;							if (d < 0 || d > 360) {								fm.error('Invalid rotate degree');								return false;							}							if (d == 0 || d == 360) {								fm.error('errResizeNoChange');								return false;							}							b = bg.val();						}						q = quality? parseInt(quality.val()) : 0;												if (mode != 'rotate') {							if (w <= 0 || h <= 0) {								fm.error('Invalid image size');								return false;							}							if (w == owidth && h == oheight) {								fm.error('errResizeNoChange');								return false;							}						}												return {w: w, h: h, x: x, y: y, d: d, q: q, b: b};					},					save = function() {						var vals;												if (vals = checkVals()) {							dialog.elfinderdialog('close');							self.resizeRequest({								target : file.hash,								width  : vals.w,								height : vals.h,								x      : vals.x,								y      : vals.y,								degree : vals.d,								quality: vals.q,								bg     : vals.b,								mode   : mode							}, file, dfrd);						}					},					saveAs = function() {						var fail = function() {								dialogs.addClass(clsediting).fadeIn(function() {									base.addClass(clactive);								});								fm.disable();							},							make = function() {								self.mime = file.mime;								self.prefix = file.name.replace(/ \d+(\.[^.]+)?$/, '$1');								self.requestCmd = 'mkfile';								self.nextAction = {};								self.data = {target : file.phash};								$.proxy(fm.res('mixin', 'make'), self)()									.done(function(data) {										var hash, dfd;										if (data.added && data.added.length) {											hash = data.added[0].hash;											dfd = fm.api < 2.1032? fm.url(file.hash, { async: true, temporary: true }) : null;											$.when(dfd).done(function(url) {												fm.request({													options : {type : 'post'},													data : {														cmd     : 'put',														target  : hash,														encoding: dfd? 'scheme' : 'hash', 														content : dfd? fm.convAbsUrl(url) : file.hash													},													notify : {type : 'copy', cnt : 1},													syncOnFail : true												})												.fail(fail)												.done(function(data) {													data = fm.normalize(data);													fm.updateCache(data);													file = fm.file(hash);													data.changed && data.changed.length && fm.change(data);													base.show().find('.elfinder-dialog-title').html(fm.escape(file.name));													save();													dialogs.fadeIn();												});											}).fail(fail);										} else {											fail();										}									})									.fail(fail)									.always(function() {										delete self.mime;										delete self.prefix;										delete self.nextAction;										delete self.data;									});								fm.trigger('unselectfiles', { files: [ file.hash ] });							},							reqOpen = null,							dialogs;												if (checkVals()) {							dialogs = fmnode.children('.' + self.dialogClass + ':visible').removeClass(clsediting).fadeOut();							base.removeClass(clactive);							fm.enable();							if (fm.searchStatus.state < 2 && file.phash !== fm.cwd().hash) {								reqOpen = fm.exec('open', [file.phash], {thash: file.phash});							}														$.when([reqOpen]).done(function() {								reqOpen? fm.one('cwdrender', make) : make();							}).fail(fail);						}					},					buttons = {},					hline   = 'elfinder-resize-handle-hline',					vline   = 'elfinder-resize-handle-vline',					rpoint  = 'elfinder-resize-handle-point',					src     = fm.openUrl(file.hash),					canvSrc = fm.openUrl(file.hash, !fm.isSameOrigin(src)),					sizeImg = quality? $('<img>').attr('crossorigin', fm.isCORS? 'use-credentials' : '').attr('src', canvSrc).on('load', function() {						try {							var canv = document.createElement('canvas');							sizeImg.data('canvas', canv).data('ctx', canv.getContext('2d'));							jpgCalc();						} catch(e) {							sizeImg.removeData('canvas').removeData('ctx');						}					}) : null,					jpgCalc = function() {						control.find('input.elfinder-resize-quality:visible').trigger('change');					},					dinit   = function(e) {						if (base.hasClass('elfinder-dialog-minimized') || base.is(':hidden')) {							return;						}												preset.hide();						presetc.hide();												var win   = fm.options.dialogContained? fmnode : $(window),							winH  = win.height(),							winW  = win.width(),							presW = 'auto',							presIn = true,							dw, ctrW, prvW;												base.width(Math.min(dialogWidth, winW - 30));						preview.attr('style', '');						if (owidth && oheight) {							pwidth  = preview.width()  - (rhandle.outerWidth()  - rhandle.width());							pheight = preview.height() - (rhandle.outerHeight() - rhandle.height());							resize.updateView(owidth, oheight);						}						ctrW  = dialog.find('div.elfinder-resize-control').width();						prvW  = preview.width();												dw = dialog.width() - 20;						if (prvW > dw) {							preview.width(dw);							presIn = false;						} else if ((dw - prvW) < ctrW) {							if (winW > winH) {								preview.width(dw - ctrW - 20);							} else {								preview.css({ float: 'none', marginLeft: 'auto', marginRight: 'auto'});								presIn = false;							}						}						if (presIn) {							presW = ctrW;						}						pwidth  = preview.width()  - (rhandle.outerWidth()  - rhandle.width());						if (fmnode.hasClass('elfinder-fullscreen')) {							if (base.height() > winH) {								winH -= 2;								preview.height(winH - base.height() + preview.height());								base.css('top', 0 - fmnode.offset().top);							}						} else {							winH -= 30;							(preview.height() > winH) && preview.height(winH);						}						pheight = preview.height() - (rhandle.outerHeight() - rhandle.height());						if (owidth && oheight) {							setupimg();						}						if (img.height() && preview.height() > img.height() + 20) {							preview.height(img.height() + 20);							pheight = preview.height() - (rhandle.outerHeight() - rhandle.height());							setuprimg();						}												preset.css('width', presW).show();						presetc.css('width', presW).show();						if (!presetc.children('span.elfinder-resize-preset:visible').length) {							presetc.hide();						}					},					preset = (function() {						var sets = $('<fieldset class="elfinder-resize-preset-container">').append($('<legend>').html(fm.i18n('presets'))).hide(),							hasC;						$.each(presetSize, function(i, s) {							if (s.length === 2) {								hasC = true;								sets.append($('<span class="elfinder-resize-preset"/>')									.data('s', s)									.text(s[0]+'x'+s[1])									.button()								);							}						});						if (!hasC) {							return $();						} else {							return sets;						}					})(),					presetc = preset.clone(true),					useSaveAs = fm.uploadMimeCheck(file.mime, file.phash),					dMinBtn, base;								uiresize.append(					$(row).append($(label).text(fm.i18n('width')), width),					$(row).append($(label).text(fm.i18n('height')), height, $('<div class="elfinder-resize-whctrls">').append(constr, reset)),					(quality? $(row).append($(label).text(fm.i18n('quality')), quality, $('<span/>')) : $()),					(isJpeg? $(row).append($(label).text(fm.i18n('8pxgrid')).addClass('elfinder-resize-grid8'), grid8px) : $()),					$(row).append($(label).text(fm.i18n('scale')), uiprop),					$(row).append(preset)				);				if (api2) {					uicrop.append(						$(row).append($(label).text('X'), pointX),						$(row).append($(label).text('Y')).append(pointY),						$(row).append($(label).text(fm.i18n('width')), offsetX),						$(row).append($(label).text(fm.i18n('height')), offsetY, $('<div class="elfinder-resize-whctrls">').append(constrc, reset.clone(true))),						(quality? $(row).append($(label).text(fm.i18n('quality')), quality.clone(true), $('<span/>')) : $()),						(isJpeg? $(row).append($(label).text(fm.i18n('8pxgrid')).addClass('elfinder-resize-grid8')) : $()),						$(row).append(presetc)					);										uirotate.append(						$(row).addClass('elfinder-resize-degree').append(							$(label).text(fm.i18n('rotate')),							degree,							$('<span/>').text(fm.i18n('degree')),							$('<div/>').append(uideg270, uideg90)[ctrgrup]()						),						$(row).css('height', '20px').append(uidegslider),						((quality)? $(row)[losslessRotate < 1? 'show' : 'hide']().addClass('elfinder-resize-quality').append(							$(label).text(fm.i18n('quality')),							quality.clone(true),							$('<span/>')) : $()						),						$(row).append($(label).text(fm.i18n('bgcolor')), bg, picker, reseter),						$(row).css('height', '20px').append(pallet)					);					uideg270.on('click', function() {						rdegree = rdegree - 90;						rotate.update(rdegree);					});					uideg90.on('click', function(){						rdegree = rdegree + 90;						rotate.update(rdegree);					});				}								dialog.append(uitype).on('resize', function(e){					e.stopPropagation();				});				if (api2) {					control.append(/*$(row), */uiresize, uicrop.hide(), uirotate.hide());				} else {					control.append(/*$(row), */uiresize);				}								rhandle.append('<div class="'+hline+' '+hline+'-top"/>',					'<div class="'+hline+' '+hline+'-bottom"/>',					'<div class="'+vline+' '+vline+'-left"/>',					'<div class="'+vline+' '+vline+'-right"/>',					'<div class="'+rpoint+' '+rpoint+'-e"/>',					'<div class="'+rpoint+' '+rpoint+'-se"/>',					'<div class="'+rpoint+' '+rpoint+'-s"/>');									preview.append(spinner).append(rhandle.hide()).append(img.hide());				if (api2) {					rhandlec.css('position', 'absolute')						.append('<div class="'+hline+' '+hline+'-top"/>',						'<div class="'+hline+' '+hline+'-bottom"/>',						'<div class="'+vline+' '+vline+'-left"/>',						'<div class="'+vline+' '+vline+'-right"/>',						'<div class="'+rpoint+' '+rpoint+'-n"/>',						'<div class="'+rpoint+' '+rpoint+'-e"/>',						'<div class="'+rpoint+' '+rpoint+'-s"/>',						'<div class="'+rpoint+' '+rpoint+'-w"/>',						'<div class="'+rpoint+' '+rpoint+'-ne"/>',						'<div class="'+rpoint+' '+rpoint+'-se"/>',						'<div class="'+rpoint+' '+rpoint+'-sw"/>',						'<div class="'+rpoint+' '+rpoint+'-nw"/>');					preview.append(basec.css('position', 'absolute').hide().append(imgc, rhandlec.append(coverc)));										preview.append(imgr.hide());				}								preview.css('overflow', 'hidden');								dialog.append(preview, control);								buttons[fm.i18n('btnApply')] = save;				if (useSaveAs) {					buttons[fm.i18n('btnSaveAs')] = function() { requestAnimationFrame(saveAs); };				}				buttons[fm.i18n('btnCancel')] = function() { dialog.elfinderdialog('close'); };								dialog.find('input,button').addClass('elfinder-tabstop');								base = self.fmDialog(dialog, {					title          : fm.escape(file.name),					width          : dialogWidth,					resizable      : false,					buttons        : buttons,					open           : function() {						var substituteImg = (fm.option('substituteImg', file.hash) && file.size > options.dimSubImgSize)? true : false,							hasSize = (file.width && file.height)? true : false;						dialog.parent().css('overflow', 'hidden');						dMinBtn = base.find('.ui-dialog-titlebar .elfinder-titlebar-minimize').hide();						fm.bind('resize', dinit);						img.attr('src', src);						imgc.attr('src', src);						imgr.attr('src', src);						if (api2) {							imgr.on('mousedown touchstart', rotate.start)								.on('touchend', rotate.stop);							base.on('mouseup', rotate.stop);						}						if (hasSize && !substituteImg) {							return init();						}						if (file.size > (options.getDimThreshold || 0)) {							dimreq = fm.request({								data : {cmd : 'dim', target : file.hash, substitute : (substituteImg? 400 : '')},								preventDefault : true							})							.done(function(data) {								if (data.dim) {									var dim = data.dim.split('x');									file.width = dim[0];									file.height = dim[1];									setdim(dim);									if (data.url) {										img.attr('src', data.url);										imgc.attr('src', data.url);										imgr.attr('src', data.url);									}									return init();								}							});						} else if (hasSize) {							return init();						}					},					close          : function() {						if (api2) {							imgr.off('mousedown touchstart', rotate.start)								.off('touchend', rotate.stop);							$(document).off('mouseup', rotate.stop);						}						fm.unbind('resize', dinit);						$(this).elfinderdialog('destroy');					},					resize         : function(e, data) {						if (data && data.minimize === 'off') {							dinit();						}					}				}).attr('id', id).closest('.ui-dialog').addClass(clsediting);								// for IE < 9 dialog mising at open second+ time.				if (fm.UA.ltIE8) {					$('.elfinder-dialog').css('filter', '');				}								coverc.css({ 'opacity': 0.2, 'background-color': '#fff', 'position': 'absolute'}),				rhandlec.css('cursor', 'move');				rhandlec.find('.elfinder-resize-handle-point').css({					'background-color' : '#fff',					'opacity': 0.5,					'border-color':'#000'				});				if (! api2) {					uitype.find('.api2').remove();				}								control.find('input,select').prop('disabled', true);				control.find('input.elfinder-resize-quality')					.next('span').addClass('elfinder-resize-jpgsize').attr('title', fm.i18n('roughFileSize'));			},						id, dialog			;					if (!files.length || files[0].mime.indexOf('image/') === -1) {			return dfrd.reject();		}				id = 'resize-'+fm.namespace+'-'+files[0].hash;		dialog = fmnode.find('#'+id);				if (dialog.length) {			dialog.elfinderdialog('toTop');			return dfrd.resolve();		}				open(files[0], id);					return dfrd;	};};(function ($) {		var findProperty = function (styleObject, styleArgs) {		var i = 0 ;		for( i in styleArgs) {	        if (typeof styleObject[styleArgs[i]] != 'undefined') 	        	return styleArgs[i];		}		styleObject[styleArgs[i]] = '';	    return styleArgs[i];	};		$.cssHooks.rotate = {		get: function(elem, computed, extra) {			return $(elem).rotate();		},		set: function(elem, value) {			$(elem).rotate(value);			return value;		}	};	$.cssHooks.transform = {		get: function(elem, computed, extra) {			var name = findProperty( elem.style , 				['WebkitTransform', 'MozTransform', 'OTransform' , 'msTransform' , 'transform'] );			return elem.style[name];		},		set: function(elem, value) {			var name = findProperty( elem.style , 				['WebkitTransform', 'MozTransform', 'OTransform' , 'msTransform' , 'transform'] );			elem.style[name] = value;			return value;		}	};		$.fn.rotate = function(val) {		var r;		if (typeof val == 'undefined') {			if (!!window.opera) {				r = this.css('transform').match(/rotate\((.*?)\)/);				return  ( r && r[1])?					Math.round(parseFloat(r[1]) * 180 / Math.PI) : 0;			} else {				r = this.css('transform').match(/rotate\((.*?)\)/);				return  ( r && r[1])? parseInt(r[1]) : 0;			}		}		this.css('transform', 			this.css('transform').replace(/none|rotate\(.*?\)/, '') + 'rotate(' + parseInt(val) + 'deg)');		return this;	};	$.fx.step.rotate  = function(fx) {		if ( fx.state == 0 ) {			fx.start = $(fx.elem).rotate();			fx.now = fx.start;		}		$(fx.elem).rotate(fx.now);	};	if (typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined") { // IE & IE<9		var GetAbsoluteXY = function(element) {			var pnode = element;			var x = pnode.offsetLeft;			var y = pnode.offsetTop;						while ( pnode.offsetParent ) {				pnode = pnode.offsetParent;				if (pnode != document.body && pnode.currentStyle['position'] != 'static') {					break;				}				if (pnode != document.body && pnode != document.documentElement) {					x -= pnode.scrollLeft;					y -= pnode.scrollTop;				}				x += pnode.offsetLeft;				y += pnode.offsetTop;			}						return { x: x, y: y };		};				var StaticToAbsolute = function (element) {			if ( element.currentStyle['position'] != 'static') {				return ;			}			var xy = GetAbsoluteXY(element);			element.style.position = 'absolute' ;			element.style.left = xy.x + 'px';			element.style.top = xy.y + 'px';		};		var IETransform = function(element,transform){			var r;			var m11 = 1;			var m12 = 1;			var m21 = 1;			var m22 = 1;			if (typeof element.style['msTransform'] != 'undefined'){				return true;			}			StaticToAbsolute(element);			r = transform.match(/rotate\((.*?)\)/);			var rotate =  ( r && r[1])	?	parseInt(r[1])	:	0;			rotate = rotate % 360;			if (rotate < 0) rotate = 360 + rotate;			var radian= rotate * Math.PI / 180;			var cosX =Math.cos(radian);			var sinY =Math.sin(radian);			m11 *= cosX;			m12 *= -sinY;			m21 *= sinY;			m22 *= cosX;			element.style.filter =  (element.style.filter || '').replace(/progid:DXImageTransform\.Microsoft\.Matrix\([^)]*\)/, "" ) +				("progid:DXImageTransform.Microsoft.Matrix(" + 					 "M11=" + m11 + 					",M12=" + m12 + 					",M21=" + m21 + 					",M22=" + m22 + 					",FilterType='bilinear',sizingMethod='auto expand')") 				;	  		var ow = parseInt(element.style.width || element.width || 0 );	  		var oh = parseInt(element.style.height || element.height || 0 );			radian = rotate * Math.PI / 180;			var absCosX =Math.abs(Math.cos(radian));			var absSinY =Math.abs(Math.sin(radian));			var dx = (ow - (ow * absCosX + oh * absSinY)) / 2;			var dy = (oh - (ow * absSinY + oh * absCosX)) / 2;			element.style.marginLeft = Math.floor(dx) + "px";			element.style.marginTop  = Math.floor(dy) + "px";			return(true);		};				var transform_set = $.cssHooks.transform.set;		$.cssHooks.transform.set = function(elem, value) {			transform_set.apply(this, [elem, value] );			IETransform(elem,value);			return value;		};	}})(jQuery);/* * File: /js/commands/restore.js *//** * @class  elFinder command "restore" * Restore items from the trash * * @author Naoki Sawada **/(elFinder.prototype.commands.restore = function() {	"use strict";	var self = this,		fm = this.fm,		fakeCnt = 0,		getFilesRecursively = function(files) {			var dfd = $.Deferred(),				dirs = [],				results = [],				reqs = [],				phashes = [],				getFile;						dfd._xhrReject = function() {				$.each(reqs, function() {					this && this.reject && this.reject();				});				getFile && getFile._xhrReject();			};						$.each(files, function(i, f) {				f.mime === 'directory'? dirs.push(f) : results.push(f);			});						if (dirs.length) {				$.each(dirs, function(i, d) {					reqs.push(fm.request({						data : {cmd  : 'open', target : d.hash},						preventDefault : true,						asNotOpen : true					}));					phashes[i] = d.hash;				});				$.when.apply($, reqs).fail(function() {					dfd.reject();				}).done(function() {					var items = [];					$.each(arguments, function(i, r) {						var files;						if (r.files) {							if (r.files.length) {								items = items.concat(r.files);							} else {								items.push({									hash: 'fakefile_' + (fakeCnt++),									phash: phashes[i],									mime: 'fakefile',									name: 'fakefile',									ts: 0								});							}						}					});					fm.cache(items);					getFile = getFilesRecursively(items).done(function(res) {						results = results.concat(res);						dfd.resolve(results);					});				});			} else {				dfd.resolve(results);			}						return dfd;		},		restore = function(dfrd, files, targets, ops) {			var rHashes = {},				others = [],				found = false,				dirs = [],				opts = ops || {},				id = +new Date(),				tm, getFile;						fm.lockfiles({files : targets});						dirs = $.map(files, function(f) {				return f.mime === 'directory'? f.hash : null;			});						dfrd.done(function() {				dirs && fm.exec('rm', dirs, {forceRm : true, quiet : true});			}).always(function() {				fm.unlockfiles({files : targets});			});						tm = setTimeout(function() {				fm.notify({type : 'search', id : id, cnt : 1, hideCnt : true, cancel : function() {					getFile && getFile._xhrReject();					dfrd.reject();				}});			}, fm.notifyDelay);			fakeCnt = 0;			getFile = getFilesRecursively(files).always(function() {				tm && clearTimeout(tm);				fm.notify({type : 'search', id: id, cnt : -1, hideCnt : true});			}).fail(function() {				dfrd.reject('errRestore', 'errFileNotFound');			}).done(function(res) {				var errFolderNotfound = ['errRestore', 'errFolderNotFound'],					dirTop = '';								if (res.length) {					$.each(res, function(i, f) {						var phash = f.phash,							pfile,							srcRoot, tPath;						while(phash) {							if (srcRoot = fm.trashes[phash]) {								if (! rHashes[srcRoot]) {									if (found) {										// Keep items of other trash										others.push(f.hash);										return null; // continue $.each									}									rHashes[srcRoot] = {};									found = true;								}										tPath = fm.path(f.hash).substr(fm.path(phash).length).replace(/\\/g, '/');								tPath = tPath.replace(/\/[^\/]+?$/, '');								if (tPath === '') {									tPath = '/';								}								if (!rHashes[srcRoot][tPath]) {									rHashes[srcRoot][tPath] = [];								}								if (f.mime === 'fakefile') {									fm.updateCache({removed:[f.hash]});								} else {									rHashes[srcRoot][tPath].push(f.hash);								}								if (!dirTop || dirTop.length > tPath.length) {									dirTop = tPath;								}								break;							}														// Go up one level for next check							pfile = fm.file(phash);														if (!pfile) {								phash = false;								// Detection method for search results								$.each(fm.trashes, function(ph) {									var file = fm.file(ph),										filePath = fm.path(ph);									if ((!file.volumeid || f.hash.indexOf(file.volumeid) === 0) && fm.path(f.hash).indexOf(filePath) === 0) {										phash = ph;										return false;									}								});							} else {								phash = pfile.phash;							}						}					});					if (found) {						$.each(rHashes, function(src, dsts) {							var dirs = Object.keys(dsts),								cnt = dirs.length;							fm.request({								data   : {cmd  : 'mkdir', target : src, dirs : dirs}, 								notify : {type : 'chkdir', cnt : cnt},								preventFail : true							}).fail(function(error) {								dfrd.reject(error);								fm.unlockfiles({files : targets});							}).done(function(data) {								var cmdPaste, hashes;																if (hashes = data.hashes) {									cmdPaste = fm.getCommand('paste');									if (cmdPaste) {										// wait until file cache made										fm.one('mkdirdone', function() {											var hasErr = false;											$.each(dsts, function(dir, files) {												if (hashes[dir]) {													if (files.length) {														if (fm.file(hashes[dir])) {															fm.clipboard(files, true);															fm.exec('paste', [ hashes[dir] ], {_cmd : 'restore', noToast : (opts.noToast || dir !== dirTop)})															.done(function(data) {																if (data && (data.error || data.warning)) {																	hasErr = true;																}															})															.fail(function() {																hasErr = true;															})															.always(function() {																if (--cnt < 1) {																	dfrd[hasErr? 'reject' : 'resolve']();																	if (others.length) {																		// Restore items of other trash																		fm.exec('restore', others);																	}																}															});														} else {															dfrd.reject(errFolderNotfound);														}													} else {														if (--cnt < 1) {															dfrd.resolve();															if (others.length) {																// Restore items of other trash																fm.exec('restore', others);															}														}													}												}											});										});									} else {										dfrd.reject(['errRestore', 'errCmdNoSupport', '(paste)']);									}								} else {									dfrd.reject(errFolderNotfound);								}							});						});					} else {						dfrd.reject(errFolderNotfound);					}				} else {					dfrd.reject('errFileNotFound');					dirs && fm.exec('rm', dirs, {forceRm : true, quiet : true});				}			});		};		// for to be able to overwrite	this.restore = restore;	this.linkedCmds = ['copy', 'paste', 'mkdir', 'rm'];	this.updateOnSelect = false;		this.init = function() {		// re-assign for extended command		self = this;		fm = this.fm;	};	this.getstate = function(sel, e) {		sel = sel || fm.selected();		return sel.length && $.grep(sel, function(h) {var f = fm.file(h); return f && ! f.locked && ! fm.isRoot(f)? true : false; }).length == sel.length			? 0 : -1;	};		this.exec = function(hashes, opts) {		var dfrd   = $.Deferred()				.fail(function(error) {					error && fm.error(error);				}),			files  = self.files(hashes);		if (! files.length) {			return dfrd.reject();		}				$.each(files, function(i, file) {			if (fm.isRoot(file)) {				return !dfrd.reject(['errRestore', file.name]);			}			if (file.locked) {				return !dfrd.reject(['errLocked', file.name]);			}		});		if (dfrd.state() === 'pending') {			this.restore(dfrd, files, hashes, opts);		}					return dfrd;	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/rm.js *//** * @class  elFinder command "rm" * Delete files * * @author Dmitry (dio) Levashov * @author Naoki Sawada **/elFinder.prototype.commands.rm = function() {	"use strict";	var self = this,		fm = this.fm,		tpl = '<div class="ui-helper-clearfix elfinder-rm-title"><span class="elfinder-cwd-icon {class} ui-corner-all"/>{title}<div class="elfinder-rm-desc">{desc}</div></div>',		confirm = function(dfrd, targets, files, tHash, addTexts) {			var cnt = targets.length,				cwd = fm.cwd().hash,				descs = [],				spinner = fm.i18n('calc') + '<span class="elfinder-spinner"/>',				dialog, text, tmb, size, f, fname;						if (cnt > 1) {				size = 0;				$.each(files, function(h, f) { 					if (f.size && f.size != 'unknown' && f.mime !== 'directory') {						var s = parseInt(f.size);						if (s >= 0 && size >= 0) {							size += s;						}					} else {						size = 'unknown';						return false;					}				});				getSize = (size === 'unknown');				descs.push(fm.i18n('size')+': '+(getSize? spinner : fm.formatSize(size)));				text = [$(tpl.replace('{class}', 'elfinder-cwd-icon-group').replace('{title}', '<strong>' + fm.i18n('items')+ ': ' + cnt + '</strong>').replace('{desc}', descs.join('<br>')))];			} else {				f = files[0];				tmb = fm.tmb(f);				getSize = (f.mime === 'directory');				descs.push(fm.i18n('size')+': '+(getSize? spinner : fm.formatSize(f.size)));				descs.push(fm.i18n('modify')+': '+fm.formatDate(f));				fname = fm.escape(f.i18 || f.name).replace(/([_.])/g, '​$1');				text = [$(tpl.replace('{class}', fm.mime2class(f.mime)).replace('{title}', '<strong>' + fname + '</strong>').replace('{desc}', descs.join('<br>')))];			}						if (addTexts) {				text = text.concat(addTexts);			}						text.push(tHash? 'confirmTrash' : 'confirmRm');						dialog = fm.confirm({				title  : self.title,				text   : text,				accept : {					label    : 'btnRm',					callback : function() {  						if (tHash) {							self.toTrash(dfrd, targets, tHash);						} else {							remove(dfrd, targets);						}					}				},				cancel : {					label    : 'btnCancel',					callback : function() {						fm.unlockfiles({files : targets});						if (targets.length === 1 && fm.file(targets[0]).phash !== cwd) {							fm.select({selected : targets});						} else {							fm.selectfiles({files : targets});						}						dfrd.reject();					}				}			});			// load thumbnail			if (tmb) {				$('<img/>')					.on('load', function() { dialog.find('.elfinder-cwd-icon').addClass(tmb.className).css('background-image', "url('"+tmb.url+"')"); })					.attr('src', tmb.url);			}						if (getSize) {				getSize = fm.getSize($.map(files, function(f) { return f.mime === 'directory'? f.hash : null; })).done(function(data) {					dialog.find('span.elfinder-spinner').parent().html(fm.i18n('size')+': '+data.formated);				}).fail(function() {					dialog.find('span.elfinder-spinner').parent().html(fm.i18n('size')+': '+fm.i18n('unknown'));				}).always(function() {					getSize = false;				});			}		},		toTrash = function(dfrd, targets, tHash) {			var dsts = {},				itemCnt = targets.length,				maxCnt = self.options.toTrashMaxItems,				checkDirs = [],				reqDfd = $.Deferred(),				req, dirs, cnt;						if (itemCnt > maxCnt) {				self.confirm(dfrd, targets, self.files(targets), null, [fm.i18n('tooManyToTrash')]);				return;			}						// Directory preparation preparation and directory enumeration			$.each(targets, function(i, h) {				var file = fm.file(h),					path = fm.path(h).replace(/\\/g, '/'),					m = path.match(/^[^\/]+?(\/(?:[^\/]+?\/)*)[^\/]+?$/);								if (file) {					if (m) {						m[1] = m[1].replace(/(^\/.*?)\/?$/, '$1');						if (! dsts[m[1]]) {							dsts[m[1]] = [];						}						dsts[m[1]].push(h);					}					if (file.mime === 'directory') {						checkDirs.push(h);					}				}			});						// Check directory information			if (checkDirs.length) {				req = fm.request({					data : {cmd : 'size', targets : checkDirs},					notify : {type: 'readdir', cnt: 1, hideCnt: true},					preventDefault : true				}).done(function(data) {					var cnt = 0;					data.fileCnt && (cnt += parseInt(data.fileCnt));					data.dirCnt && (cnt += parseInt(data.dirCnt));					reqDfd[cnt > maxCnt ? 'reject' : 'resolve']();				}).fail(function() {					reqDfd.reject();				});				setTimeout(function() {					var xhr = (req && req.xhr)? req.xhr : null;					if (xhr && xhr.state() == 'pending') {						req.syncOnFail(false);						req.reject();						reqDfd.reject();					}				}, self.options.infoCheckWait * 1000);			} else {				reqDfd.resolve();			}						// Directory creation and paste command execution			reqDfd.done(function() {				dirs = Object.keys(dsts);				cnt = dirs.length;				if (cnt) {					fm.request({						data   : {cmd  : 'mkdir', target : tHash, dirs : dirs}, 						notify : {type : 'chkdir', cnt : cnt},						preventFail : true					})					.fail(function(error) {						dfrd.reject(error);						fm.unlockfiles({files : targets});					})					.done(function(data) {						var margeRes = function(data, phash, reqData) {								var undo, prevUndo, redo, prevRedo;								$.each(data, function(k, v) {									if (Array.isArray(v)) {										if (res[k]) {											res[k] = res[k].concat(v);										} else {											res[k] = v;										}									}								});								if (data.sync) {									res.sync = 1;								}								if (data.added && data.added.length) {									undo = function() {										var targets = [],											dirs    = $.map(data.added, function(f) { return f.mime === 'directory'? f.hash : null; });										$.each(data.added, function(i, f) {											if ($.inArray(f.phash, dirs) === -1) {												targets.push(f.hash);											}										});										return fm.exec('restore', targets, {noToast: true});									};									redo = function() {										return fm.request({											data   : reqData,											notify : {type : 'redo', cnt : targets.length}										});									};									if (res.undo) {										prevUndo = res.undo;										res.undo = function() {											undo();											prevUndo();										};									} else {										res.undo = undo;									}									if (res.redo) {										prevRedo = res.redo;										res.redo = function() {											redo();											prevRedo();										};									} else {										res.redo = redo;									}								}							},							err = ['errTrash'],							res = {},							hasNtf = function() {								return fm.ui.notify.children('.elfinder-notify-trash').length;							},							hashes, tm, prg, prgSt;												if (hashes = data.hashes) {							prg = 1 / cnt * 100;							prgSt = cnt === 1? 100 : 5;							tm = setTimeout(function() {								fm.notify({type : 'trash', cnt : 1, hideCnt : true, progress : prgSt});							}, fm.notifyDelay);							$.each(dsts, function(dir, files) {								var phash = fm.file(files[0]).phash,									reqData;								if (hashes[dir]) {									reqData = {cmd : 'paste', dst : hashes[dir], targets : files, cut : 1};									fm.request({										data : reqData,										preventDefault : true									})									.fail(function(error) {										if (error) {											err = err.concat(error);										}									})									.done(function(data) {										data = fm.normalize(data);										fm.updateCache(data);										margeRes(data, phash, reqData);										if (data.warning) {											err = err.concat(data.warning);											delete data.warning;										}										// fire some event to update cache/ui										data.removed && data.removed.length && fm.remove(data);										data.added   && data.added.length   && fm.add(data);										data.changed && data.changed.length && fm.change(data);										// fire event with command name										fm.trigger('paste', data);										// fire event with command name + 'done'										fm.trigger('pastedone');										// force update content										data.sync && fm.sync();									})									.always(function() {										var hashes = [], addTexts, end = 2;										if (hasNtf()) {											fm.notify({type : 'trash', cnt : 0, hideCnt : true, progress : prg});										} else {											prgSt+= prg;										}										if (--cnt < 1) {											tm && clearTimeout(tm);											hasNtf() && fm.notify({type : 'trash', cnt  : -1});											fm.unlockfiles({files : targets});											if (Object.keys(res).length) {												if (err.length > 1) {													if (res.removed || res.removed.length) {														hashes = $.grep(targets, function(h) {															return $.inArray(h, res.removed) === -1? true : false;														});													}													if (hashes.length) {														if (err.length > end) {															end = (fm.messages[err[end-1]] || '').indexOf('$') === -1? end : end + 1;														}														dfrd.reject();														fm.exec('rm', hashes, { addTexts: err.slice(0, end), forceRm: true });													} else {														fm.error(err);													}												}												res._noSound = true;												if (res.undo && res.redo) {													res.undo = {														cmd : 'trash',														callback : res.undo,													};													res.redo = {														cmd : 'trash',														callback : res.redo													};												}												dfrd.resolve(res);											} else {												dfrd.reject(err);											}										}									});								}							});						} else {							dfrd.reject('errFolderNotFound');							fm.unlockfiles({files : targets});						}					});				} else {					dfrd.reject(['error', 'The folder hierarchy to be deleting can not be determined.']);					fm.unlockfiles({files : targets});				}			}).fail(function() {				self.confirm(dfrd, targets, self.files(targets), null, [fm.i18n('tooManyToTrash')]);			});		},		remove = function(dfrd, targets, quiet) {			var notify = quiet? {} : {type : 'rm', cnt : targets.length};			fm.request({				data   : {cmd  : 'rm', targets : targets}, 				notify : notify,				preventFail : true			})			.fail(function(error) {				dfrd.reject(error);			})			.done(function(data) {				if (data.error || data.warning) {					data.sync = true;				}				dfrd.resolve(data);			})			.always(function() {				fm.unlockfiles({files : targets});			});		},		getTHash = function(targets) {			var thash = null,				root1st;						if (targets && targets.length) {				if (targets.length > 1 && fm.searchStatus.state === 2) {					root1st = fm.file(fm.root(targets[0])).volumeid;					if (!$.grep(targets, function(h) { return h.indexOf(root1st) !== 0? true : false ; }).length) {						thash = fm.option('trashHash', targets[0]);					}				} else {					thash = fm.option('trashHash', targets[0]);				}			}			return thash;		},		getSize = false;		// for to be able to overwrite	this.confirm = confirm;	this.toTrash = toTrash;	this.remove = remove;	this.syncTitleOnChange = true;	this.updateOnSelect = false;	this.shortcuts = [{		pattern     : 'delete ctrl+backspace shift+delete'	}];	this.value = 'rm';		this.init = function() {		// re-assign for extended command		self = this;		fm = this.fm;		// bind function of change		self.change(function() {			var targets;			delete self.extra;			self.title = fm.i18n('cmd' + self.value);			self.className = self.value;			self.button && self.button.children('span.elfinder-button-icon')[self.value === 'trash'? 'addClass' : 'removeClass']('elfinder-button-icon-trash');			if (self.value === 'trash') {				self.extra = {					icon: 'rm',					node: $('<span/>')						.attr({title: fm.i18n('cmdrm')})						.on('ready', function(e, data) {							targets = data.targets;						})						.on('click touchstart', function(e){							if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {								return;							}							e.stopPropagation();							e.preventDefault();							fm.getUI().trigger('click'); // to close the context menu immediately							fm.exec('rm', targets, {_userAction: true, forceRm : true});						})				};			}		});	};		this.getstate = function(select) {		var sel   = this.hashes(select);				return sel.length && $.grep(sel, function(h) { var f = fm.file(h); return f && ! f.locked && ! fm.isRoot(f)? true : false; }).length == sel.length			? 0 : -1;	};		this.exec = function(hashes, cOpts) {		var opts   = cOpts || {},			dfrd   = $.Deferred()				.always(function() {					if (getSize && getSize.state && getSize.state() === 'pending') {						getSize.reject();					}				})				.fail(function(error) {					error && fm.error(error);				}).done(function(data) {					!opts.quiet && !data._noSound && data.removed && data.removed.length && fm.trigger('playsound', {soundFile : 'rm.wav'});				}),			files  = self.files(hashes),			cnt    = files.length,			tHash  = null,			addTexts = opts.addTexts? opts.addTexts : null,			forceRm = opts.forceRm,			quiet = opts.quiet,			targets;		if (! cnt) {			return dfrd.reject();		}				$.each(files, function(i, file) {			if (fm.isRoot(file)) {				return !dfrd.reject(['errRm', file.name, 'errPerm']);			}			if (file.locked) {				return !dfrd.reject(['errLocked', file.name]);			}		});		if (dfrd.state() === 'pending') {			targets = self.hashes(hashes);			cnt     = files.length;						if (forceRm || (self.event && self.event.originalEvent && self.event.originalEvent.shiftKey)) {				tHash = '';				self.title = fm.i18n('cmdrm');			}						if (tHash === null) {				tHash = getTHash(targets);			}						fm.lockfiles({files : targets});						if (tHash && self.options.quickTrash) {				self.toTrash(dfrd, targets, tHash);			} else {				if (quiet) {					remove(dfrd, targets, quiet);				} else {					self.confirm(dfrd, targets, files, tHash, addTexts);				}			}		}					return dfrd;	};	fm.bind('select contextmenucreate closecontextmenu', function(e) {		var targets = (e.data? (e.data.selected || e.data.targets) : null) || fm.selected();		if (targets && targets.length) {			self.update(void(0), (targets? getTHash(targets) : fm.option('trashHash'))? 'trash' : 'rm');		}	});};/* * File: /js/commands/search.js *//** * @class  elFinder command "search" * Find files * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.search = function() {	"use strict";	this.title          = 'Find files';	this.options        = {ui : 'searchbutton'};	this.alwaysEnabled  = true;	this.updateOnSelect = false;		/**	 * Return command status.	 * Search does not support old api.	 *	 * @return Number	 **/	this.getstate = function() {		return 0;	};		/**	 * Send search request to backend.	 *	 * @param  String  search string	 * @return $.Deferred	 **/	this.exec = function(q, target, mime, type) {		var fm = this.fm,			reqDef = [],			sType = type || '',			onlyMimes = fm.options.onlyMimes,			phash, targetVolids = [],			setType = function(data) {				if (sType && sType !== 'SearchName' && sType !== 'SearchMime') {					data.type = sType;				}				return data;			};				if (typeof q == 'string' && q) {			if (typeof target == 'object') {				mime = target.mime || '';				target = target.target || '';			}			target = target? target : '';			if (mime) {				mime = $.trim(mime).replace(',', ' ').split(' ');				if (onlyMimes.length) {					mime = $.map(mime, function(m){ 						m = $.trim(m);						return m && ($.inArray(m, onlyMimes) !== -1									|| $.grep(onlyMimes, function(om) { return m.indexOf(om) === 0? true : false; }).length									)? m : null;					});				}			} else {				mime = [].concat(onlyMimes);			}			fm.trigger('searchstart', setType({query : q, target : target, mimes : mime}));						if (! onlyMimes.length || mime.length) {				if (target === '' && fm.api >= 2.1) {					$.each(fm.roots, function(id, hash) {						reqDef.push(fm.request({							data   : setType({cmd : 'search', q : q, target : hash, mimes : mime}),							notify : {type : 'search', cnt : 1, hideCnt : (reqDef.length? false : true)},							cancel : true,							preventDone : true						}));					});				} else {					reqDef.push(fm.request({						data   : setType({cmd : 'search', q : q, target : target, mimes : mime}),						notify : {type : 'search', cnt : 1, hideCnt : true},						cancel : true,						preventDone : true					}));					if (target !== '' && fm.api >= 2.1 && Object.keys(fm.leafRoots).length) {						$.each(fm.leafRoots, function(hash, roots) {							phash = hash;							while(phash) {								if (target === phash) {									$.each(roots, function() {										var f = fm.file(this);										f && f.volumeid && targetVolids.push(f.volumeid);										reqDef.push(fm.request({											data   : setType({cmd : 'search', q : q, target : this, mimes : mime}),											notify : {type : 'search', cnt : 1, hideCnt : false},											cancel : true,											preventDone : true										}));									});								}								phash = (fm.file(phash) || {}).phash;							}						});					}				}			} else {				reqDef = [$.Deferred().resolve({files: []})];			}						fm.searchStatus.mixed = (reqDef.length > 1)? targetVolids : false;						return $.when.apply($, reqDef).done(function(data) {				var argLen = arguments.length,					i;								data.warning && fm.error(data.warning);								if (argLen > 1) {					data.files = (data.files || []);					for(i = 1; i < argLen; i++) {						arguments[i].warning && fm.error(arguments[i].warning);												if (arguments[i].files) {							data.files.push.apply(data.files, arguments[i].files);						}					}				}								// because "preventDone : true" so update files cache				data.files && data.files.length && fm.cache(data.files);								fm.lazy(function() {					fm.trigger('search', data);				}).then(function() {					// fire event with command name + 'done'					return fm.lazy(function() {						fm.trigger('searchdone');					});				}).then(function() {					// force update content					data.sync && fm.sync();				});			});		}		fm.getUI('toolbar').find('.'+fm.res('class', 'searchbtn')+' :text').trigger('focus');		return $.Deferred().reject();	};};/* * File: /js/commands/selectall.js *//** * @class  elFinder command "selectall" * Select ALL of cwd items * * @author Naoki Sawada **/elFinder.prototype.commands.selectall = function() {	"use strict";	var self = this,		state = 0;		this.fm.bind('select', function(e) {		state = (e.data && e.data.selectall)? -1 : 0;	});		this.state = 0;	this.updateOnSelect = false;		this.getstate = function() {		return state;	};		this.exec = function() {		$(document).trigger($.Event('keydown', { keyCode: 65, ctrlKey : true, shiftKey : false, altKey : false, metaKey : false }));		return $.Deferred().resolve();	};};/* * File: /js/commands/selectinvert.js *//** * @class  elFinder command "selectinvert" * Invert Selection of cwd items * * @author Naoki Sawada **/elFinder.prototype.commands.selectinvert = function() {	"use strict";	this.updateOnSelect = false;		this.getstate = function() {		return 0;	};		this.exec = function() {		$(document).trigger($.Event('keydown', { keyCode: 73, ctrlKey : true, shiftKey : true, altKey : false, metaKey : false }));		return $.Deferred().resolve();	};};/* * File: /js/commands/selectnone.js *//** * @class  elFinder command "selectnone" * Unselect ALL of cwd items * * @author Naoki Sawada **/elFinder.prototype.commands.selectnone = function() {	"use strict";	var self = this,		fm = this.fm,		state = -1;		fm.bind('select', function(e) {		state = (e.data && e.data.unselectall)? -1 : 0;	});		this.state = -1;	this.updateOnSelect = false;		this.getstate = function() {		return state;	};		this.exec = function() {		fm.getUI('cwd').trigger('unselectall');		return $.Deferred().resolve();	};};/* * File: /js/commands/sort.js *//** * @class  elFinder command "sort" * Change sort files rule * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.sort = function() {	"use strict";	var self  = this,		fm    = self.fm,		setVar = function() {			self.variants = [];			$.each(fm.sortRules, function(name, value) {				if (fm.sorters[name]) {					var arr = (name === fm.sortType)? (fm.sortOrder === 'asc'? 'n' : 's') : '';					self.variants.push([name, (arr? '<span class="ui-icon ui-icon-arrowthick-1-'+arr+'"></span>' : '') + ' ' + fm.i18n('sort'+name)]);				}			});			self.variants.push('|');			self.variants.push([				'stick',				(fm.sortStickFolders? '<span class="ui-icon ui-icon-check"/>' : '') + ' ' + fm.i18n('sortFoldersFirst')			]);			if (fm.ui.tree) {				self.variants.push('|');				self.variants.push([					'tree',					(fm.sortAlsoTreeview? '<span class="ui-icon ui-icon-check"/>' : '') + ' ' + fm.i18n('sortAlsoTreeview')				]);			}			updateContextmenu();		},		updateContextmenu = function() {			var cm = fm.getUI('contextmenu'),				icon, sub;			if (cm.is(':visible')) {				icon = cm.find('span.elfinder-button-icon-sort');				sub = icon.siblings('div.elfinder-contextmenu-sub');				sub.find('span.ui-icon').remove();				sub.children('div.elfinder-contextsubmenu-item').each(function() {					var tgt = $(this).children('span'),						name = tgt.text().trim(),						arr;					if (name === (i18Name.stick || (i18Name.stick = fm.i18n('sortFoldersFirst')))) {						if (fm.sortStickFolders) {							tgt.prepend('<span class="ui-icon ui-icon-check"/>');						}					} else if (name === (i18Name.tree || (i18Name.tree = fm.i18n('sortAlsoTreeview')))) {						if (fm.sortAlsoTreeview) {							tgt.prepend('<span class="ui-icon ui-icon-check"/>');						}					} else if (name === (i18Name[fm.sortType] || (i18Name[fm.sortType] = fm.i18n('sort' + fm.sortType)))) {						arr = fm.sortOrder === 'asc'? 'n' : 's';						tgt.prepend('<span class="ui-icon ui-icon-arrowthick-1-'+arr+'"></span>');					}				});			}		},		i18Name = {};		/**	 * Command options	 *	 * @type  Object	 */	this.options = {ui : 'sortbutton'};		this.keepContextmenu = true;	fm.bind('sortchange', setVar)	.bind('sorterupdate', function() {		setVar();		fm.getUI('toolbar').find('.elfiner-button-sort .elfinder-button-menu .elfinder-button-menu-item').each(function() {			var tgt = $(this),				rel = tgt.attr('rel');			tgt.toggle(! rel || fm.sorters[rel]);		});	})	.bind('cwdrender', function() {		var cols = $(fm.cwd).find('div.elfinder-cwd-wrapper-list table');		if (cols.length) {			$.each(fm.sortRules, function(name, value) {				var td = cols.find('thead tr td.elfinder-cwd-view-th-'+name);				if (td.length) {					var current = ( name == fm.sortType),					sort = {						type  : name,						order : current ? fm.sortOrder == 'asc' ? 'desc' : 'asc' : fm.sortOrder					},arr;					if (current) {						td.addClass('ui-state-active');						arr = fm.sortOrder == 'asc' ? 'n' : 's';						$('<span class="ui-icon ui-icon-triangle-1-'+arr+'"/>').appendTo(td);					}					$(td).on('click', function(e){						if (! $(this).data('dragging')) {							e.stopPropagation();							if (! fm.getUI('cwd').data('longtap')) {								fm.exec('sort', [], sort);							}						}					})					.on('mouseenter mouseleave', function(e) {						$(this).toggleClass('ui-state-hover', e.type === 'mouseenter');					});				}							});		}	});		this.getstate = function() {		return 0;	};		this.exec = function(hashes, cOpt) {		var fm = this.fm,			sortopt = $.isPlainObject(cOpt)? cOpt : (function() {				cOpt += '';				var sOpts = {};				if (cOpt === 'stick') {					sOpts.stick = !fm.sortStickFolders;				} else if (cOpt === 'tree') {					sOpts.tree = !fm.sortAlsoTreeview;				} else if (fm.sorters[cOpt]) {					if (fm.sortType === cOpt) {						sOpts.order = fm.sortOrder === 'asc'? 'desc' : 'asc';					} else {						sOpts.type = cOpt;					}				}				return sOpts;			})(),			sort = Object.assign({				type  : fm.sortType,				order : fm.sortOrder,				stick : fm.sortStickFolders,				tree  : fm.sortAlsoTreeview			}, sortopt);		return fm.lazy(function() {			fm.setSort(sort.type, sort.order, sort.stick, sort.tree);			this.resolve();		});	};};/* * File: /js/commands/undo.js *//** * @class  elFinder command "undo" * Undo previous commands * * @author Naoki Sawada **/elFinder.prototype.commands.undo = function() {	"use strict";	var self = this,		fm = this.fm,		setTitle = function(undo) {			if (undo) {				self.title = fm.i18n('cmdundo') + ' ' + fm.i18n('cmd'+undo.cmd);				self.state = 0;			} else {				self.title = fm.i18n('cmdundo');				self.state = -1;			}			self.change();		},		cmds = [];		this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.shortcuts      = [{		pattern     : 'ctrl+z'	}];	this.syncTitleOnChange = true;		this.getstate = function() {		return cmds.length? 0 : -1;	};		this.setUndo = function(undo, redo) {		var _undo = {};		if (undo) {			if ($.isPlainObject(undo) && undo.cmd && undo.callback) {				Object.assign(_undo, undo);				if (redo) {					delete redo.undo;					_undo.redo = redo;				} else {					fm.getCommand('redo').setRedo(null);				}				cmds.push(_undo);				setTitle(_undo);			}		}	};		this.exec = function() {		var redo = fm.getCommand('redo'),			dfd = $.Deferred(),			undo, res, _redo = {};		if (cmds.length) {			undo = cmds.pop();			if (undo.redo) {				Object.assign(_redo, undo.redo);				delete undo.redo;			} else {				_redo = null;			} 			dfd.done(function() {				if (_redo) {					redo.setRedo(_redo, undo);				}			});						setTitle(cmds.length? cmds[cmds.length-1] : void(0));						res = undo.callback();						if (res && res.done) {				res.done(function() {					dfd.resolve();				}).fail(function() {					dfd.reject();				});			} else {				dfd.resolve();			}			if (cmds.length) {				this.update(0, cmds[cmds.length - 1].name);			} else {				this.update(-1, '');			}		} else {			dfd.reject();		}		return dfd;	};		fm.bind('exec', function(e) {		var data = e.data || {};		if (data.opts && data.opts._userAction) {			if (data.dfrd && data.dfrd.done) {				data.dfrd.done(function(res) {					if (res && res.undo && res.redo) {						res.undo.redo = res.redo;						self.setUndo(res.undo);					}				});			}		}	});};/** * @class  elFinder command "redo" * Redo previous commands * * @author Naoki Sawada **/elFinder.prototype.commands.redo = function() {	"use strict";	var self = this,		fm   = this.fm,		setTitle = function(redo) {			if (redo && redo.callback) {				self.title = fm.i18n('cmdredo') + ' ' + fm.i18n('cmd'+redo.cmd);				self.state = 0;			} else {				self.title = fm.i18n('cmdredo');				self.state = -1;			}			self.change();		},		cmds = [];		this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.shortcuts      = [{		pattern     : 'shift+ctrl+z ctrl+y'	}];	this.syncTitleOnChange = true;		this.getstate = function() {		return cmds.length? 0 : -1;	};		this.setRedo = function(redo, undo) {		if (redo === null) {			cmds = [];			setTitle();		} else {			if (redo && redo.cmd && redo.callback) {				if (undo) {					redo.undo = undo;				}				cmds.push(redo);				setTitle(redo);			}		}	};		this.exec = function() {		var undo = fm.getCommand('undo'),			dfd = $.Deferred(),			redo, res, _undo = {}, _redo = {};		if (cmds.length) {			redo = cmds.pop();			if (redo.undo) {				Object.assign(_undo, redo.undo);				Object.assign(_redo, redo);				delete _redo.undo;				dfd.done(function() {					undo.setUndo(_undo, _redo);				});			}						setTitle(cmds.length? cmds[cmds.length-1] : void(0));						res = redo.callback();						if (res && res.done) {				res.done(function() {					dfd.resolve();				}).fail(function() {					dfd.reject();				});			} else {				dfd.resolve();			}			return dfd;		} else {			return dfd.reject();		}	};};/* * File: /js/commands/up.js *//** * @class  elFinder command "up" * Go into parent directory * * @author Dmitry (dio) Levashov **/(elFinder.prototype.commands.up = function() {	"use strict";	this.alwaysEnabled = true;	this.updateOnSelect = false;		this.shortcuts = [{		pattern     : 'ctrl+up'	}];		this.getstate = function() {		return this.fm.cwd().phash ? 0 : -1;	};		this.exec = function() {		var fm = this.fm,			cwdhash = fm.cwd().hash;		return this.fm.cwd().phash ? this.fm.exec('open', this.fm.cwd().phash).done(function() {			fm.one('opendone', function() {				fm.selectfiles({files : [cwdhash]});			});		}) : $.Deferred().reject();	};}).prototype = { forceLoad : true }; // this is required command/* * File: /js/commands/upload.js *//** * @class elFinder command "upload" * Upload files using iframe or XMLHttpRequest & FormData. * Dialog allow to send files using drag and drop * * @type  elFinder.command * @author  Dmitry (dio) Levashov */elFinder.prototype.commands.upload = function() {	"use strict";	var hover = this.fm.res('class', 'hover');		this.disableOnSearch = true;	this.updateOnSelect  = false;		// Shortcut opens dialog	this.shortcuts = [{		pattern     : 'ctrl+u'	}];		/**	 * Return command state	 *	 * @return Number	 **/	this.getstate = function(select) {		var fm = this.fm, f,		sel = (select || [fm.cwd().hash]);		if (!this._disabled && sel.length == 1) {			f = fm.file(sel[0]);		}		return (f && f.mime == 'directory' && f.write)? 0 : -1;	};			this.exec = function(data) {		var fm = this.fm,			cwdHash = fm.cwd().hash,			getTargets = function() {				var tgts = data && (data instanceof Array)? data : null,					sel;				if (! data || data instanceof Array) {					if (! tgts && (sel = fm.selected()).length === 1 && fm.file(sel[0]).mime === 'directory') {						tgts = sel;					} else if (!tgts || tgts.length !== 1 || fm.file(tgts[0]).mime !== 'directory') {						tgts = [ cwdHash ];					}				}				return tgts;			},			targets = getTargets(),			check = targets? targets[0] : (data && data.target? data.target : null),			targetDir = check? fm.file(check) : fm.cwd(),			fmUpload = function(data) {				fm.upload(data)					.fail(function(error) {						dfrd.reject(error);					})					.done(function(data) {						var cwd = fm.getUI('cwd'),							node;						dfrd.resolve(data);						if (data && data.added && data.added[0] && ! fm.ui.notify.children('.elfinder-notify-upload').length) {							var newItem = fm.findCwdNodes(data.added);							if (newItem.length) {								newItem.trigger('scrolltoview');							} else {								if (targetDir.hash !== cwdHash) {									node = $('<div/>').append(										$('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all elfinder-tabstop"><span class="ui-button-text">'+fm.i18n('cmdopendir')+'</span></button>')										.on('mouseenter mouseleave', function(e) { 											$(this).toggleClass('ui-state-hover', e.type == 'mouseenter');										}).on('click', function() {											fm.exec('open', check).done(function() {												fm.one('opendone', function() {													fm.trigger('selectfiles', {files : $.map(data.added, function(f) {return f.hash;})});												});											});										})									);								} else {									fm.trigger('selectfiles', {files : $.map(data.added, function(f) {return f.hash;})});								}								fm.toast({msg: fm.i18n(['complete', fm.i18n('cmdupload')]), extNode: node});							}						}					})					.progress(function() {						dfrd.notifyWith(this, Array.from(arguments));					});			},			upload = function(data) {				dialog.elfinderdialog('close');				if (targets) {					data.target = targets[0];				}				fmUpload(data);			},			getSelector = function() {				var hash = targetDir.hash,					dirs = $.map(fm.files(hash), function(f) {						return (f.mime === 'directory' && f.write)? f : null; 					});								if (! dirs.length) {					return $();				}								return $('<div class="elfinder-upload-dirselect elfinder-tabstop" title="' + fm.i18n('folders') + '"/>')				.on('click', function(e) {					e.stopPropagation();					e.preventDefault();					dirs = fm.sortFiles(dirs);					var $this  = $(this),						cwd    = fm.cwd(),						base   = dialog.closest('div.ui-dialog'),						getRaw = function(f, icon) {							return {								label    : fm.escape(f.i18 || f.name),								icon     : icon,								remain   : false,								callback : function() {									var title = base.children('.ui-dialog-titlebar:first').find('span.elfinder-upload-target');									targets = [ f.hash ];									title.html(' - ' + fm.escape(f.i18 || f.name));									$this.trigger('focus');								},								options  : {									className : (targets && targets.length && f.hash === targets[0])? 'ui-state-active' : '',									iconClass : f.csscls || '',									iconImg   : f.icon   || ''								}							};						},						raw = [ getRaw(targetDir, 'opendir'), '|' ];					$.each(dirs, function(i, f) {						raw.push(getRaw(f, 'dir'));					});					$this.trigger('blur');					fm.trigger('contextmenu', {						raw: raw,						x: e.pageX || $(this).offset().left,						y: e.pageY || $(this).offset().top,						prevNode: base,						fitHeight: true					});				}).append('<span class="elfinder-button-icon elfinder-button-icon-dir" />');			},			inputButton = function(type, caption) {				var button,					input = $('<input type="file" ' + type + '/>')					.on('click', function() {						// for IE's bug						if (fm.UA.IE) {							setTimeout(function() {								form.css('display', 'none').css('position', 'relative');								requestAnimationFrame(function() {									form.css('display', '').css('position', '');								});							}, 100);						}					})					.on('change', function() {						upload({input : input.get(0), type : 'files'});					})					.on('dragover', function(e) {						e.originalEvent.dataTransfer.dropEffect = 'copy';					}),					form = $('<form/>').append(input);				return $('<div class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only elfinder-tabstop elfinder-focus"><span class="ui-button-text">'+fm.i18n(caption)+'</span></div>')					.append(form)					.on('click', function(e) {						if (e.target === this) {							e.stopPropagation();							e.preventDefault();							input.trigger('click');						}					})					.on('mouseenter mouseleave', function(e) {						$(this).toggleClass(hover, e.type === 'mouseenter');					});			},			dfrd = $.Deferred(),			dialog, dropbox, pastebox, dropUpload, paste, dirs, spinner, uidialog;				dropUpload = function(e) {			e.stopPropagation();			e.preventDefault();			var file = false,				type = '',				elfFrom = null,				mycwd = '',				data = null,				target = e._target || null,				trf = e.dataTransfer || null,				kind = (trf.items && trf.items.length && trf.items[0].kind)? trf.items[0].kind : '',				errors;						if (trf) {				try {					elfFrom = trf.getData('elfinderfrom');					if (elfFrom) {						mycwd = window.location.href + fm.cwd().hash;						if ((!target && elfFrom === mycwd) || target === mycwd) {							dfrd.reject();							return;						}					}				} catch(e) {}								if (kind === 'file' && (trf.items[0].getAsEntry || trf.items[0].webkitGetAsEntry)) {					file = trf;					type = 'data';				} else if (kind !== 'string' && trf.files && trf.files.length && $.inArray('Text', trf.types) === -1) {					file = trf.files;					type = 'files';				} else {					try {						if ((data = trf.getData('text/html')) && data.match(/<(?:img|a)/i)) {							file = [ data ];							type = 'html';						}					} catch(e) {}					if (! file) {						if (data = trf.getData('text')) {							file = [ data ];							type = 'text';						} else if (trf && trf.files) {							// maybe folder uploading but this UA dose not support it							kind = 'file';						}					}				}			}			if (file) {				fmUpload({files : file, type : type, target : target, dropEvt : e});			} else {				errors = ['errUploadNoFiles'];				if (kind === 'file') {					errors.push('errFolderUpload');				}				fm.error(errors);				dfrd.reject();			}		};				if (!targets && data) {			if (data.input || data.files) {				data.type = 'files';				fmUpload(data);			} else if (data.dropEvt) {				dropUpload(data.dropEvt);			}			return dfrd;		}				paste = function(ev) {			var e = ev.originalEvent || ev;			var files = [], items = [];			var file;			if (e.clipboardData) {				if (e.clipboardData.items && e.clipboardData.items.length){					items = e.clipboardData.items;					for (var i=0; i < items.length; i++) {						if (e.clipboardData.items[i].kind == 'file') {							file = e.clipboardData.items[i].getAsFile();							files.push(file);						}					}				} else if (e.clipboardData.files && e.clipboardData.files.length) {					files = e.clipboardData.files;				}				if (files.length) {					upload({files : files, type : 'files', clipdata : true});					return;				}			}			var my = e.target || e.srcElement;			requestAnimationFrame(function() {				var type = 'text',					src;				if (my.innerHTML) {					$(my).find('img').each(function(i, v){						if (v.src.match(/^webkit-fake-url:\/\//)) {							// For Safari's bug.							// ref. https://bugs.webkit.org/show_bug.cgi?id=49141							//      https://dev.ckeditor.com/ticket/13029							$(v).remove();						}					});										if ($(my).find('a,img').length) {						type = 'html';					}					src = my.innerHTML;					my.innerHTML = '';					upload({files : [ src ], type : type});				}			});		};				dialog = $('<div class="elfinder-upload-dialog-wrapper"/>')			.append(inputButton('multiple', 'selectForUpload'));				if (! fm.UA.Mobile && (function(input) {			return (typeof input.webkitdirectory !== 'undefined' || typeof input.directory !== 'undefined');})(document.createElement('input'))) {			dialog.append(inputButton('multiple webkitdirectory directory', 'selectFolder'));		}				if (targetDir.dirs) {			if (targetDir.hash === cwdHash || $('#'+fm.navHash2Id(targetDir.hash)).hasClass('elfinder-subtree-loaded')) {				getSelector().appendTo(dialog);			} else {				spinner = $('<div class="elfinder-upload-dirselect" title="' + fm.i18n('nowLoading') + '"/>')					.append('<span class="elfinder-button-icon elfinder-button-icon-spinner" />')					.appendTo(dialog);				fm.request({cmd : 'tree', target : targetDir.hash})					.done(function() { 						fm.one('treedone', function() {							spinner.replaceWith(getSelector());							uidialog.elfinderdialog('tabstopsInit');						});					})					.fail(function() {						spinner.remove();					});			}		}				if (fm.dragUpload) {			dropbox = $('<div class="ui-corner-all elfinder-upload-dropbox elfinder-tabstop" contenteditable="true" data-ph="'+fm.i18n('dropPasteFiles')+'"></div>')				.on('paste', function(e){					paste(e);				})				.on('mousedown click', function(){					$(this).trigger('focus');				})				.on('focus', function(){					this.innerHTML = '';				})				.on('mouseover', function(){					$(this).addClass(hover);				})				.on('mouseout', function(){					$(this).removeClass(hover);				})				.on('dragenter', function(e) {					e.stopPropagation();				  	e.preventDefault();				  	$(this).addClass(hover);				})				.on('dragleave', function(e) {					e.stopPropagation();				  	e.preventDefault();				  	$(this).removeClass(hover);				})				.on('dragover', function(e) {					e.stopPropagation();				  	e.preventDefault();					e.originalEvent.dataTransfer.dropEffect = 'copy';					$(this).addClass(hover);				})				.on('drop', function(e) {					dialog.elfinderdialog('close');					targets && (e.originalEvent._target = targets[0]);					dropUpload(e.originalEvent);				})				.prependTo(dialog)				.after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')[0];					} else {			pastebox = $('<div class="ui-corner-all elfinder-upload-dropbox" contenteditable="true">'+fm.i18n('dropFilesBrowser')+'</div>')				.on('paste drop', function(e){					paste(e);				})				.on('mousedown click', function(){					$(this).trigger('focus');				})				.on('focus', function(){					this.innerHTML = '';				})				.on('dragenter mouseover', function(){					$(this).addClass(hover);				})				.on('dragleave mouseout', function(){					$(this).removeClass(hover);				})				.prependTo(dialog)				.after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')[0];					}				uidialog = this.fmDialog(dialog, {			title          : this.title + '<span class="elfinder-upload-target">' + (targetDir? ' - ' + fm.escape(targetDir.i18 || targetDir.name) : '') + '</span>',			modal          : true,			resizable      : false,			destroyOnClose : true,			propagationEvents : ['mousemove', 'mouseup', 'click'],			close          : function() {				var cm = fm.getUI('contextmenu');				if (cm.is(':visible')) {					cm.click();				}			}		});				return dfrd;	};};/* * File: /js/commands/view.js *//** * @class  elFinder command "view" * Change current directory view (icons/list) * * @author Dmitry (dio) Levashov **/elFinder.prototype.commands.view = function() {	"use strict";	var self = this,		fm = this.fm,		subMenuRaw;	this.value          = fm.viewType;	this.alwaysEnabled  = true;	this.updateOnSelect = false;	this.options = { ui : 'viewbutton'};		this.getstate = function() {		return 0;	};		this.extra = {		icon: 'menu',		node: $('<span/>')			.attr({title: fm.i18n('viewtype')})			.on('click touchstart', function(e){				if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {					return;				}				var node = $(this);				e.stopPropagation();				e.preventDefault();				fm.trigger('contextmenu', {					raw: getSubMenuRaw(),					x: node.offset().left,					y: node.offset().top				});			})	};	this.exec = function() {		var self  = this,			value = fm.storage('view', this.value == 'list' ? 'icons' : 'list');		return fm.lazy(function() {			fm.viewchange();			self.update(void(0), value);			this.resolve();		});	};	fm.bind('init', function() {		subMenuRaw = (function() {			var cwd = fm.getUI('cwd'),				raws = [],				sizeNames = fm.options.uiOptions.cwd.iconsView.sizeNames,				max = fm.options.uiOptions.cwd.iconsView.sizeMax,				i, size;			for (i = 0; i <= max; i++) {				raws.push(					{						label    : fm.i18n(sizeNames[i] || ('Size-' + i + ' icons')),						icon     : 'view',						callback : (function(s) {							return function() {								cwd.trigger('iconpref', {size: s});								fm.storage('iconsize', s);								if (self.value === 'list') {									self.exec();								}							};						})(i)					}				);			}			raws.push('|');			raws.push(				{					label    : fm.i18n('viewlist'),					icon     : 'view-list',					callback : function() {						if (self.value !== 'list') {							self.exec();						}					}				}					);			return raws;		})();	}).bind('contextmenucreate', function() {		self.extra = {			icon: 'menu',			node: $('<span/>')				.attr({title: fm.i18n('cmdview')})				.on('click touchstart', function(e){					if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {						return;					}					var node = $(this),						raw = subMenuRaw.concat(),						idx, i;					if (self.value === 'list') {						idx = subMenuRaw.length - 1;					} else {						idx = parseInt(fm.storage('iconsize') || 0);					}					for (i = 0; i < subMenuRaw.length; i++) {						if (subMenuRaw[i] !== '|') {							subMenuRaw[i].options = (i === idx? {'className': 'ui-state-active'} : void(0))							;						}					}					e.stopPropagation();					e.preventDefault();					fm.trigger('contextmenu', {						raw: subMenuRaw,						x: node.offset().left,						y: node.offset().top					});				})		};	});};return elFinder;}));
 |