MOON
Server: Apache
System: Linux res.emeff.ca 3.10.0-962.3.2.lve1.5.24.10.el7.x86_64 #1 SMP Wed Mar 20 07:36:02 EDT 2019 x86_64
User: accemeff (1004)
PHP: 7.0.33
Disabled: NONE
Upload Files
File: /home/accemeff/vendor/craftcms/cms/lib/fileupload/jquery.fileupload.js.map
{"version":3,"sources":["jquery.fileupload.js"],"names":["factory","define","amd","exports","require","window","jQuery","$","getDragHandler","type","isDragOver","e","dataTransfer","originalEvent","inArray","types","this","_trigger","Event","delegatedEvent","preventDefault","dropEffect","support","fileInput","RegExp","test","navigator","userAgent","prop","xhrFileUpload","ProgressEvent","FileReader","xhrFormDataFileUpload","FormData","blobSlice","Blob","prototype","slice","webkitSlice","mozSlice","widget","options","dropZone","document","pasteZone","undefined","replaceFileInput","paramName","singleFileUploads","limitMultiFileUploads","limitMultiFileUploadSize","limitMultiFileUploadSizeOverhead","sequentialUploads","limitConcurrentUploads","forceIframeTransport","redirect","redirectParamName","postMessage","multipart","maxChunkSize","uploadedBytes","recalculateProgress","progressInterval","bitrateInterval","autoUpload","messages","i18n","message","context","toString","each","key","value","replace","formData","form","serializeArray","add","data","isDefaultPrevented","fileupload","process","done","submit","processData","contentType","cache","timeout","_specialOptions","_blobSlice","apply","arguments","_BitrateTimer","timestamp","Date","now","getTime","loaded","bitrate","getBitrate","interval","timeDiff","_isXHRUpload","_getFormData","isArray","name","push","_getTotal","files","total","index","file","size","_initProgressObject","obj","progress","_progress","extend","_initResponseObject","_response","hasOwnProperty","_onProgress","lengthComputable","_time","Math","floor","chunkSize","_bitrateTimer","_initProgressListener","that","xhr","ajaxSettings","upload","bind","oe","_deinitProgressListener","unbind","_isInstanceOf","Object","call","_initXHRData","headers","contentRange","blob","encodeURI","uploadName","field","append","_initIframeSettings","targetHost","url","dataType","location","host","_initDataSettings","_chunkedUpload","_getParamName","input","i","length","_initFormSettings","href","toUpperCase","formAcceptCharset","attr","_getAJAXSettings","_getDeferredState","deferred","state","isResolved","isRejected","_enhancePromise","promise","success","error","fail","complete","always","_getXHRPromise","resolveOrReject","args","dfd","Deferred","resolveWith","rejectWith","abort","_addConvenienceMethods","getPromise","resolveFunc","rejectFunc","_processQueue","then","errorThrown","jqXHR","_onSend","processing","response","_getUploadedBytes","range","getResponseHeader","parts","split","upperBytesPos","parseInt","testOnly","fs","ub","mcs","o","currentLoaded","ajax","result","textStatus","_beforeSend","_active","_onDone","_onFail","_onAlways","jqXHRorResult","jqXHRorError","aborted","slot","pipe","send","_sending","nextSlot","_slots","shift","resolve","_sequence","_onAdd","paramNameSet","paramNameSlice","fileSet","filesLength","limit","limitSize","overhead","batchSize","j","originalFiles","element","newData","_replaceFileInput","inputClone","clone","restoreFocus","is","activeElement","fileInputClone","reset","after","detach","focus","cleanData","map","el","_handleFileTreeEntry","entry","path","dirReader","entries","errorHandler","readEntries","results","concat","_handleFileTreeEntries","isFile","_file","relativePath","isDirectory","createReader","when","Array","_getDroppedFiles","items","webkitGetAsEntry","getAsEntry","item","getAsFile","makeArray","_getSingleFileInputFiles","fileName","fileSize","_getFileInputFiles","_onChange","target","_onPaste","clipboardData","_onDrop","_onDragOver","_onDragEnter","_onDragLeave","_initEventHandlers","_on","dragover","drop","dragenter","dragleave","paste","change","_destroyEventHandlers","_off","_destroy","_setOption","reinit","_super","_initSpecialOptions","find","_getRegExp","str","modifiers","pop","join","_isRegExpOption","_initDataAttributes","attributes","toLowerCase","charAt","_create","active","disabled","reject"],"mappings":"CAcE,SAAUA,GACR,aACsB,mBAAXC,QAAyBA,OAAOC,IAEvCD,OAAO,CACH,SACA,uBACDD,GACuB,iBAAZG,QAEdH,EACII,QAAQ,UACRA,QAAQ,8BAIZJ,EAAQK,OAAOC,QAhBtB,CAkBC,SAAUC,GACR,aA2BA,SAASC,EAAeC,GACpB,IAAIC,EAAsB,aAATD,EACjB,OAAO,SAAUE,GACbA,EAAEC,aAAeD,EAAEE,eAAiBF,EAAEE,cAAcD,aACpD,IAAIA,EAAeD,EAAEC,aACjBA,IAA4D,IAA5CL,EAAEO,QAAQ,QAASF,EAAaG,SAItC,IAHNC,KAAKC,SACDR,EACAF,EAAEW,MAAMT,EAAM,CAACU,eAAgBR,OAEvCA,EAAES,iBACEV,IACAE,EAAaS,WAAa,UAnC1Cd,EAAEe,QAAQC,YAAc,IAAIC,OAExB,uJAIFC,KAAKpB,OAAOqB,UAAUC,YAEpBpB,EAAE,wBAAwBqB,KAAK,aAOnCrB,EAAEe,QAAQO,iBAAmBxB,OAAOyB,gBAAiBzB,OAAO0B,YAC5DxB,EAAEe,QAAQU,wBAA0B3B,OAAO4B,SAG3C1B,EAAEe,QAAQY,UAAY7B,OAAO8B,OAASA,KAAKC,UAAUC,OACjDF,KAAKC,UAAUE,aAAeH,KAAKC,UAAUG,UA6BjDhC,EAAEiC,OAAO,qBAAsB,CAE3BC,QAAS,CAGLC,SAAUnC,EAAEoC,UAGZC,eAAWC,EAKXtB,eAAWsB,EAKXC,kBAAkB,EAKlBC,eAAWF,EAIXG,mBAAmB,EAGnBC,2BAAuBJ,EAIvBK,8BAA0BL,EAI1BM,iCAAkC,IAGlCC,mBAAmB,EAGnBC,4BAAwBR,EAExBS,sBAAsB,EAGtBC,cAAUV,EAGVW,uBAAmBX,EAGnBY,iBAAaZ,EAIba,WAAW,EAKXC,kBAAcd,EAMde,mBAAef,EAIfgB,qBAAqB,EAErBC,iBAAkB,IAElBC,gBAAiB,IAEjBC,YAAY,EAGZC,SAAU,CACNL,cAAe,mCAKnBM,KAAM,SAAUC,EAASC,GAOrB,OANAD,EAAUnD,KAAKiD,SAASE,IAAYA,EAAQE,WACxCD,GACA7D,EAAE+D,KAAKF,EAAS,SAAUG,EAAKC,GAC3BL,EAAUA,EAAQM,QAAQ,IAAMF,EAAM,IAAKC,KAG5CL,GAQXO,SAAU,SAAUC,GAChB,OAAOA,EAAKC,kBAmBhBC,IAAK,SAAUlE,EAAGmE,GACd,GAAInE,EAAEoE,qBACF,OAAO,GAEPD,EAAKd,aAAmC,IAApBc,EAAKd,YACrBzD,EAAES,MAAMgE,WAAW,SAAU,gBACjCF,EAAKG,UAAUC,KAAK,WAChBJ,EAAKK,YA+DjBC,aAAa,EACbC,aAAa,EACbC,OAAO,EACPC,QAAS,GAKbC,gBAAiB,CACb,YACA,WACA,YACA,YACA,wBAGJC,WAAYlF,EAAEe,QAAQY,WAAa,WAE/B,OADYlB,KAAKqB,OAASrB,KAAKsB,aAAetB,KAAKuB,UACtCmD,MAAM1E,KAAM2E,YAG7BC,cAAe,WACX5E,KAAK6E,UAAcC,KAAQ,IAAIA,KAAKC,OAAQ,IAAKD,MAAQE,UACzDhF,KAAKiF,OAAS,EACdjF,KAAKkF,QAAU,EACflF,KAAKmF,WAAa,SAAUJ,EAAKE,EAAQG,GACrC,IAAIC,EAAWN,EAAM/E,KAAK6E,UAM1B,QALK7E,KAAKkF,UAAYE,GAAuBA,EAAXC,KAC9BrF,KAAKkF,SAAWD,EAASjF,KAAKiF,SAAW,IAAOI,GAAY,EAC5DrF,KAAKiF,OAASA,EACdjF,KAAK6E,UAAYE,GAEd/E,KAAKkF,UAIpBI,aAAc,SAAU7D,GACpB,OAAQA,EAAQa,wBACTb,EAAQiB,WAAanD,EAAEe,QAAQO,eAClCtB,EAAEe,QAAQU,wBAGlBuE,aAAc,SAAU9D,GACpB,IAAIiC,EACJ,MAAiC,aAA7BnE,EAAEE,KAAKgC,EAAQiC,UACRjC,EAAQiC,SAASjC,EAAQkC,MAEhCpE,EAAEiG,QAAQ/D,EAAQiC,UACXjC,EAAQiC,SAEc,WAA7BnE,EAAEE,KAAKgC,EAAQiC,WACfA,EAAW,GACXnE,EAAE+D,KAAK7B,EAAQiC,SAAU,SAAU+B,EAAMjC,GACrCE,EAASgC,KAAK,CAACD,KAAMA,EAAMjC,MAAOA,MAE/BE,GAEJ,IAGXiC,UAAW,SAAUC,GACjB,IAAIC,EAAQ,EAIZ,OAHAtG,EAAE+D,KAAKsC,EAAO,SAAUE,EAAOC,GAC3BF,GAASE,EAAKC,MAAQ,IAEnBH,GAGXI,oBAAqB,SAAUC,GAC3B,IAAIC,EAAW,CACXlB,OAAQ,EACRY,MAAO,EACPX,QAAS,GAETgB,EAAIE,UACJ7G,EAAE8G,OAAOH,EAAIE,UAAWD,GAExBD,EAAIE,UAAYD,GAIxBG,oBAAqB,SAAUJ,GAC3B,IAAItF,EACJ,GAAIsF,EAAIK,UACJ,IAAK3F,KAAQsF,EAAIK,UACTL,EAAIK,UAAUC,eAAe5F,WACtBsF,EAAIK,UAAU3F,QAI7BsF,EAAIK,UAAY,IAIxBE,YAAa,SAAU9G,EAAGmE,GACtB,GAAInE,EAAE+G,iBAAkB,CACpB,IACIzB,EADAF,EAAQD,KAAQ,IAAIA,KAAKC,OAAQ,IAAKD,MAAQE,UAElD,GAAIlB,EAAK6C,OAAS7C,EAAKhB,kBACdiC,EAAMjB,EAAK6C,MAAQ7C,EAAKhB,kBACzBnD,EAAEsF,SAAWtF,EAAEkG,MACnB,OAEJ/B,EAAK6C,MAAQ5B,EACbE,EAAS2B,KAAKC,MACVlH,EAAEsF,OAAStF,EAAEkG,OAAS/B,EAAKgD,WAAahD,EAAKsC,UAAUP,SACtD/B,EAAKlB,eAAiB,GAG3B5C,KAAKoG,UAAUnB,QAAWA,EAASnB,EAAKsC,UAAUnB,OAClDjF,KAAKoG,UAAUlB,QAAUlF,KAAK+G,cAAc5B,WACxCJ,EACA/E,KAAKoG,UAAUnB,OACfnB,EAAKf,iBAETe,EAAKsC,UAAUnB,OAASnB,EAAKmB,OAASA,EACtCnB,EAAKsC,UAAUlB,QAAUpB,EAAKoB,QAAUpB,EAAKiD,cAAc5B,WACvDJ,EACAE,EACAnB,EAAKf,iBAKT/C,KAAKC,SACD,WACAV,EAAEW,MAAM,WAAY,CAACC,eAAgBR,IACrCmE,GAIJ9D,KAAKC,SACD,cACAV,EAAEW,MAAM,cAAe,CAACC,eAAgBR,IACxCK,KAAKoG,aAKjBY,sBAAuB,SAAUvF,GAC7B,IAAIwF,EAAOjH,KACPkH,EAAMzF,EAAQyF,IAAMzF,EAAQyF,MAAQ3H,EAAE4H,aAAaD,MAGnDA,EAAIE,SACJ7H,EAAE2H,EAAIE,QAAQC,KAAK,WAAY,SAAU1H,GACrC,IAAI2H,EAAK3H,EAAEE,cAEXF,EAAE+G,iBAAmBY,EAAGZ,iBACxB/G,EAAEsF,OAASqC,EAAGrC,OACdtF,EAAEkG,MAAQyB,EAAGzB,MACboB,EAAKR,YAAY9G,EAAG8B,KAExBA,EAAQyF,IAAM,WACV,OAAOA,KAKnBK,wBAAyB,SAAU9F,GAC/B,IAAIyF,EAAMzF,EAAQyF,IAAMzF,EAAQyF,MAAQ3H,EAAE4H,aAAaD,MACnDA,EAAIE,QACJ7H,EAAE2H,EAAIE,QAAQI,OAAO,aAI7BC,cAAe,SAAUhI,EAAMyG,GAE3B,OAAOwB,OAAOtG,UAAUiC,SAASsE,KAAKzB,KAAS,WAAazG,EAAO,KAGvEmI,aAAc,SAAUnG,GACpB,IACIiC,EADAuD,EAAOjH,KAEP+F,EAAOtE,EAAQmE,MAAM,GAErBlD,EAAYjB,EAAQiB,YAAcnD,EAAEe,QAAQO,cAC5CkB,EAA0C,UAA9BxC,EAAEE,KAAKgC,EAAQM,WACvBN,EAAQM,UAAU,GAAKN,EAAQM,UACvCN,EAAQoG,QAAUtI,EAAE8G,OAAO,GAAI5E,EAAQoG,SACnCpG,EAAQqG,eACRrG,EAAQoG,QAAQ,iBAAmBpG,EAAQqG,cAE1CpF,IAAajB,EAAQsG,MAAS/H,KAAKyH,cAAc,OAAQ1B,KAC1DtE,EAAQoG,QAAQ,uBAAyB,yBACrCG,UAAUjC,EAAKkC,YAAclC,EAAKN,MAAQ,KAE7C/C,EAGMnD,EAAEe,QAAQU,wBACbS,EAAQgB,aAKRiB,EAAW1D,KAAKuF,aAAa9D,GACzBA,EAAQsG,KACRrE,EAASgC,KAAK,CACVD,KAAM1D,EACNyB,MAAO/B,EAAQsG,OAGnBxI,EAAE+D,KAAK7B,EAAQmE,MAAO,SAAUE,EAAOC,GACnCrC,EAASgC,KAAK,CACVD,KAAqC,UAA9BlG,EAAEE,KAAKgC,EAAQM,YAClBN,EAAQM,UAAU+D,IAAW/D,EACjCyB,MAAOuC,QAKfkB,EAAKQ,cAAc,WAAYhG,EAAQiC,UACvCA,EAAWjC,EAAQiC,UAEnBA,EAAW,IAAIzC,SACf1B,EAAE+D,KAAKtD,KAAKuF,aAAa9D,GAAU,SAAUqE,EAAOoC,GAChDxE,EAASyE,OAAOD,EAAMzC,KAAMyC,EAAM1E,UAGtC/B,EAAQsG,KACRrE,EAASyE,OACLpG,EACAN,EAAQsG,KACRhC,EAAKkC,YAAclC,EAAKN,MAG5BlG,EAAE+D,KAAK7B,EAAQmE,MAAO,SAAUE,EAAOC,IAG/BkB,EAAKQ,cAAc,OAAQ1B,IACvBkB,EAAKQ,cAAc,OAAQ1B,KAC/BrC,EAASyE,OAC0B,UAA9B5I,EAAEE,KAAKgC,EAAQM,YACZN,EAAQM,UAAU+D,IAAW/D,EACjCgE,EACAA,EAAKkC,YAAclC,EAAKN,SAM5ChE,EAAQqC,KAAOJ,IAtDfjC,EAAQ4C,YAAc0B,EAAKtG,MAAQ,2BACnCgC,EAAQqC,KAAOrC,EAAQsG,MAAQhC,GAwDnCtE,EAAQsG,KAAO,MAGnBK,oBAAqB,SAAU3G,GAC3B,IAAI4G,EAAa9I,EAAE,WAAWqB,KAAK,OAAQa,EAAQ6G,KAAK1H,KAAK,QAE7Da,EAAQ8G,SAAW,WAAa9G,EAAQ8G,UAAY,IAEpD9G,EAAQiC,SAAW1D,KAAKuF,aAAa9D,GAEjCA,EAAQc,UAAY8F,GAAcA,IAAeG,SAASC,MAC1DhH,EAAQiC,SAASgC,KAAK,CAClBD,KAAMhE,EAAQe,mBAAqB,WACnCgB,MAAO/B,EAAQc,YAK3BmG,kBAAmB,SAAUjH,GACrBzB,KAAKsF,aAAa7D,IACbzB,KAAK2I,eAAelH,GAAS,KACzBA,EAAQqC,MACT9D,KAAK4H,aAAanG,GAEtBzB,KAAKgH,sBAAsBvF,IAE3BA,EAAQgB,cAGRhB,EAAQ8G,SAAW,gBAAkB9G,EAAQ8G,UAAY,MAG7DvI,KAAKoI,oBAAoB3G,IAIjCmH,cAAe,SAAUnH,GACrB,IAAIlB,EAAYhB,EAAEkC,EAAQlB,WACtBwB,EAAYN,EAAQM,UAkBxB,OAjBKA,EAcOxC,EAAEiG,QAAQzD,KAClBA,EAAY,CAACA,KAdbA,EAAY,GACZxB,EAAU+C,KAAK,WAIX,IAHA,IAAIuF,EAAQtJ,EAAES,MACVyF,EAAOoD,EAAMjI,KAAK,SAAW,UAC7BkI,GAAKD,EAAMjI,KAAK,UAAY,CAAC,IAAImI,OAC9BD,GACH/G,EAAU2D,KAAKD,GACfqD,GAAK,IAGR/G,EAAUgH,SACXhH,EAAY,CAACxB,EAAUK,KAAK,SAAW,aAKxCmB,GAGXiH,kBAAmB,SAAUvH,GAGpBA,EAAQkC,MAASlC,EAAQkC,KAAKoF,SAC/BtH,EAAQkC,KAAOpE,EAAEkC,EAAQlB,UAAUK,KAAK,SAGnCa,EAAQkC,KAAKoF,SACdtH,EAAQkC,KAAOpE,EAAES,KAAKyB,QAAQlB,UAAUK,KAAK,WAGrDa,EAAQM,UAAY/B,KAAK4I,cAAcnH,GAClCA,EAAQ6G,MACT7G,EAAQ6G,IAAM7G,EAAQkC,KAAK/C,KAAK,WAAa4H,SAASS,MAG1DxH,EAAQhC,MAAQgC,EAAQhC,MACqB,WAAxCF,EAAEE,KAAKgC,EAAQkC,KAAK/C,KAAK,YACtBa,EAAQkC,KAAK/C,KAAK,WAAc,IAClCsI,cACe,SAAjBzH,EAAQhC,MAAoC,QAAjBgC,EAAQhC,MACd,UAAjBgC,EAAQhC,OACZgC,EAAQhC,KAAO,QAEdgC,EAAQ0H,oBACT1H,EAAQ0H,kBAAoB1H,EAAQkC,KAAKyF,KAAK,oBAItDC,iBAAkB,SAAUvF,GACxB,IAAIrC,EAAUlC,EAAE8G,OAAO,GAAIrG,KAAKyB,QAASqC,GAGzC,OAFA9D,KAAKgJ,kBAAkBvH,GACvBzB,KAAK0I,kBAAkBjH,GAChBA,GAKX6H,kBAAmB,SAAUC,GACzB,OAAIA,EAASC,MACFD,EAASC,QAEhBD,EAASE,aACF,WAEPF,EAASG,aACF,WAEJ,WAKXC,gBAAiB,SAAUC,GAIvB,OAHAA,EAAQC,QAAUD,EAAQ1F,KAC1B0F,EAAQE,MAAQF,EAAQG,KACxBH,EAAQI,SAAWJ,EAAQK,OACpBL,GAKXM,eAAgB,SAAUC,EAAiB/G,EAASgH,GAChD,IAAIC,EAAM9K,EAAE+K,WACRV,EAAUS,EAAIT,UAQlB,OAPAxG,EAAUA,GAAWpD,KAAKyB,QAAQ2B,SAAWwG,GACrB,IAApBO,EACAE,EAAIE,YAAYnH,EAASgH,IACE,IAApBD,GACPE,EAAIG,WAAWpH,EAASgH,GAE5BR,EAAQa,MAAQJ,EAAIT,QACb5J,KAAK2J,gBAAgBC,IAIhCc,uBAAwB,SAAU/K,EAAGmE,GACjC,IAAImD,EAAOjH,KACP2K,EAAa,SAAUP,GACnB,OAAO7K,EAAE+K,WAAWC,YAAYtD,EAAMmD,GAAMR,WAEpD9F,EAAKG,QAAU,SAAU2G,EAAaC,GAalC,OAZID,GAAeC,KACf/G,EAAKgH,cAAgB9K,KAAK8K,eACrB9K,KAAK8K,eAAiBH,EAAW,CAAC3K,QAAQ+K,KACvC,WACI,OAAIjH,EAAKkH,YACEzL,EAAE+K,WACJE,WAAWvD,EAAM,CAACnD,IAAO8F,UAE3Be,EAAWhG,aAExBoG,KAAKH,EAAaC,IAErB7K,KAAK8K,eAAiBH,EAAW,CAAC3K,QAE7C8D,EAAKK,OAAS,WASV,MARqB,YAAjBnE,KAAKwJ,UACL1F,EAAKmH,MAAQjL,KAAKiL,OAKR,IAJLhE,EAAKhH,SACF,SACAV,EAAEW,MAAM,SAAU,CAACC,eAAgBR,IACnCK,OACYiH,EAAKiE,QAAQvL,EAAGK,OAEjCA,KAAKiL,OAAShE,EAAKiD,kBAE9BpG,EAAK2G,MAAQ,WACT,OAAIzK,KAAKiL,MACEjL,KAAKiL,MAAMR,SAEtBzK,KAAKgL,YAAc,QACnB/D,EAAKhH,SAAS,OAAQ,KAAMD,MACrBiH,EAAKiD,gBAAe,KAE/BpG,EAAK0F,MAAQ,WACT,OAAIxJ,KAAKiL,MACEhE,EAAKqC,kBAAkBtJ,KAAKiL,OAEnCjL,KAAK8K,cACE7D,EAAKqC,kBAAkBtJ,KAAK8K,oBADvC,GAIJhH,EAAKqH,WAAa,WACd,OAAQnL,KAAKiL,OAASjL,KAAK8K,eACoB,YADH7D,EACvCqC,kBAAkBtJ,KAAK8K,gBAEhChH,EAAKqC,SAAW,WACZ,OAAOnG,KAAKoG,WAEhBtC,EAAKsH,SAAW,WACZ,OAAOpL,KAAKuG,YAMpB8E,kBAAmB,SAAUJ,GACzB,IAAIK,EAAQL,EAAMM,kBAAkB,SAChCC,EAAQF,GAASA,EAAMG,MAAM,KAC7BC,EAAgBF,GAAwB,EAAfA,EAAMzC,QAC3B4C,SAASH,EAAM,GAAI,IAC3B,OAAOE,GAAiBA,EAAgB,GAQ5C/C,eAAgB,SAAUlH,EAASmK,GAC/BnK,EAAQmB,cAAgBnB,EAAQmB,eAAiB,EACjD,IAQIqI,EACA7D,EATAH,EAAOjH,KACP+F,EAAOtE,EAAQmE,MAAM,GACrBiG,EAAK9F,EAAKC,KACV8F,EAAKrK,EAAQmB,cACbmJ,EAAMtK,EAAQkB,cAAgBkJ,EAC9BxK,EAAQrB,KAAKyE,WACb4F,EAAM9K,EAAE+K,WACRV,EAAUS,EAAIT,UAGlB,UAAM5J,KAAKsF,aAAa7D,IAAYJ,IAAUyK,IAAuB,aAAhBvM,EAAEE,KAAKsM,GAAsBA,EAAItK,GAAWsK,GAAOF,KAChGpK,EAAQqC,UAGZ8H,IAGMC,GAANC,GACA/F,EAAK+D,MAAQrI,EAAQyB,KAAK,iBACnBlD,KAAKkK,gBACR,EACAzI,EAAQ2B,QACR,CAAC,KAAM,QAAS2C,EAAK+D,UAI7B1C,EAAS,WAEL,IAAI4E,EAAIzM,EAAE8G,OAAO,GAAI5E,GACjBwK,EAAgBD,EAAE5F,UAAUnB,OAChC+G,EAAEjE,KAAO1G,EAAMsG,KACX5B,EACA+F,EACAA,GAAsB,aAAhBvM,EAAEE,KAAKsM,GAAsBA,EAAIC,GAAKD,GAC5ChG,EAAKtG,MAITuM,EAAElF,UAAYkF,EAAEjE,KAAK/B,KAErBgG,EAAElE,aAAe,SAAWgE,EAAK,KAC5BA,EAAKE,EAAElF,UAAY,GAAK,IAAM+E,EAEnC5E,EAAKhH,SAAS,kBAAmB,KAAM+L,GAEvC/E,EAAKW,aAAaoE,GAElB/E,EAAKD,sBAAsBgF,GAC3Bf,IAAkD,IAAxChE,EAAKhH,SAAS,YAAa,KAAM+L,IAAgBzM,EAAE2M,KAAKF,IAC1D/E,EAAKiD,gBAAe,EAAO8B,EAAE5I,UAChCc,KAAK,SAAUiI,EAAQC,EAAYnB,GAChCa,EAAK7E,EAAKoE,kBAAkBJ,IACvBa,EAAKE,EAAElF,UAIRmF,EAAgBD,EAAElF,UAAYkF,EAAE5F,UAAUnB,QAC1CgC,EAAKR,YAAYlH,EAAEW,MAAM,WAAY,CACjCwG,kBAAkB,EAClBzB,OAAQ6G,EAAKE,EAAEpJ,cACfiD,MAAOiG,EAAKE,EAAEpJ,gBACdoJ,GAERvK,EAAQmB,cAAgBoJ,EAAEpJ,cAAgBkJ,EAC1CE,EAAEG,OAASA,EACXH,EAAEI,WAAaA,EACfJ,EAAEf,MAAQA,EACVhE,EAAKhH,SAAS,YAAa,KAAM+L,GACjC/E,EAAKhH,SAAS,cAAe,KAAM+L,GAC/BF,EAAKD,EAGLzE,IAEAiD,EAAIE,YACAyB,EAAE5I,QACF,CAAC+I,EAAQC,EAAYnB,MAIhClB,KAAK,SAAUkB,EAAOmB,EAAYpB,GAC/BgB,EAAEf,MAAQA,EACVe,EAAEI,WAAaA,EACfJ,EAAEhB,YAAcA,EAChB/D,EAAKhH,SAAS,YAAa,KAAM+L,GACjC/E,EAAKhH,SAAS,cAAe,KAAM+L,GACnC3B,EAAIG,WACAwB,EAAE5I,QACF,CAAC6H,EAAOmB,EAAYpB,MAG3Bf,OAAO,WACJhD,EAAKM,wBAAwByE,MAGzChM,KAAK2J,gBAAgBC,GACrBA,EAAQa,MAAQ,WACZ,OAAOQ,EAAMR,SAEjBrD,IACOwC,MAGXyC,YAAa,SAAU1M,EAAGmE,GACD,IAAjB9D,KAAKsM,UAILtM,KAAKC,SAAS,SAEdD,KAAK+G,cAAgB,IAAI/G,KAAK4E,cAE9B5E,KAAKoG,UAAUnB,OAASjF,KAAKoG,UAAUP,MAAQ,EAC/C7F,KAAKoG,UAAUlB,QAAU,GAK7BlF,KAAKsG,oBAAoBxC,GACzB9D,KAAKiG,oBAAoBnC,GACzBA,EAAKsC,UAAUnB,OAASnB,EAAKmB,OAASnB,EAAKlB,eAAiB,EAC5DkB,EAAKsC,UAAUP,MAAQ/B,EAAK+B,MAAQ7F,KAAK2F,UAAU7B,EAAK8B,QAAU,EAClE9B,EAAKsC,UAAUlB,QAAUpB,EAAKoB,QAAU,EACxClF,KAAKsM,SAAW,EAEhBtM,KAAKoG,UAAUnB,QAAUnB,EAAKmB,OAC9BjF,KAAKoG,UAAUP,OAAS/B,EAAK+B,OAGjC0G,QAAS,SAAUJ,EAAQC,EAAYnB,EAAOxJ,GAC1C,IAAIoE,EAAQpE,EAAQ2E,UAAUP,MAC1BuF,EAAW3J,EAAQ8E,UACnB9E,EAAQ2E,UAAUnB,OAASY,GAG3B7F,KAAKyG,YAAYlH,EAAEW,MAAM,WAAY,CACjCwG,kBAAkB,EAClBzB,OAAQY,EACRA,MAAOA,IACPpE,GAER2J,EAASe,OAAS1K,EAAQ0K,OAASA,EACnCf,EAASgB,WAAa3K,EAAQ2K,WAAaA,EAC3ChB,EAASH,MAAQxJ,EAAQwJ,MAAQA,EACjCjL,KAAKC,SAAS,OAAQ,KAAMwB,IAGhC+K,QAAS,SAAUvB,EAAOmB,EAAYpB,EAAavJ,GAC/C,IAAI2J,EAAW3J,EAAQ8E,UACnB9E,EAAQoB,sBAGR7C,KAAKoG,UAAUnB,QAAUxD,EAAQ2E,UAAUnB,OAC3CjF,KAAKoG,UAAUP,OAASpE,EAAQ2E,UAAUP,OAE9CuF,EAASH,MAAQxJ,EAAQwJ,MAAQA,EACjCG,EAASgB,WAAa3K,EAAQ2K,WAAaA,EAC3ChB,EAASJ,YAAcvJ,EAAQuJ,YAAcA,EAC7ChL,KAAKC,SAAS,OAAQ,KAAMwB,IAGhCgL,UAAW,SAAUC,EAAeN,EAAYO,EAAclL,GAG1DzB,KAAKC,SAAS,SAAU,KAAMwB,IAGlCyJ,QAAS,SAAUvL,EAAGmE,GACbA,EAAKK,QACNnE,KAAK0K,uBAAuB/K,EAAGmE,GAEnC,IACImH,EACA2B,EACAC,EACAC,EAJA7F,EAAOjH,KAKPyB,EAAUwF,EAAKoC,iBAAiBvF,GAChCiJ,EAAO,WA6CH,OA5CA9F,EAAK+F,UAAY,EAEjBvL,EAAQsF,cAAgB,IAAIE,EAAKrC,cACjCqG,EAAQA,KACF2B,IAII,IAJO3F,EAAKhH,SACd,OACAV,EAAEW,MAAM,OAAQ,CAACC,eAAgBR,IACjC8B,KAEJwF,EAAKiD,gBAAe,EAAOzI,EAAQ2B,QAASwJ,IAC5C3F,EAAK0B,eAAelH,IAAYlC,EAAE2M,KAAKzK,IACzCyC,KAAK,SAAUiI,EAAQC,EAAYnB,GACjChE,EAAKsF,QAAQJ,EAAQC,EAAYnB,EAAOxJ,KACzCsI,KAAK,SAAUkB,EAAOmB,EAAYpB,GACjC/D,EAAKuF,QAAQvB,EAAOmB,EAAYpB,EAAavJ,KAC9CwI,OAAO,SAAUyC,EAAeN,EAAYO,GAU3C,GATA1F,EAAKM,wBAAwB9F,GAC7BwF,EAAKwF,UACDC,EACAN,EACAO,EACAlL,GAEJwF,EAAK+F,UAAY,EACjB/F,EAAKqF,SAAW,EACZ7K,EAAQY,wBACJZ,EAAQY,uBAAyB4E,EAAK+F,SAI1C,IADA,IAAIC,EAAWhG,EAAKiG,OAAOC,QACpBF,GAAU,CACb,GAAyC,YAArChG,EAAKqC,kBAAkB2D,GAAyB,CAChDA,EAASG,UACT,MAEJH,EAAWhG,EAAKiG,OAAOC,QAGV,IAAjBlG,EAAKqF,SAGLrF,EAAKhH,SAAS,WAM9B,OADAD,KAAKqM,YAAY1M,EAAG8B,GAChBzB,KAAKyB,QAAQW,mBACRpC,KAAKyB,QAAQY,wBACdrC,KAAKyB,QAAQY,wBAA0BrC,KAAKgN,WAI5CF,EAHsC,EAAtC9M,KAAKyB,QAAQY,wBACbwK,EAAOtN,EAAE+K,WACTtK,KAAKkN,OAAOxH,KAAKmH,GACVA,EAAK9B,KAAKgC,KAEjB/M,KAAKqN,UAAYrN,KAAKqN,UAAUtC,KAAKgC,EAAMA,GACpC/M,KAAKqN,YAKX5C,MAAQ,WAET,OADAmC,EAAU,MAAC/K,EAAW,QAAS,SAC1BoJ,EAMEA,EAAMR,SALLoC,GACAA,EAAKrC,WAAW/I,EAAQ2B,QAASwJ,GAE9BG,MAIR/M,KAAK2J,gBAAgBmD,IAEzBC,KAGXO,OAAQ,SAAU3N,EAAGmE,GACjB,IAUIyJ,EACAC,EACAC,EACA3E,EAbA7B,EAAOjH,KACPmM,GAAS,EACT1K,EAAUlC,EAAE8G,OAAO,GAAIrG,KAAKyB,QAASqC,GACrC8B,EAAQ9B,EAAK8B,MACb8H,EAAc9H,EAAMmD,OACpB4E,EAAQlM,EAAQQ,sBAChB2L,EAAYnM,EAAQS,yBACpB2L,EAAWpM,EAAQU,iCACnB2L,EAAY,EACZ/L,EAAY/B,KAAK4I,cAAcnH,GAK/BsM,EAAI,EACR,IAAKL,EACD,OAAO,EAKX,GAHIE,QAA+B/L,IAAlB+D,EAAM,GAAGI,OACtB4H,OAAY/L,IAEVJ,EAAQO,mBAAqB2L,GAASC,IACnC5N,KAAKsF,aAAa7D,GAGpB,GAAMA,EAAQO,mBAAqB4L,IAAcD,EAWjD,IAAKlM,EAAQO,mBAAqB4L,EAGrC,IAFAH,EAAU,GACVF,EAAe,GACVzE,EAAI,EAAGA,EAAI4E,EAAa5E,GAAQ,EACjCgF,GAAalI,EAAMkD,GAAG9C,KAAO6H,GACzB/E,EAAI,IAAM4E,GACJI,EAAYlI,EAAMkD,EAAI,GAAG9C,KAAO6H,EAAYD,GAC7CD,GAAsBA,GAAb7E,EAAI,EAAIiF,KACtBN,EAAQ/H,KAAKE,EAAMvE,MAAM0M,EAAGjF,EAAI,KAChC0E,EAAiBzL,EAAUV,MAAM0M,EAAGjF,EAAI,IACpBC,SAChByE,EAAiBzL,GAErBwL,EAAa7H,KAAK8H,GAClBO,EAAIjF,EAAI,EACRgF,EAAY,QAIpBP,EAAexL,OA3Bf,IAFA0L,EAAU,GACVF,EAAe,GACVzE,EAAI,EAAGA,EAAI4E,EAAa5E,GAAK6E,EAC9BF,EAAQ/H,KAAKE,EAAMvE,MAAMyH,EAAGA,EAAI6E,KAChCH,EAAiBzL,EAAUV,MAAMyH,EAAGA,EAAI6E,IACpB5E,SAChByE,EAAiBzL,GAErBwL,EAAa7H,KAAK8H,QAXtBC,EAAU,CAAC7H,GACX2H,EAAe,CAACxL,GAgDpB,OAfA+B,EAAKkK,cAAgBpI,EACrBrG,EAAE+D,KAAKmK,GAAW7H,EAAO,SAAUE,EAAOmI,GACtC,IAAIC,EAAU3O,EAAE8G,OAAO,GAAIvC,GAW3B,OAVAoK,EAAQtI,MAAQ6H,EAAUQ,EAAU,CAACA,GACrCC,EAAQnM,UAAYwL,EAAazH,GACjCmB,EAAKX,oBAAoB4H,GACzBjH,EAAKhB,oBAAoBiI,GACzBjH,EAAKyD,uBAAuB/K,EAAGuO,GAC/B/B,EAASlF,EAAKhH,SACV,MACAV,EAAEW,MAAM,MAAO,CAACC,eAAgBR,IAChCuO,KAID/B,GAGXgC,kBAAmB,SAAUrK,GACzB,IAAI+E,EAAQ/E,EAAKvD,UACb6N,EAAavF,EAAMwF,OAAM,GACzBC,EAAezF,EAAM0F,GAAG5M,SAAS6M,eAErC1K,EAAK2K,eAAiBL,EACtB7O,EAAE,iBAAiB4I,OAAOiG,GAAY,GAAGM,QAGzC7F,EAAM8F,MAAMP,GAAYQ,SAGpBN,GACAF,EAAWS,QAGftP,EAAEuP,UAAUjG,EAAMrB,OAAO,WAIzBxH,KAAKyB,QAAQlB,UAAYP,KAAKyB,QAAQlB,UAAUwO,IAAI,SAAUjG,EAAGkG,GAC7D,OAAIA,IAAOnG,EAAM,GACNuF,EAAW,GAEfY,IAIPnG,EAAM,KAAO7I,KAAKiO,QAAQ,KAC1BjO,KAAKiO,QAAUG,IAIvBa,qBAAsB,SAAUC,EAAOC,GACnC,IAGIC,EAHAnI,EAAOjH,KACPqK,EAAM9K,EAAE+K,WACR+E,EAAU,GAEVC,EAAe,SAAU3P,GACjBA,IAAMA,EAAEuP,QACRvP,EAAEuP,MAAQA,GAMd7E,EAAI+C,QAAQ,CAACzN,KAUjB4P,EAAc,WACVH,EAAUG,YAAY,SAAUC,GATnB,IAAUH,EAUdG,EAAQzG,QAGTsG,EAAUA,EAAQI,OAAOD,GACzBD,MAdeF,EAWAA,EAVvBpI,EAAKyI,uBACDL,EACAF,EAAOD,EAAMzJ,KAAO,KACtBvB,KAAK,SAAU0B,GACbyE,EAAI+C,QAAQxH,KACbmE,KAAKuF,KAULA,IAsBX,OApBAH,EAAOA,GAAQ,GACXD,EAAMS,OACFT,EAAMU,OAENV,EAAMU,MAAMC,aAAeV,EAC3B9E,EAAI+C,QAAQ8B,EAAMU,QAElBV,EAAMnJ,KAAK,SAAUA,GACjBA,EAAK8J,aAAeV,EACpB9E,EAAI+C,QAAQrH,IACbuJ,GAEAJ,EAAMY,aACbV,EAAYF,EAAMa,eAClBR,KAIAlF,EAAI+C,QAAQ,IAET/C,EAAIT,WAGf8F,uBAAwB,SAAUL,EAASF,GACvC,IAAIlI,EAAOjH,KACX,OAAOT,EAAEyQ,KAAKtL,MACVnF,EACAA,EAAEwP,IAAIM,EAAS,SAAUH,GACrB,OAAOjI,EAAKgI,qBAAqBC,EAAOC,MAE9CpE,KAAK,WACH,OAAOkF,MAAM7O,UAAUqO,OAAO/K,MAC1B,GACAC,cAKZuL,iBAAkB,SAAUtQ,GAExB,IAAIuQ,GADJvQ,EAAeA,GAAgB,IACNuQ,MACzB,OAAIA,GAASA,EAAMpH,SAAWoH,EAAM,GAAGC,kBAC/BD,EAAM,GAAGE,YACNrQ,KAAK0P,uBACRnQ,EAAEwP,IAAIoB,EAAO,SAAUG,GACnB,IAAIpB,EACJ,OAAIoB,EAAKF,mBACLlB,EAAQoB,EAAKF,sBAGTlB,EAAMU,MAAQU,EAAKC,aAEhBrB,GAEJoB,EAAKD,gBAIjB9Q,EAAE+K,WAAW8C,QAChB7N,EAAEiR,UAAU5Q,EAAagG,QAC3BgE,WAGN6G,yBAA0B,SAAUlQ,GAEhC,IAEIqF,EACApC,EAHA6L,GADJ9O,EAAYhB,EAAEgB,IACUK,KAAK,kBACrBL,EAAUK,KAAK,WAGvB,GAAIyO,GAAWA,EAAQtG,OACnB,OAAO/I,KAAK0P,uBAAuBL,GAGvC,IADAzJ,EAAQrG,EAAEiR,UAAUjQ,EAAUK,KAAK,WACxBmI,YASkBlH,IAAlB+D,EAAM,GAAGH,MAAsBG,EAAM,GAAG8K,UAE/CnR,EAAE+D,KAAKsC,EAAO,SAAUE,EAAOC,GAC3BA,EAAKN,KAAOM,EAAK2K,SACjB3K,EAAKC,KAAOD,EAAK4K,eAbN,CAEf,KADAnN,EAAQjD,EAAUK,KAAK,UAEnB,OAAOrB,EAAE+K,WAAW8C,QAAQ,IAAIxD,UAKpChE,EAAQ,CAAC,CAACH,KAAMjC,EAAMC,QAAQ,QAAS,MAQ3C,OAAOlE,EAAE+K,WAAW8C,QAAQxH,GAAOgE,WAGvCgH,mBAAoB,SAAUrQ,GAC1B,OAAMA,aAAqBhB,GAA2B,IAArBgB,EAAUwI,OAGpCxJ,EAAEyQ,KAAKtL,MACVnF,EACAA,EAAEwP,IAAIxO,EAAWP,KAAKyQ,2BACxB1F,KAAK,WACH,OAAOkF,MAAM7O,UAAUqO,OAAO/K,MAC1B,GACAC,aARG3E,KAAKyQ,yBAAyBlQ,IAa7CsQ,UAAW,SAAUlR,GACjB,IAAIsH,EAAOjH,KACP8D,EAAO,CACHvD,UAAWhB,EAAEI,EAAEmR,QACfnN,KAAMpE,EAAEI,EAAEmR,OAAOnN,OAEzB3D,KAAK4Q,mBAAmB9M,EAAKvD,WAAW0J,OAAO,SAAUrE,GACrD9B,EAAK8B,MAAQA,EACTqB,EAAKxF,QAAQK,kBACbmF,EAAKkH,kBAAkBrK,IAMjB,IAJNmD,EAAKhH,SACD,SACAV,EAAEW,MAAM,SAAU,CAACC,eAAgBR,IACnCmE,IAEJmD,EAAKqG,OAAO3N,EAAGmE,MAK3BiN,SAAU,SAAUpR,GAChB,IAAIwQ,EAAQxQ,EAAEE,eAAiBF,EAAEE,cAAcmR,eACvCrR,EAAEE,cAAcmR,cAAcb,MAClCrM,EAAO,CAAC8B,MAAO,IACfuK,GAASA,EAAMpH,SACfxJ,EAAE+D,KAAK6M,EAAO,SAAUrK,EAAOwK,GAC3B,IAAIvK,EAAOuK,EAAKC,WAAaD,EAAKC,YAC9BxK,GACAjC,EAAK8B,MAAMF,KAAKK,MAOd,IAJN/F,KAAKC,SACD,QACAV,EAAEW,MAAM,QAAS,CAACC,eAAgBR,IAClCmE,IAEJ9D,KAAKsN,OAAO3N,EAAGmE,KAK3BmN,QAAS,SAAUtR,GACfA,EAAEC,aAAeD,EAAEE,eAAiBF,EAAEE,cAAcD,aACpD,IAAIqH,EAAOjH,KACPJ,EAAeD,EAAEC,aACjBkE,EAAO,GACPlE,GAAgBA,EAAagG,OAAShG,EAAagG,MAAMmD,SACzDpJ,EAAES,iBACFJ,KAAKkQ,iBAAiBtQ,GAAcqK,OAAO,SAAUrE,GACjD9B,EAAK8B,MAAQA,GAKH,IAJNqB,EAAKhH,SACD,OACAV,EAAEW,MAAM,OAAQ,CAACC,eAAgBR,IACjCmE,IAEJmD,EAAKqG,OAAO3N,EAAGmE,OAM/BoN,YAAa1R,EAAe,YAE5B2R,aAAc3R,EAAe,aAE7B4R,aAAc5R,EAAe,aAE7B6R,mBAAoB,WACZrR,KAAKsF,aAAatF,KAAKyB,WACvBzB,KAAKsR,IAAItR,KAAKyB,QAAQC,SAAU,CAC5B6P,SAAUvR,KAAKkR,YACfM,KAAMxR,KAAKiR,QAEXQ,UAAWzR,KAAKmR,aAEhBO,UAAW1R,KAAKoR,eAEpBpR,KAAKsR,IAAItR,KAAKyB,QAAQG,UAAW,CAC7B+P,MAAO3R,KAAK+Q,YAGhBxR,EAAEe,QAAQC,WACVP,KAAKsR,IAAItR,KAAKyB,QAAQlB,UAAW,CAC7BqR,OAAQ5R,KAAK6Q,aAKzBgB,sBAAuB,WACnB7R,KAAK8R,KAAK9R,KAAKyB,QAAQC,SAAU,qCACjC1B,KAAK8R,KAAK9R,KAAKyB,QAAQG,UAAW,SAClC5B,KAAK8R,KAAK9R,KAAKyB,QAAQlB,UAAW,WAGtCwR,SAAU,WACN/R,KAAK6R,yBAGTG,WAAY,SAAUzO,EAAKC,GACvB,IAAIyO,GAAmD,IAA1C1S,EAAEO,QAAQyD,EAAKvD,KAAKwE,iBAC7ByN,GACAjS,KAAK6R,wBAET7R,KAAKkS,OAAO3O,EAAKC,GACbyO,IACAjS,KAAKmS,sBACLnS,KAAKqR,uBAIbc,oBAAqB,WACjB,IAAI1Q,EAAUzB,KAAKyB,aACOI,IAAtBJ,EAAQlB,UACRkB,EAAQlB,UAAYP,KAAKiO,QAAQM,GAAG,sBAC5BvO,KAAKiO,QAAUjO,KAAKiO,QAAQmE,KAAK,sBAChC3Q,EAAQlB,qBAAqBhB,IACtCkC,EAAQlB,UAAYhB,EAAEkC,EAAQlB,YAE5BkB,EAAQC,oBAAoBnC,IAC9BkC,EAAQC,SAAWnC,EAAEkC,EAAQC,WAE3BD,EAAQG,qBAAqBrC,IAC/BkC,EAAQG,UAAYrC,EAAEkC,EAAQG,aAItCyQ,WAAY,SAAUC,GAClB,IAAI9G,EAAQ8G,EAAI7G,MAAM,KAClB8G,EAAY/G,EAAMgH,MAEtB,OADAhH,EAAM2B,QACC,IAAI3M,OAAOgL,EAAMiH,KAAK,KAAMF,IAGvCG,gBAAiB,SAAUnP,EAAKC,GAC5B,MAAe,QAARD,GAAmC,WAAlBhE,EAAEE,KAAK+D,IAC3B,qBAAqB/C,KAAK+C,IAGlCmP,oBAAqB,WACjB,IAAI1L,EAAOjH,KACPyB,EAAUzB,KAAKyB,QACfqC,EAAO9D,KAAKiO,QAAQnK,OAExBvE,EAAE+D,KACEtD,KAAKiO,QAAQ,GAAG2E,WAChB,SAAU9M,EAAOsD,GACb,IACI5F,EADAD,EAAM6F,EAAK3D,KAAKoN,cAEhB,SAASpS,KAAK8C,KAEdA,EAAMA,EAAIlC,MAAM,GAAGoC,QAAQ,UAAW,SAAU6O,GAC5C,OAAOA,EAAIQ,OAAO,GAAG5J,gBAEzB1F,EAAQM,EAAKP,GACT0D,EAAKyL,gBAAgBnP,EAAKC,KAC1BA,EAAQyD,EAAKoL,WAAW7O,IAE5B/B,EAAQ8B,GAAOC,MAM/BuP,QAAS,WACL/S,KAAK2S,sBACL3S,KAAKmS,sBACLnS,KAAKkN,OAAS,GACdlN,KAAKqN,UAAYrN,KAAKkK,gBAAe,GACrClK,KAAKgN,SAAWhN,KAAKsM,QAAU,EAC/BtM,KAAKiG,oBAAoBjG,MACzBA,KAAKqR,sBAKT2B,OAAQ,WACJ,OAAOhT,KAAKsM,SAOhBnG,SAAU,WACN,OAAOnG,KAAKoG,WAOhBvC,IAAK,SAAUC,GACX,IAAImD,EAAOjH,KACN8D,IAAQ9D,KAAKyB,QAAQwR,WAGtBnP,EAAKvD,YAAcuD,EAAK8B,MACxB5F,KAAK4Q,mBAAmB9M,EAAKvD,WAAW0J,OAAO,SAAUrE,GACrD9B,EAAK8B,MAAQA,EACbqB,EAAKqG,OAAO,KAAMxJ,MAGtBA,EAAK8B,MAAQrG,EAAEiR,UAAU1M,EAAK8B,OAC9B5F,KAAKsN,OAAO,KAAMxJ,MAS1BiJ,KAAM,SAAUjJ,GACZ,GAAIA,IAAS9D,KAAKyB,QAAQwR,SAAU,CAChC,GAAInP,EAAKvD,YAAcuD,EAAK8B,MAAO,CAC/B,IAGIqF,EACA2B,EAJA3F,EAAOjH,KACPqK,EAAM9K,EAAE+K,WACRV,EAAUS,EAAIT,UAgClB,OA7BAA,EAAQa,MAAQ,WAEZ,OADAmC,GAAU,EACN3B,EACOA,EAAMR,SAEjBJ,EAAI6I,OAAO,KAAM,QAAS,SACnBtJ,IAEX5J,KAAK4Q,mBAAmB9M,EAAKvD,WAAW0J,OACpC,SAAUrE,GACFgH,IAGChH,EAAMmD,QAIXjF,EAAK8B,MAAQA,GACbqF,EAAQhE,EAAKiE,QAAQ,KAAMpH,IACrBiH,KACF,SAAUoB,EAAQC,EAAYnB,GAC1BZ,EAAI+C,QAAQjB,EAAQC,EAAYnB,IAEpC,SAAUA,EAAOmB,EAAYpB,GACzBX,EAAI6I,OAAOjI,EAAOmB,EAAYpB,MAVlCX,EAAI6I,YAeTlT,KAAK2J,gBAAgBC,GAGhC,GADA9F,EAAK8B,MAAQrG,EAAEiR,UAAU1M,EAAK8B,OAC1B9B,EAAK8B,MAAMmD,OACX,OAAO/I,KAAKkL,QAAQ,KAAMpH,GAGlC,OAAO9D,KAAKkK,gBAAe,EAAOpG,GAAQA,EAAKV","file":"jquery.fileupload.js","sourcesContent":["/*\n * jQuery File Upload Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document, location, Blob, FormData */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'jquery-ui/ui/widget'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./vendor/jquery.ui.widget')\n        );\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    // Detect file input support, based on\n    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/\n    $.support.fileInput = !(new RegExp(\n        // Handle devices which give false positives for the feature detection:\n        '(Android (1\\\\.[0156]|2\\\\.[01]))' +\n            '|(Windows Phone (OS 7|8\\\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +\n            '|(w(eb)?OSBrowser)|(webOS)' +\n            '|(Kindle/(1\\\\.0|2\\\\.[05]|3\\\\.0))'\n    ).test(window.navigator.userAgent) ||\n        // Feature detection for all other devices:\n        $('<input type=\"file\"/>').prop('disabled'));\n\n    // The FileReader API is not actually used, but works as feature detection,\n    // as some Safari versions (5?) support XHR file uploads via the FormData API,\n    // but not non-multipart XHR file uploads.\n    // window.XMLHttpRequestUpload is not available on IE10, so we check for\n    // window.ProgressEvent instead to detect XHR2 file upload capability:\n    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);\n    $.support.xhrFormDataFileUpload = !!window.FormData;\n\n    // Detect support for Blob slicing (required for chunked uploads):\n    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||\n        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);\n\n    // Helper function to create drag handlers for dragover/dragenter/dragleave:\n    function getDragHandler(type) {\n        var isDragOver = type === 'dragover';\n        return function (e) {\n            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n            var dataTransfer = e.dataTransfer;\n            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&\n                    this._trigger(\n                        type,\n                        $.Event(type, {delegatedEvent: e})\n                    ) !== false) {\n                e.preventDefault();\n                if (isDragOver) {\n                    dataTransfer.dropEffect = 'copy';\n                }\n            }\n        };\n    }\n\n    // The fileupload widget listens for change events on file input fields defined\n    // via fileInput setting and paste or drop events of the given dropZone.\n    // In addition to the default jQuery Widget methods, the fileupload widget\n    // exposes the \"add\" and \"send\" methods, to add or directly send files using\n    // the fileupload API.\n    // By default, files added via file input selection, paste, drag & drop or\n    // \"add\" method are uploaded immediately, but it is possible to override\n    // the \"add\" callback option to queue file uploads.\n    $.widget('blueimp.fileupload', {\n\n        options: {\n            // The drop target element(s), by the default the complete document.\n            // Set to null to disable drag & drop support:\n            dropZone: $(document),\n            // The paste target element(s), by the default undefined.\n            // Set to a DOM node or jQuery object to enable file pasting:\n            pasteZone: undefined,\n            // The file input field(s), that are listened to for change events.\n            // If undefined, it is set to the file input fields inside\n            // of the widget element on plugin initialization.\n            // Set to null to disable the change listener.\n            fileInput: undefined,\n            // By default, the file input field is replaced with a clone after\n            // each input field change event. This is required for iframe transport\n            // queues and allows change events to be fired for the same file\n            // selection, but can be disabled by setting the following option to false:\n            replaceFileInput: true,\n            // The parameter name for the file form data (the request argument name).\n            // If undefined or empty, the name property of the file input field is\n            // used, or \"files[]\" if the file input name property is also empty,\n            // can be a string or an array of strings:\n            paramName: undefined,\n            // By default, each file of a selection is uploaded using an individual\n            // request for XHR type uploads. Set to false to upload file\n            // selections in one request each:\n            singleFileUploads: true,\n            // To limit the number of files uploaded with one XHR request,\n            // set the following option to an integer greater than 0:\n            limitMultiFileUploads: undefined,\n            // The following option limits the number of files uploaded with one\n            // XHR request to keep the request size under or equal to the defined\n            // limit in bytes:\n            limitMultiFileUploadSize: undefined,\n            // Multipart file uploads add a number of bytes to each uploaded file,\n            // therefore the following option adds an overhead for each file used\n            // in the limitMultiFileUploadSize configuration:\n            limitMultiFileUploadSizeOverhead: 512,\n            // Set the following option to true to issue all file upload requests\n            // in a sequential order:\n            sequentialUploads: false,\n            // To limit the number of concurrent uploads,\n            // set the following option to an integer greater than 0:\n            limitConcurrentUploads: undefined,\n            // Set the following option to true to force iframe transport uploads:\n            forceIframeTransport: false,\n            // Set the following option to the location of a redirect url on the\n            // origin server, for cross-domain iframe transport uploads:\n            redirect: undefined,\n            // The parameter name for the redirect url, sent as part of the form\n            // data and set to 'redirect' if this option is empty:\n            redirectParamName: undefined,\n            // Set the following option to the location of a postMessage window,\n            // to enable postMessage transport uploads:\n            postMessage: undefined,\n            // By default, XHR file uploads are sent as multipart/form-data.\n            // The iframe transport is always using multipart/form-data.\n            // Set to false to enable non-multipart XHR uploads:\n            multipart: true,\n            // To upload large files in smaller chunks, set the following option\n            // to a preferred maximum chunk size. If set to 0, null or undefined,\n            // or the browser does not support the required Blob API, files will\n            // be uploaded as a whole.\n            maxChunkSize: undefined,\n            // When a non-multipart upload or a chunked multipart upload has been\n            // aborted, this option can be used to resume the upload by setting\n            // it to the size of the already uploaded bytes. This option is most\n            // useful when modifying the options object inside of the \"add\" or\n            // \"send\" callbacks, as the options are cloned for each file upload.\n            uploadedBytes: undefined,\n            // By default, failed (abort or error) file uploads are removed from the\n            // global progress calculation. Set the following option to false to\n            // prevent recalculating the global progress data:\n            recalculateProgress: true,\n            // Interval in milliseconds to calculate and trigger progress events:\n            progressInterval: 100,\n            // Interval in milliseconds to calculate progress bitrate:\n            bitrateInterval: 500,\n            // By default, uploads are started automatically when adding files:\n            autoUpload: true,\n\n            // Error and info messages:\n            messages: {\n                uploadedBytes: 'Uploaded bytes exceed file size'\n            },\n\n            // Translation function, gets the message key to be translated\n            // and an object with context specific data as arguments:\n            i18n: function (message, context) {\n                message = this.messages[message] || message.toString();\n                if (context) {\n                    $.each(context, function (key, value) {\n                        message = message.replace('{' + key + '}', value);\n                    });\n                }\n                return message;\n            },\n\n            // Additional form data to be sent along with the file uploads can be set\n            // using this option, which accepts an array of objects with name and\n            // value properties, a function returning such an array, a FormData\n            // object (for XHR file uploads), or a simple object.\n            // The form of the first fileInput is given as parameter to the function:\n            formData: function (form) {\n                return form.serializeArray();\n            },\n\n            // The add callback is invoked as soon as files are added to the fileupload\n            // widget (via file input selection, drag & drop, paste or add API call).\n            // If the singleFileUploads option is enabled, this callback will be\n            // called once for each file in the selection for XHR file uploads, else\n            // once for each file selection.\n            //\n            // The upload starts when the submit method is invoked on the data parameter.\n            // The data object contains a files property holding the added files\n            // and allows you to override plugin options as well as define ajax settings.\n            //\n            // Listeners for this callback can also be bound the following way:\n            // .bind('fileuploadadd', func);\n            //\n            // data.submit() returns a Promise object and allows to attach additional\n            // handlers using jQuery's Deferred callbacks:\n            // data.submit().done(func).fail(func).always(func);\n            add: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                if (data.autoUpload || (data.autoUpload !== false &&\n                        $(this).fileupload('option', 'autoUpload'))) {\n                    data.process().done(function () {\n                        data.submit();\n                    });\n                }\n            },\n\n            // Other callbacks:\n\n            // Callback for the submit event of each file upload:\n            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);\n\n            // Callback for the start of each file upload request:\n            // send: function (e, data) {}, // .bind('fileuploadsend', func);\n\n            // Callback for successful uploads:\n            // done: function (e, data) {}, // .bind('fileuploaddone', func);\n\n            // Callback for failed (abort or error) uploads:\n            // fail: function (e, data) {}, // .bind('fileuploadfail', func);\n\n            // Callback for completed (success, abort or error) requests:\n            // always: function (e, data) {}, // .bind('fileuploadalways', func);\n\n            // Callback for upload progress events:\n            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);\n\n            // Callback for global upload progress events:\n            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);\n\n            // Callback for uploads start, equivalent to the global ajaxStart event:\n            // start: function (e) {}, // .bind('fileuploadstart', func);\n\n            // Callback for uploads stop, equivalent to the global ajaxStop event:\n            // stop: function (e) {}, // .bind('fileuploadstop', func);\n\n            // Callback for change events of the fileInput(s):\n            // change: function (e, data) {}, // .bind('fileuploadchange', func);\n\n            // Callback for paste events to the pasteZone(s):\n            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);\n\n            // Callback for drop events of the dropZone(s):\n            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);\n\n            // Callback for dragover events of the dropZone(s):\n            // dragover: function (e) {}, // .bind('fileuploaddragover', func);\n\n            // Callback before the start of each chunk upload request (before form data initialization):\n            // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func);\n\n            // Callback for the start of each chunk upload request:\n            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);\n\n            // Callback for successful chunk uploads:\n            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);\n\n            // Callback for failed (abort or error) chunk uploads:\n            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);\n\n            // Callback for completed (success, abort or error) chunk upload requests:\n            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);\n\n            // The plugin options are used as settings object for the ajax calls.\n            // The following are jQuery ajax settings required for the file uploads:\n            processData: false,\n            contentType: false,\n            cache: false,\n            timeout: 0\n        },\n\n        // A list of options that require reinitializing event listeners and/or\n        // special initialization code:\n        _specialOptions: [\n            'fileInput',\n            'dropZone',\n            'pasteZone',\n            'multipart',\n            'forceIframeTransport'\n        ],\n\n        _blobSlice: $.support.blobSlice && function () {\n            var slice = this.slice || this.webkitSlice || this.mozSlice;\n            return slice.apply(this, arguments);\n        },\n\n        _BitrateTimer: function () {\n            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());\n            this.loaded = 0;\n            this.bitrate = 0;\n            this.getBitrate = function (now, loaded, interval) {\n                var timeDiff = now - this.timestamp;\n                if (!this.bitrate || !interval || timeDiff > interval) {\n                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;\n                    this.loaded = loaded;\n                    this.timestamp = now;\n                }\n                return this.bitrate;\n            };\n        },\n\n        _isXHRUpload: function (options) {\n            return !options.forceIframeTransport &&\n                ((!options.multipart && $.support.xhrFileUpload) ||\n                $.support.xhrFormDataFileUpload);\n        },\n\n        _getFormData: function (options) {\n            var formData;\n            if ($.type(options.formData) === 'function') {\n                return options.formData(options.form);\n            }\n            if ($.isArray(options.formData)) {\n                return options.formData;\n            }\n            if ($.type(options.formData) === 'object') {\n                formData = [];\n                $.each(options.formData, function (name, value) {\n                    formData.push({name: name, value: value});\n                });\n                return formData;\n            }\n            return [];\n        },\n\n        _getTotal: function (files) {\n            var total = 0;\n            $.each(files, function (index, file) {\n                total += file.size || 1;\n            });\n            return total;\n        },\n\n        _initProgressObject: function (obj) {\n            var progress = {\n                loaded: 0,\n                total: 0,\n                bitrate: 0\n            };\n            if (obj._progress) {\n                $.extend(obj._progress, progress);\n            } else {\n                obj._progress = progress;\n            }\n        },\n\n        _initResponseObject: function (obj) {\n            var prop;\n            if (obj._response) {\n                for (prop in obj._response) {\n                    if (obj._response.hasOwnProperty(prop)) {\n                        delete obj._response[prop];\n                    }\n                }\n            } else {\n                obj._response = {};\n            }\n        },\n\n        _onProgress: function (e, data) {\n            if (e.lengthComputable) {\n                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),\n                    loaded;\n                if (data._time && data.progressInterval &&\n                        (now - data._time < data.progressInterval) &&\n                        e.loaded !== e.total) {\n                    return;\n                }\n                data._time = now;\n                loaded = Math.floor(\n                    e.loaded / e.total * (data.chunkSize || data._progress.total)\n                ) + (data.uploadedBytes || 0);\n                // Add the difference from the previously loaded state\n                // to the global loaded counter:\n                this._progress.loaded += (loaded - data._progress.loaded);\n                this._progress.bitrate = this._bitrateTimer.getBitrate(\n                    now,\n                    this._progress.loaded,\n                    data.bitrateInterval\n                );\n                data._progress.loaded = data.loaded = loaded;\n                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(\n                    now,\n                    loaded,\n                    data.bitrateInterval\n                );\n                // Trigger a custom progress event with a total data property set\n                // to the file size(s) of the current upload and a loaded data\n                // property calculated accordingly:\n                this._trigger(\n                    'progress',\n                    $.Event('progress', {delegatedEvent: e}),\n                    data\n                );\n                // Trigger a global progress event for all current file uploads,\n                // including ajax calls queued for sequential file uploads:\n                this._trigger(\n                    'progressall',\n                    $.Event('progressall', {delegatedEvent: e}),\n                    this._progress\n                );\n            }\n        },\n\n        _initProgressListener: function (options) {\n            var that = this,\n                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n            // Accesss to the native XHR object is required to add event listeners\n            // for the upload progress event:\n            if (xhr.upload) {\n                $(xhr.upload).bind('progress', function (e) {\n                    var oe = e.originalEvent;\n                    // Make sure the progress event properties get copied over:\n                    e.lengthComputable = oe.lengthComputable;\n                    e.loaded = oe.loaded;\n                    e.total = oe.total;\n                    that._onProgress(e, options);\n                });\n                options.xhr = function () {\n                    return xhr;\n                };\n            }\n        },\n\n        _deinitProgressListener: function (options) {\n            var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n            if (xhr.upload) {\n                $(xhr.upload).unbind('progress');\n            }\n        },\n\n        _isInstanceOf: function (type, obj) {\n            // Cross-frame instanceof check\n            return Object.prototype.toString.call(obj) === '[object ' + type + ']';\n        },\n\n        _initXHRData: function (options) {\n            var that = this,\n                formData,\n                file = options.files[0],\n                // Ignore non-multipart setting if not supported:\n                multipart = options.multipart || !$.support.xhrFileUpload,\n                paramName = $.type(options.paramName) === 'array' ?\n                    options.paramName[0] : options.paramName;\n            options.headers = $.extend({}, options.headers);\n            if (options.contentRange) {\n                options.headers['Content-Range'] = options.contentRange;\n            }\n            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {\n                options.headers['Content-Disposition'] = 'attachment; filename=\"' +\n                    encodeURI(file.uploadName || file.name) + '\"';\n            }\n            if (!multipart) {\n                options.contentType = file.type || 'application/octet-stream';\n                options.data = options.blob || file;\n            } else if ($.support.xhrFormDataFileUpload) {\n                if (options.postMessage) {\n                    // window.postMessage does not allow sending FormData\n                    // objects, so we just add the File/Blob objects to\n                    // the formData array and let the postMessage window\n                    // create the FormData object out of this array:\n                    formData = this._getFormData(options);\n                    if (options.blob) {\n                        formData.push({\n                            name: paramName,\n                            value: options.blob\n                        });\n                    } else {\n                        $.each(options.files, function (index, file) {\n                            formData.push({\n                                name: ($.type(options.paramName) === 'array' &&\n                                    options.paramName[index]) || paramName,\n                                value: file\n                            });\n                        });\n                    }\n                } else {\n                    if (that._isInstanceOf('FormData', options.formData)) {\n                        formData = options.formData;\n                    } else {\n                        formData = new FormData();\n                        $.each(this._getFormData(options), function (index, field) {\n                            formData.append(field.name, field.value);\n                        });\n                    }\n                    if (options.blob) {\n                        formData.append(\n                            paramName,\n                            options.blob,\n                            file.uploadName || file.name\n                        );\n                    } else {\n                        $.each(options.files, function (index, file) {\n                            // This check allows the tests to run with\n                            // dummy objects:\n                            if (that._isInstanceOf('File', file) ||\n                                    that._isInstanceOf('Blob', file)) {\n                                formData.append(\n                                    ($.type(options.paramName) === 'array' &&\n                                        options.paramName[index]) || paramName,\n                                    file,\n                                    file.uploadName || file.name\n                                );\n                            }\n                        });\n                    }\n                }\n                options.data = formData;\n            }\n            // Blob reference is not needed anymore, free memory:\n            options.blob = null;\n        },\n\n        _initIframeSettings: function (options) {\n            var targetHost = $('<a></a>').prop('href', options.url).prop('host');\n            // Setting the dataType to iframe enables the iframe transport:\n            options.dataType = 'iframe ' + (options.dataType || '');\n            // The iframe transport accepts a serialized array as form data:\n            options.formData = this._getFormData(options);\n            // Add redirect url to form data on cross-domain uploads:\n            if (options.redirect && targetHost && targetHost !== location.host) {\n                options.formData.push({\n                    name: options.redirectParamName || 'redirect',\n                    value: options.redirect\n                });\n            }\n        },\n\n        _initDataSettings: function (options) {\n            if (this._isXHRUpload(options)) {\n                if (!this._chunkedUpload(options, true)) {\n                    if (!options.data) {\n                        this._initXHRData(options);\n                    }\n                    this._initProgressListener(options);\n                }\n                if (options.postMessage) {\n                    // Setting the dataType to postmessage enables the\n                    // postMessage transport:\n                    options.dataType = 'postmessage ' + (options.dataType || '');\n                }\n            } else {\n                this._initIframeSettings(options);\n            }\n        },\n\n        _getParamName: function (options) {\n            var fileInput = $(options.fileInput),\n                paramName = options.paramName;\n            if (!paramName) {\n                paramName = [];\n                fileInput.each(function () {\n                    var input = $(this),\n                        name = input.prop('name') || 'files[]',\n                        i = (input.prop('files') || [1]).length;\n                    while (i) {\n                        paramName.push(name);\n                        i -= 1;\n                    }\n                });\n                if (!paramName.length) {\n                    paramName = [fileInput.prop('name') || 'files[]'];\n                }\n            } else if (!$.isArray(paramName)) {\n                paramName = [paramName];\n            }\n            return paramName;\n        },\n\n        _initFormSettings: function (options) {\n            // Retrieve missing options from the input field and the\n            // associated form, if available:\n            if (!options.form || !options.form.length) {\n                options.form = $(options.fileInput.prop('form'));\n                // If the given file input doesn't have an associated form,\n                // use the default widget file input's form:\n                if (!options.form.length) {\n                    options.form = $(this.options.fileInput.prop('form'));\n                }\n            }\n            options.paramName = this._getParamName(options);\n            if (!options.url) {\n                options.url = options.form.prop('action') || location.href;\n            }\n            // The HTTP request method must be \"POST\" or \"PUT\":\n            options.type = (options.type ||\n                ($.type(options.form.prop('method')) === 'string' &&\n                    options.form.prop('method')) || ''\n                ).toUpperCase();\n            if (options.type !== 'POST' && options.type !== 'PUT' &&\n                    options.type !== 'PATCH') {\n                options.type = 'POST';\n            }\n            if (!options.formAcceptCharset) {\n                options.formAcceptCharset = options.form.attr('accept-charset');\n            }\n        },\n\n        _getAJAXSettings: function (data) {\n            var options = $.extend({}, this.options, data);\n            this._initFormSettings(options);\n            this._initDataSettings(options);\n            return options;\n        },\n\n        // jQuery 1.6 doesn't provide .state(),\n        // while jQuery 1.8+ removed .isRejected() and .isResolved():\n        _getDeferredState: function (deferred) {\n            if (deferred.state) {\n                return deferred.state();\n            }\n            if (deferred.isResolved()) {\n                return 'resolved';\n            }\n            if (deferred.isRejected()) {\n                return 'rejected';\n            }\n            return 'pending';\n        },\n\n        // Maps jqXHR callbacks to the equivalent\n        // methods of the given Promise object:\n        _enhancePromise: function (promise) {\n            promise.success = promise.done;\n            promise.error = promise.fail;\n            promise.complete = promise.always;\n            return promise;\n        },\n\n        // Creates and returns a Promise object enhanced with\n        // the jqXHR methods abort, success, error and complete:\n        _getXHRPromise: function (resolveOrReject, context, args) {\n            var dfd = $.Deferred(),\n                promise = dfd.promise();\n            context = context || this.options.context || promise;\n            if (resolveOrReject === true) {\n                dfd.resolveWith(context, args);\n            } else if (resolveOrReject === false) {\n                dfd.rejectWith(context, args);\n            }\n            promise.abort = dfd.promise;\n            return this._enhancePromise(promise);\n        },\n\n        // Adds convenience methods to the data callback argument:\n        _addConvenienceMethods: function (e, data) {\n            var that = this,\n                getPromise = function (args) {\n                    return $.Deferred().resolveWith(that, args).promise();\n                };\n            data.process = function (resolveFunc, rejectFunc) {\n                if (resolveFunc || rejectFunc) {\n                    data._processQueue = this._processQueue =\n                        (this._processQueue || getPromise([this])).then(\n                            function () {\n                                if (data.errorThrown) {\n                                    return $.Deferred()\n                                        .rejectWith(that, [data]).promise();\n                                }\n                                return getPromise(arguments);\n                            }\n                        ).then(resolveFunc, rejectFunc);\n                }\n                return this._processQueue || getPromise([this]);\n            };\n            data.submit = function () {\n                if (this.state() !== 'pending') {\n                    data.jqXHR = this.jqXHR =\n                        (that._trigger(\n                            'submit',\n                            $.Event('submit', {delegatedEvent: e}),\n                            this\n                        ) !== false) && that._onSend(e, this);\n                }\n                return this.jqXHR || that._getXHRPromise();\n            };\n            data.abort = function () {\n                if (this.jqXHR) {\n                    return this.jqXHR.abort();\n                }\n                this.errorThrown = 'abort';\n                that._trigger('fail', null, this);\n                return that._getXHRPromise(false);\n            };\n            data.state = function () {\n                if (this.jqXHR) {\n                    return that._getDeferredState(this.jqXHR);\n                }\n                if (this._processQueue) {\n                    return that._getDeferredState(this._processQueue);\n                }\n            };\n            data.processing = function () {\n                return !this.jqXHR && this._processQueue && that\n                    ._getDeferredState(this._processQueue) === 'pending';\n            };\n            data.progress = function () {\n                return this._progress;\n            };\n            data.response = function () {\n                return this._response;\n            };\n        },\n\n        // Parses the Range header from the server response\n        // and returns the uploaded bytes:\n        _getUploadedBytes: function (jqXHR) {\n            var range = jqXHR.getResponseHeader('Range'),\n                parts = range && range.split('-'),\n                upperBytesPos = parts && parts.length > 1 &&\n                    parseInt(parts[1], 10);\n            return upperBytesPos && upperBytesPos + 1;\n        },\n\n        // Uploads a file in multiple, sequential requests\n        // by splitting the file up in multiple blob chunks.\n        // If the second parameter is true, only tests if the file\n        // should be uploaded in chunks, but does not invoke any\n        // upload requests:\n        _chunkedUpload: function (options, testOnly) {\n            options.uploadedBytes = options.uploadedBytes || 0;\n            var that = this,\n                file = options.files[0],\n                fs = file.size,\n                ub = options.uploadedBytes,\n                mcs = options.maxChunkSize || fs,\n                slice = this._blobSlice,\n                dfd = $.Deferred(),\n                promise = dfd.promise(),\n                jqXHR,\n                upload;\n            if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||\n                    options.data) {\n                return false;\n            }\n            if (testOnly) {\n                return true;\n            }\n            if (ub >= fs) {\n                file.error = options.i18n('uploadedBytes');\n                return this._getXHRPromise(\n                    false,\n                    options.context,\n                    [null, 'error', file.error]\n                );\n            }\n            // The chunk upload method:\n            upload = function () {\n                // Clone the options object for each chunk upload:\n                var o = $.extend({}, options),\n                    currentLoaded = o._progress.loaded;\n                o.blob = slice.call(\n                    file,\n                    ub,\n                    ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),\n                    file.type\n                );\n                // Store the current chunk size, as the blob itself\n                // will be dereferenced after data processing:\n                o.chunkSize = o.blob.size;\n                // Expose the chunk bytes position range:\n                o.contentRange = 'bytes ' + ub + '-' +\n                    (ub + o.chunkSize - 1) + '/' + fs;\n                // Trigger chunkbeforesend to allow form data to be updated for this chunk\n                that._trigger('chunkbeforesend', null, o);\n                // Process the upload data (the blob and potential form data):\n                that._initXHRData(o);\n                // Add progress listeners for this chunk upload:\n                that._initProgressListener(o);\n                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||\n                        that._getXHRPromise(false, o.context))\n                    .done(function (result, textStatus, jqXHR) {\n                        ub = that._getUploadedBytes(jqXHR) ||\n                            (ub + o.chunkSize);\n                        // Create a progress event if no final progress event\n                        // with loaded equaling total has been triggered\n                        // for this chunk:\n                        if (currentLoaded + o.chunkSize - o._progress.loaded) {\n                            that._onProgress($.Event('progress', {\n                                lengthComputable: true,\n                                loaded: ub - o.uploadedBytes,\n                                total: ub - o.uploadedBytes\n                            }), o);\n                        }\n                        options.uploadedBytes = o.uploadedBytes = ub;\n                        o.result = result;\n                        o.textStatus = textStatus;\n                        o.jqXHR = jqXHR;\n                        that._trigger('chunkdone', null, o);\n                        that._trigger('chunkalways', null, o);\n                        if (ub < fs) {\n                            // File upload not yet complete,\n                            // continue with the next chunk:\n                            upload();\n                        } else {\n                            dfd.resolveWith(\n                                o.context,\n                                [result, textStatus, jqXHR]\n                            );\n                        }\n                    })\n                    .fail(function (jqXHR, textStatus, errorThrown) {\n                        o.jqXHR = jqXHR;\n                        o.textStatus = textStatus;\n                        o.errorThrown = errorThrown;\n                        that._trigger('chunkfail', null, o);\n                        that._trigger('chunkalways', null, o);\n                        dfd.rejectWith(\n                            o.context,\n                            [jqXHR, textStatus, errorThrown]\n                        );\n                    })\n                    .always(function () {\n                        that._deinitProgressListener(o);\n                    });\n            };\n            this._enhancePromise(promise);\n            promise.abort = function () {\n                return jqXHR.abort();\n            };\n            upload();\n            return promise;\n        },\n\n        _beforeSend: function (e, data) {\n            if (this._active === 0) {\n                // the start callback is triggered when an upload starts\n                // and no other uploads are currently running,\n                // equivalent to the global ajaxStart event:\n                this._trigger('start');\n                // Set timer for global bitrate progress calculation:\n                this._bitrateTimer = new this._BitrateTimer();\n                // Reset the global progress values:\n                this._progress.loaded = this._progress.total = 0;\n                this._progress.bitrate = 0;\n            }\n            // Make sure the container objects for the .response() and\n            // .progress() methods on the data object are available\n            // and reset to their initial state:\n            this._initResponseObject(data);\n            this._initProgressObject(data);\n            data._progress.loaded = data.loaded = data.uploadedBytes || 0;\n            data._progress.total = data.total = this._getTotal(data.files) || 1;\n            data._progress.bitrate = data.bitrate = 0;\n            this._active += 1;\n            // Initialize the global progress values:\n            this._progress.loaded += data.loaded;\n            this._progress.total += data.total;\n        },\n\n        _onDone: function (result, textStatus, jqXHR, options) {\n            var total = options._progress.total,\n                response = options._response;\n            if (options._progress.loaded < total) {\n                // Create a progress event if no final progress event\n                // with loaded equaling total has been triggered:\n                this._onProgress($.Event('progress', {\n                    lengthComputable: true,\n                    loaded: total,\n                    total: total\n                }), options);\n            }\n            response.result = options.result = result;\n            response.textStatus = options.textStatus = textStatus;\n            response.jqXHR = options.jqXHR = jqXHR;\n            this._trigger('done', null, options);\n        },\n\n        _onFail: function (jqXHR, textStatus, errorThrown, options) {\n            var response = options._response;\n            if (options.recalculateProgress) {\n                // Remove the failed (error or abort) file upload from\n                // the global progress calculation:\n                this._progress.loaded -= options._progress.loaded;\n                this._progress.total -= options._progress.total;\n            }\n            response.jqXHR = options.jqXHR = jqXHR;\n            response.textStatus = options.textStatus = textStatus;\n            response.errorThrown = options.errorThrown = errorThrown;\n            this._trigger('fail', null, options);\n        },\n\n        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {\n            // jqXHRorResult, textStatus and jqXHRorError are added to the\n            // options object via done and fail callbacks\n            this._trigger('always', null, options);\n        },\n\n        _onSend: function (e, data) {\n            if (!data.submit) {\n                this._addConvenienceMethods(e, data);\n            }\n            var that = this,\n                jqXHR,\n                aborted,\n                slot,\n                pipe,\n                options = that._getAJAXSettings(data),\n                send = function () {\n                    that._sending += 1;\n                    // Set timer for bitrate progress calculation:\n                    options._bitrateTimer = new that._BitrateTimer();\n                    jqXHR = jqXHR || (\n                        ((aborted || that._trigger(\n                            'send',\n                            $.Event('send', {delegatedEvent: e}),\n                            options\n                        ) === false) &&\n                        that._getXHRPromise(false, options.context, aborted)) ||\n                        that._chunkedUpload(options) || $.ajax(options)\n                    ).done(function (result, textStatus, jqXHR) {\n                        that._onDone(result, textStatus, jqXHR, options);\n                    }).fail(function (jqXHR, textStatus, errorThrown) {\n                        that._onFail(jqXHR, textStatus, errorThrown, options);\n                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {\n                        that._deinitProgressListener(options);\n                        that._onAlways(\n                            jqXHRorResult,\n                            textStatus,\n                            jqXHRorError,\n                            options\n                        );\n                        that._sending -= 1;\n                        that._active -= 1;\n                        if (options.limitConcurrentUploads &&\n                                options.limitConcurrentUploads > that._sending) {\n                            // Start the next queued upload,\n                            // that has not been aborted:\n                            var nextSlot = that._slots.shift();\n                            while (nextSlot) {\n                                if (that._getDeferredState(nextSlot) === 'pending') {\n                                    nextSlot.resolve();\n                                    break;\n                                }\n                                nextSlot = that._slots.shift();\n                            }\n                        }\n                        if (that._active === 0) {\n                            // The stop callback is triggered when all uploads have\n                            // been completed, equivalent to the global ajaxStop event:\n                            that._trigger('stop');\n                        }\n                    });\n                    return jqXHR;\n                };\n            this._beforeSend(e, options);\n            if (this.options.sequentialUploads ||\n                    (this.options.limitConcurrentUploads &&\n                    this.options.limitConcurrentUploads <= this._sending)) {\n                if (this.options.limitConcurrentUploads > 1) {\n                    slot = $.Deferred();\n                    this._slots.push(slot);\n                    pipe = slot.then(send);\n                } else {\n                    this._sequence = this._sequence.then(send, send);\n                    pipe = this._sequence;\n                }\n                // Return the piped Promise object, enhanced with an abort method,\n                // which is delegated to the jqXHR object of the current upload,\n                // and jqXHR callbacks mapped to the equivalent Promise methods:\n                pipe.abort = function () {\n                    aborted = [undefined, 'abort', 'abort'];\n                    if (!jqXHR) {\n                        if (slot) {\n                            slot.rejectWith(options.context, aborted);\n                        }\n                        return send();\n                    }\n                    return jqXHR.abort();\n                };\n                return this._enhancePromise(pipe);\n            }\n            return send();\n        },\n\n        _onAdd: function (e, data) {\n            var that = this,\n                result = true,\n                options = $.extend({}, this.options, data),\n                files = data.files,\n                filesLength = files.length,\n                limit = options.limitMultiFileUploads,\n                limitSize = options.limitMultiFileUploadSize,\n                overhead = options.limitMultiFileUploadSizeOverhead,\n                batchSize = 0,\n                paramName = this._getParamName(options),\n                paramNameSet,\n                paramNameSlice,\n                fileSet,\n                i,\n                j = 0;\n            if (!filesLength) {\n                return false;\n            }\n            if (limitSize && files[0].size === undefined) {\n                limitSize = undefined;\n            }\n            if (!(options.singleFileUploads || limit || limitSize) ||\n                    !this._isXHRUpload(options)) {\n                fileSet = [files];\n                paramNameSet = [paramName];\n            } else if (!(options.singleFileUploads || limitSize) && limit) {\n                fileSet = [];\n                paramNameSet = [];\n                for (i = 0; i < filesLength; i += limit) {\n                    fileSet.push(files.slice(i, i + limit));\n                    paramNameSlice = paramName.slice(i, i + limit);\n                    if (!paramNameSlice.length) {\n                        paramNameSlice = paramName;\n                    }\n                    paramNameSet.push(paramNameSlice);\n                }\n            } else if (!options.singleFileUploads && limitSize) {\n                fileSet = [];\n                paramNameSet = [];\n                for (i = 0; i < filesLength; i = i + 1) {\n                    batchSize += files[i].size + overhead;\n                    if (i + 1 === filesLength ||\n                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||\n                            (limit && i + 1 - j >= limit)) {\n                        fileSet.push(files.slice(j, i + 1));\n                        paramNameSlice = paramName.slice(j, i + 1);\n                        if (!paramNameSlice.length) {\n                            paramNameSlice = paramName;\n                        }\n                        paramNameSet.push(paramNameSlice);\n                        j = i + 1;\n                        batchSize = 0;\n                    }\n                }\n            } else {\n                paramNameSet = paramName;\n            }\n            data.originalFiles = files;\n            $.each(fileSet || files, function (index, element) {\n                var newData = $.extend({}, data);\n                newData.files = fileSet ? element : [element];\n                newData.paramName = paramNameSet[index];\n                that._initResponseObject(newData);\n                that._initProgressObject(newData);\n                that._addConvenienceMethods(e, newData);\n                result = that._trigger(\n                    'add',\n                    $.Event('add', {delegatedEvent: e}),\n                    newData\n                );\n                return result;\n            });\n            return result;\n        },\n\n        _replaceFileInput: function (data) {\n            var input = data.fileInput,\n                inputClone = input.clone(true),\n                restoreFocus = input.is(document.activeElement);\n            // Add a reference for the new cloned file input to the data argument:\n            data.fileInputClone = inputClone;\n            $('<form></form>').append(inputClone)[0].reset();\n            // Detaching allows to insert the fileInput on another form\n            // without loosing the file input value:\n            input.after(inputClone).detach();\n            // If the fileInput had focus before it was detached,\n            // restore focus to the inputClone.\n            if (restoreFocus) {\n                inputClone.focus();\n            }\n            // Avoid memory leaks with the detached file input:\n            $.cleanData(input.unbind('remove'));\n            // Replace the original file input element in the fileInput\n            // elements set with the clone, which has been copied including\n            // event handlers:\n            this.options.fileInput = this.options.fileInput.map(function (i, el) {\n                if (el === input[0]) {\n                    return inputClone[0];\n                }\n                return el;\n            });\n            // If the widget has been initialized on the file input itself,\n            // override this.element with the file input clone:\n            if (input[0] === this.element[0]) {\n                this.element = inputClone;\n            }\n        },\n\n        _handleFileTreeEntry: function (entry, path) {\n            var that = this,\n                dfd = $.Deferred(),\n                entries = [],\n                dirReader,\n                errorHandler = function (e) {\n                    if (e && !e.entry) {\n                        e.entry = entry;\n                    }\n                    // Since $.when returns immediately if one\n                    // Deferred is rejected, we use resolve instead.\n                    // This allows valid files and invalid items\n                    // to be returned together in one set:\n                    dfd.resolve([e]);\n                },\n                successHandler = function (entries) {\n                    that._handleFileTreeEntries(\n                        entries,\n                        path + entry.name + '/'\n                    ).done(function (files) {\n                        dfd.resolve(files);\n                    }).fail(errorHandler);\n                },\n                readEntries = function () {\n                    dirReader.readEntries(function (results) {\n                        if (!results.length) {\n                            successHandler(entries);\n                        } else {\n                            entries = entries.concat(results);\n                            readEntries();\n                        }\n                    }, errorHandler);\n                };\n            path = path || '';\n            if (entry.isFile) {\n                if (entry._file) {\n                    // Workaround for Chrome bug #149735\n                    entry._file.relativePath = path;\n                    dfd.resolve(entry._file);\n                } else {\n                    entry.file(function (file) {\n                        file.relativePath = path;\n                        dfd.resolve(file);\n                    }, errorHandler);\n                }\n            } else if (entry.isDirectory) {\n                dirReader = entry.createReader();\n                readEntries();\n            } else {\n                // Return an empty list for file system items\n                // other than files or directories:\n                dfd.resolve([]);\n            }\n            return dfd.promise();\n        },\n\n        _handleFileTreeEntries: function (entries, path) {\n            var that = this;\n            return $.when.apply(\n                $,\n                $.map(entries, function (entry) {\n                    return that._handleFileTreeEntry(entry, path);\n                })\n            ).then(function () {\n                return Array.prototype.concat.apply(\n                    [],\n                    arguments\n                );\n            });\n        },\n\n        _getDroppedFiles: function (dataTransfer) {\n            dataTransfer = dataTransfer || {};\n            var items = dataTransfer.items;\n            if (items && items.length && (items[0].webkitGetAsEntry ||\n                    items[0].getAsEntry)) {\n                return this._handleFileTreeEntries(\n                    $.map(items, function (item) {\n                        var entry;\n                        if (item.webkitGetAsEntry) {\n                            entry = item.webkitGetAsEntry();\n                            if (entry) {\n                                // Workaround for Chrome bug #149735:\n                                entry._file = item.getAsFile();\n                            }\n                            return entry;\n                        }\n                        return item.getAsEntry();\n                    })\n                );\n            }\n            return $.Deferred().resolve(\n                $.makeArray(dataTransfer.files)\n            ).promise();\n        },\n\n        _getSingleFileInputFiles: function (fileInput) {\n            fileInput = $(fileInput);\n            var entries = fileInput.prop('webkitEntries') ||\n                    fileInput.prop('entries'),\n                files,\n                value;\n            if (entries && entries.length) {\n                return this._handleFileTreeEntries(entries);\n            }\n            files = $.makeArray(fileInput.prop('files'));\n            if (!files.length) {\n                value = fileInput.prop('value');\n                if (!value) {\n                    return $.Deferred().resolve([]).promise();\n                }\n                // If the files property is not available, the browser does not\n                // support the File API and we add a pseudo File object with\n                // the input value as name with path information removed:\n                files = [{name: value.replace(/^.*\\\\/, '')}];\n            } else if (files[0].name === undefined && files[0].fileName) {\n                // File normalization for Safari 4 and Firefox 3:\n                $.each(files, function (index, file) {\n                    file.name = file.fileName;\n                    file.size = file.fileSize;\n                });\n            }\n            return $.Deferred().resolve(files).promise();\n        },\n\n        _getFileInputFiles: function (fileInput) {\n            if (!(fileInput instanceof $) || fileInput.length === 1) {\n                return this._getSingleFileInputFiles(fileInput);\n            }\n            return $.when.apply(\n                $,\n                $.map(fileInput, this._getSingleFileInputFiles)\n            ).then(function () {\n                return Array.prototype.concat.apply(\n                    [],\n                    arguments\n                );\n            });\n        },\n\n        _onChange: function (e) {\n            var that = this,\n                data = {\n                    fileInput: $(e.target),\n                    form: $(e.target.form)\n                };\n            this._getFileInputFiles(data.fileInput).always(function (files) {\n                data.files = files;\n                if (that.options.replaceFileInput) {\n                    that._replaceFileInput(data);\n                }\n                if (that._trigger(\n                        'change',\n                        $.Event('change', {delegatedEvent: e}),\n                        data\n                    ) !== false) {\n                    that._onAdd(e, data);\n                }\n            });\n        },\n\n        _onPaste: function (e) {\n            var items = e.originalEvent && e.originalEvent.clipboardData &&\n                    e.originalEvent.clipboardData.items,\n                data = {files: []};\n            if (items && items.length) {\n                $.each(items, function (index, item) {\n                    var file = item.getAsFile && item.getAsFile();\n                    if (file) {\n                        data.files.push(file);\n                    }\n                });\n                if (this._trigger(\n                        'paste',\n                        $.Event('paste', {delegatedEvent: e}),\n                        data\n                    ) !== false) {\n                    this._onAdd(e, data);\n                }\n            }\n        },\n\n        _onDrop: function (e) {\n            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n            var that = this,\n                dataTransfer = e.dataTransfer,\n                data = {};\n            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n                e.preventDefault();\n                this._getDroppedFiles(dataTransfer).always(function (files) {\n                    data.files = files;\n                    if (that._trigger(\n                            'drop',\n                            $.Event('drop', {delegatedEvent: e}),\n                            data\n                        ) !== false) {\n                        that._onAdd(e, data);\n                    }\n                });\n            }\n        },\n\n        _onDragOver: getDragHandler('dragover'),\n\n        _onDragEnter: getDragHandler('dragenter'),\n\n        _onDragLeave: getDragHandler('dragleave'),\n\n        _initEventHandlers: function () {\n            if (this._isXHRUpload(this.options)) {\n                this._on(this.options.dropZone, {\n                    dragover: this._onDragOver,\n                    drop: this._onDrop,\n                    // event.preventDefault() on dragenter is required for IE10+:\n                    dragenter: this._onDragEnter,\n                    // dragleave is not required, but added for completeness:\n                    dragleave: this._onDragLeave\n                });\n                this._on(this.options.pasteZone, {\n                    paste: this._onPaste\n                });\n            }\n            if ($.support.fileInput) {\n                this._on(this.options.fileInput, {\n                    change: this._onChange\n                });\n            }\n        },\n\n        _destroyEventHandlers: function () {\n            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');\n            this._off(this.options.pasteZone, 'paste');\n            this._off(this.options.fileInput, 'change');\n        },\n\n        _destroy: function () {\n            this._destroyEventHandlers();\n        },\n\n        _setOption: function (key, value) {\n            var reinit = $.inArray(key, this._specialOptions) !== -1;\n            if (reinit) {\n                this._destroyEventHandlers();\n            }\n            this._super(key, value);\n            if (reinit) {\n                this._initSpecialOptions();\n                this._initEventHandlers();\n            }\n        },\n\n        _initSpecialOptions: function () {\n            var options = this.options;\n            if (options.fileInput === undefined) {\n                options.fileInput = this.element.is('input[type=\"file\"]') ?\n                        this.element : this.element.find('input[type=\"file\"]');\n            } else if (!(options.fileInput instanceof $)) {\n                options.fileInput = $(options.fileInput);\n            }\n            if (!(options.dropZone instanceof $)) {\n                options.dropZone = $(options.dropZone);\n            }\n            if (!(options.pasteZone instanceof $)) {\n                options.pasteZone = $(options.pasteZone);\n            }\n        },\n\n        _getRegExp: function (str) {\n            var parts = str.split('/'),\n                modifiers = parts.pop();\n            parts.shift();\n            return new RegExp(parts.join('/'), modifiers);\n        },\n\n        _isRegExpOption: function (key, value) {\n            return key !== 'url' && $.type(value) === 'string' &&\n                /^\\/.*\\/[igm]{0,3}$/.test(value);\n        },\n\n        _initDataAttributes: function () {\n            var that = this,\n                options = this.options,\n                data = this.element.data();\n            // Initialize options set via HTML5 data-attributes:\n            $.each(\n                this.element[0].attributes,\n                function (index, attr) {\n                    var key = attr.name.toLowerCase(),\n                        value;\n                    if (/^data-/.test(key)) {\n                        // Convert hyphen-ated key to camelCase:\n                        key = key.slice(5).replace(/-[a-z]/g, function (str) {\n                            return str.charAt(1).toUpperCase();\n                        });\n                        value = data[key];\n                        if (that._isRegExpOption(key, value)) {\n                            value = that._getRegExp(value);\n                        }\n                        options[key] = value;\n                    }\n                }\n            );\n        },\n\n        _create: function () {\n            this._initDataAttributes();\n            this._initSpecialOptions();\n            this._slots = [];\n            this._sequence = this._getXHRPromise(true);\n            this._sending = this._active = 0;\n            this._initProgressObject(this);\n            this._initEventHandlers();\n        },\n\n        // This method is exposed to the widget API and allows to query\n        // the number of active uploads:\n        active: function () {\n            return this._active;\n        },\n\n        // This method is exposed to the widget API and allows to query\n        // the widget upload progress.\n        // It returns an object with loaded, total and bitrate properties\n        // for the running uploads:\n        progress: function () {\n            return this._progress;\n        },\n\n        // This method is exposed to the widget API and allows adding files\n        // using the fileupload API. The data parameter accepts an object which\n        // must have a files property and can contain additional options:\n        // .fileupload('add', {files: filesList});\n        add: function (data) {\n            var that = this;\n            if (!data || this.options.disabled) {\n                return;\n            }\n            if (data.fileInput && !data.files) {\n                this._getFileInputFiles(data.fileInput).always(function (files) {\n                    data.files = files;\n                    that._onAdd(null, data);\n                });\n            } else {\n                data.files = $.makeArray(data.files);\n                this._onAdd(null, data);\n            }\n        },\n\n        // This method is exposed to the widget API and allows sending files\n        // using the fileupload API. The data parameter accepts an object which\n        // must have a files or fileInput property and can contain additional options:\n        // .fileupload('send', {files: filesList});\n        // The method returns a Promise object for the file upload call.\n        send: function (data) {\n            if (data && !this.options.disabled) {\n                if (data.fileInput && !data.files) {\n                    var that = this,\n                        dfd = $.Deferred(),\n                        promise = dfd.promise(),\n                        jqXHR,\n                        aborted;\n                    promise.abort = function () {\n                        aborted = true;\n                        if (jqXHR) {\n                            return jqXHR.abort();\n                        }\n                        dfd.reject(null, 'abort', 'abort');\n                        return promise;\n                    };\n                    this._getFileInputFiles(data.fileInput).always(\n                        function (files) {\n                            if (aborted) {\n                                return;\n                            }\n                            if (!files.length) {\n                                dfd.reject();\n                                return;\n                            }\n                            data.files = files;\n                            jqXHR = that._onSend(null, data);\n                            jqXHR.then(\n                                function (result, textStatus, jqXHR) {\n                                    dfd.resolve(result, textStatus, jqXHR);\n                                },\n                                function (jqXHR, textStatus, errorThrown) {\n                                    dfd.reject(jqXHR, textStatus, errorThrown);\n                                }\n                            );\n                        }\n                    );\n                    return this._enhancePromise(promise);\n                }\n                data.files = $.makeArray(data.files);\n                if (data.files.length) {\n                    return this._onSend(null, data);\n                }\n            }\n            return this._getXHRPromise(false, data && data.context);\n        }\n\n    });\n\n}));\n"]}