{"version":3,"sources":["jsdelivr-header.js","/npm/blueimp-file-upload@9.34.0/js/jquery.fileupload.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,CCQE,SAAU,GACR,aACsB,mBAAX,QAAyB,OAAO,IAEvC,OAAO,CACH,SACA,uBACD,GACuB,iBAAZ,QAEd,EACI,QAAQ,UACR,QAAQ,8BAIZ,EAAQ,OAAO,OAEvB,CAlBC,EAkBC,SAAU,GACR,aA2BA,SAAS,EAAe,GACpB,IAAI,EAAsB,aAAT,EACjB,OAAO,SAAU,GACb,EAAE,aAAe,EAAE,eAAiB,EAAE,cAAc,aACpD,IAAI,EAAe,EAAE,aACjB,IAA4D,IAA5C,EAAE,QAAQ,QAAS,EAAa,SAItC,IAHN,KAAK,SACD,EACA,EAAE,MAAM,EAAM,CAAC,eAAgB,OAEvC,EAAE,iBACE,IACA,EAAa,WAAa,QAGtC,CACJ,CAvCA,EAAE,QAAQ,YAAc,IAAI,OAExB,uJAIF,KAAK,OAAO,UAAU,YAEpB,EAAE,wBAAwB,KAAK,aAOnC,EAAE,QAAQ,iBAAmB,OAAO,gBAAiB,OAAO,YAC5D,EAAE,QAAQ,wBAA0B,OAAO,SAG3C,EAAE,QAAQ,UAAY,OAAO,OAAS,KAAK,UAAU,OACjD,KAAK,UAAU,aAAe,KAAK,UAAU,UA6BjD,EAAE,OAAO,qBAAsB,CAE3B,QAAS,CAGL,SAAU,EAAE,UAGZ,eAAW,EAKX,eAAW,EAKX,kBAAkB,EAKlB,eAAW,EAIX,mBAAmB,EAGnB,2BAAuB,EAIvB,8BAA0B,EAI1B,iCAAkC,IAGlC,mBAAmB,EAGnB,4BAAwB,EAExB,sBAAsB,EAGtB,cAAU,EAGV,uBAAmB,EAGnB,iBAAa,EAIb,WAAW,EAKX,kBAAc,EAMd,mBAAe,EAIf,qBAAqB,EAErB,iBAAkB,IAElB,gBAAiB,IAEjB,YAAY,EASZ,qBAAiB,EAGjB,SAAU,CACN,cAAe,mCAKnB,KAAM,SAAU,EAAS,GAOrB,OANA,EAAU,KAAK,SAAS,IAAY,EAAQ,WACxC,GACA,EAAE,KAAK,GAAS,SAAU,EAAK,GAC3B,EAAU,EAAQ,QAAQ,IAAM,EAAM,IAAK,EAC/C,IAEG,CACX,EAOA,SAAU,SAAU,GAChB,OAAO,EAAK,gBAChB,EAkBA,IAAK,SAAU,EAAG,GACd,GAAI,EAAE,qBACF,OAAO,GAEP,EAAK,aAAmC,IAApB,EAAK,YACrB,EAAE,MAAM,WAAW,SAAU,gBACjC,EAAK,UAAU,MAAK,WAChB,EAAK,QACT,GAER,EA4DA,aAAa,EACb,aAAa,EACb,OAAO,EACP,QAAS,GAKb,gBAAiB,CACb,YACA,WACA,YACA,YACA,wBAGJ,WAAY,EAAE,QAAQ,WAAa,WAE/B,OADY,KAAK,OAAS,KAAK,aAAe,KAAK,UACtC,MAAM,KAAM,UAC7B,EAEA,cAAe,WACX,KAAK,UAAc,KAAQ,IAAI,KAAK,OAAQ,IAAK,MAAQ,UACzD,KAAK,OAAS,EACd,KAAK,QAAU,EACf,KAAK,WAAa,SAAU,EAAK,EAAQ,GACrC,IAAI,EAAW,EAAM,KAAK,UAM1B,QALK,KAAK,UAAY,GAAY,EAAW,KACzC,KAAK,SAAW,EAAS,KAAK,SAAW,IAAO,GAAY,EAC5D,KAAK,OAAS,EACd,KAAK,UAAY,GAEd,KAAK,OAChB,CACJ,EAEA,aAAc,SAAU,GACpB,OAAQ,EAAQ,wBACT,EAAQ,WAAa,EAAE,QAAQ,eAClC,EAAE,QAAQ,sBAClB,EAEA,aAAc,SAAU,GACpB,IAAI,EACJ,MAAiC,aAA7B,EAAE,KAAK,EAAQ,UACR,EAAQ,SAAS,EAAQ,MAEhC,EAAE,QAAQ,EAAQ,UACX,EAAQ,SAEc,WAA7B,EAAE,KAAK,EAAQ,WACf,EAAW,GACX,EAAE,KAAK,EAAQ,UAAU,SAAU,EAAM,GACrC,EAAS,KAAK,CAAC,KAAM,EAAM,MAAO,GACtC,IACO,GAEJ,EACX,EAEA,UAAW,SAAU,GACjB,IAAI,EAAQ,EAIZ,OAHA,EAAE,KAAK,GAAO,SAAU,EAAO,GAC3B,GAAS,EAAK,MAAQ,CAC1B,IACO,CACX,EAEA,oBAAqB,SAAU,GAC3B,IAAI,EAAW,CACX,OAAQ,EACR,MAAO,EACP,QAAS,GAET,EAAI,UACJ,EAAE,OAAO,EAAI,UAAW,GAExB,EAAI,UAAY,CAExB,EAEA,oBAAqB,SAAU,GAC3B,IAAI,EACJ,GAAI,EAAI,UACJ,IAAK,KAAQ,EAAI,UACT,EAAI,UAAU,eAAe,WACtB,EAAI,UAAU,QAI7B,EAAI,UAAY,CAAC,CAEzB,EAEA,YAAa,SAAU,EAAG,GACtB,GAAI,EAAE,iBAAkB,CACpB,IACI,EADA,EAAQ,KAAQ,IAAI,KAAK,OAAQ,IAAK,MAAQ,UAElD,GAAI,EAAK,OAAS,EAAK,kBACd,EAAM,EAAK,MAAQ,EAAK,kBACzB,EAAE,SAAW,EAAE,MACnB,OAEJ,EAAK,MAAQ,EACb,EAAS,KAAK,MACV,EAAE,OAAS,EAAE,OAAS,EAAK,WAAa,EAAK,UAAU,SACtD,EAAK,eAAiB,GAG3B,KAAK,UAAU,QAAW,EAAS,EAAK,UAAU,OAClD,KAAK,UAAU,QAAU,KAAK,cAAc,WACxC,EACA,KAAK,UAAU,OACf,EAAK,iBAET,EAAK,UAAU,OAAS,EAAK,OAAS,EACtC,EAAK,UAAU,QAAU,EAAK,QAAU,EAAK,cAAc,WACvD,EACA,EACA,EAAK,iBAKT,KAAK,SACD,WACA,EAAE,MAAM,WAAY,CAAC,eAAgB,IACrC,GAIJ,KAAK,SACD,cACA,EAAE,MAAM,cAAe,CAAC,eAAgB,IACxC,KAAK,UAEb,CACJ,EAEA,sBAAuB,SAAU,GAC7B,IAAI,EAAO,KACP,EAAM,EAAQ,IAAM,EAAQ,MAAQ,EAAE,aAAa,MAGnD,EAAI,SACJ,EAAE,EAAI,QAAQ,KAAK,YAAY,SAAU,GACrC,IAAI,EAAK,EAAE,cAEX,EAAE,iBAAmB,EAAG,iBACxB,EAAE,OAAS,EAAG,OACd,EAAE,MAAQ,EAAG,MACb,EAAK,YAAY,EAAG,EACxB,IACA,EAAQ,IAAM,WACV,OAAO,CACX,EAER,EAEA,wBAAyB,SAAU,GAC/B,IAAI,EAAM,EAAQ,IAAM,EAAQ,MAAQ,EAAE,aAAa,MACnD,EAAI,QACJ,EAAE,EAAI,QAAQ,OAAO,WAE7B,EAEA,cAAe,SAAU,EAAM,GAE3B,OAAO,OAAO,UAAU,SAAS,KAAK,KAAS,WAAa,EAAO,GACvE,EAEA,mBAAoB,SAAU,EAAM,GAEhC,OAAI,EADJ,EAAO,OAAO,KAEV,EAAO,EAAK,QACR,gCACA,SAAU,EAAG,EAAI,GAGb,MAAO,MAFK,EAAK,OAAO,GAAM,EAAI,GAEZ,KADZ,GAAM,GAEpB,IAEG,KAAK,mBAAmB,EAAM,KAEzC,EAAI,IAAQ,EACL,EACX,EAEA,aAAc,SAAU,GACpB,IACI,EADA,EAAO,KAEP,EAAO,EAAQ,MAAM,GAErB,EAAY,EAAQ,YAAc,EAAE,QAAQ,cAC5C,EAA0C,UAA9B,EAAE,KAAK,EAAQ,WACvB,EAAQ,UAAU,GAAK,EAAQ,UACvC,EAAQ,QAAU,EAAE,OAAO,CAAC,EAAG,EAAQ,SACnC,EAAQ,eACR,EAAQ,QAAQ,iBAAmB,EAAQ,cAE1C,IAAa,EAAQ,MAAS,KAAK,cAAc,OAAQ,KAC1D,EAAQ,QAAQ,uBAAyB,yBACrC,UAAU,EAAK,YAAc,EAAK,MAAQ,KAE7C,EAGM,EAAE,QAAQ,wBACb,EAAQ,aAKR,EAAW,KAAK,aAAa,GACzB,EAAQ,KACR,EAAS,KAAK,CACV,KAAM,EACN,MAAO,EAAQ,OAGnB,EAAE,KAAK,EAAQ,OAAO,SAAU,EAAO,GACnC,EAAS,KAAK,CACV,KAAqC,UAA9B,EAAE,KAAK,EAAQ,YAClB,EAAQ,UAAU,IAAW,EACjC,MAAO,GAEf,MAGA,EAAK,cAAc,WAAY,EAAQ,UACvC,EAAW,EAAQ,UAEnB,EAAW,IAAI,SACf,EAAE,KAAK,KAAK,aAAa,IAAU,SAAU,EAAO,GAChD,EAAS,OAAO,EAAM,KAAM,EAAM,MACtC,KAEA,EAAQ,KACR,EAAS,OACL,EACA,EAAQ,KACR,EAAK,YAAc,EAAK,MAG5B,EAAE,KAAK,EAAQ,OAAO,SAAU,EAAO,GAGnC,GAAI,EAAK,cAAc,OAAQ,IACvB,EAAK,cAAc,OAAQ,GAAO,CACtC,IAAI,EAAW,EAAK,YAAc,EAAK,KACnC,EAAQ,kBACR,EAAW,EAAK,mBACZ,EACA,EAAQ,kBAGhB,EAAS,OAC0B,UAA9B,EAAE,KAAK,EAAQ,YACZ,EAAQ,UAAU,IAAW,EACjC,EACA,EAER,CACJ,KAGR,EAAQ,KAAO,IA7Df,EAAQ,YAAc,EAAK,MAAQ,2BACnC,EAAQ,KAAO,EAAQ,MAAQ,GA+DnC,EAAQ,KAAO,IACnB,EAEA,oBAAqB,SAAU,GAC3B,IAAI,EAAa,EAAE,WAAW,KAAK,OAAQ,EAAQ,KAAK,KAAK,QAE7D,EAAQ,SAAW,WAAa,EAAQ,UAAY,IAEpD,EAAQ,SAAW,KAAK,aAAa,GAEjC,EAAQ,UAAY,GAAc,IAAe,SAAS,MAC1D,EAAQ,SAAS,KAAK,CAClB,KAAM,EAAQ,mBAAqB,WACnC,MAAO,EAAQ,UAG3B,EAEA,kBAAmB,SAAU,GACrB,KAAK,aAAa,IACb,KAAK,eAAe,GAAS,KACzB,EAAQ,MACT,KAAK,aAAa,GAEtB,KAAK,sBAAsB,IAE3B,EAAQ,cAGR,EAAQ,SAAW,gBAAkB,EAAQ,UAAY,MAG7D,KAAK,oBAAoB,EAEjC,EAEA,cAAe,SAAU,GACrB,IAAI,EAAY,EAAE,EAAQ,WACtB,EAAY,EAAQ,UAkBxB,OAjBK,EAcO,EAAE,QAAQ,KAClB,EAAY,CAAC,KAdb,EAAY,GACZ,EAAU,MAAK,WAIX,IAHA,IAAI,EAAQ,EAAE,MACV,EAAO,EAAM,KAAK,SAAW,UAC7B,GAAK,EAAM,KAAK,UAAY,CAAC,IAAI,OAC9B,GACH,EAAU,KAAK,GACf,GAAK,CAEb,IACK,EAAU,SACX,EAAY,CAAC,EAAU,KAAK,SAAW,aAKxC,CACX,EAEA,kBAAmB,SAAU,GAGpB,EAAQ,MAAS,EAAQ,KAAK,SAC/B,EAAQ,KAAO,EAAE,EAAQ,UAAU,KAAK,SAGnC,EAAQ,KAAK,SACd,EAAQ,KAAO,EAAE,KAAK,QAAQ,UAAU,KAAK,WAGrD,EAAQ,UAAY,KAAK,cAAc,GAClC,EAAQ,MACT,EAAQ,IAAM,EAAQ,KAAK,KAAK,WAAa,SAAS,MAG1D,EAAQ,MAAQ,EAAQ,MACqB,WAAxC,EAAE,KAAK,EAAQ,KAAK,KAAK,YACtB,EAAQ,KAAK,KAAK,WAAc,IAClC,cACe,SAAjB,EAAQ,MAAoC,QAAjB,EAAQ,MACd,UAAjB,EAAQ,OACZ,EAAQ,KAAO,QAEd,EAAQ,oBACT,EAAQ,kBAAoB,EAAQ,KAAK,KAAK,kBAEtD,EAEA,iBAAkB,SAAU,GACxB,IAAI,EAAU,EAAE,OAAO,CAAC,EAAG,KAAK,QAAS,GAGzC,OAFA,KAAK,kBAAkB,GACvB,KAAK,kBAAkB,GAChB,CACX,EAIA,kBAAmB,SAAU,GACzB,OAAI,EAAS,MACF,EAAS,QAEhB,EAAS,aACF,WAEP,EAAS,aACF,WAEJ,SACX,EAIA,gBAAiB,SAAU,GAIvB,OAHA,EAAQ,QAAU,EAAQ,KAC1B,EAAQ,MAAQ,EAAQ,KACxB,EAAQ,SAAW,EAAQ,OACpB,CACX,EAIA,eAAgB,SAAU,EAAiB,EAAS,GAChD,IAAI,EAAM,EAAE,WACR,EAAU,EAAI,UAQlB,OAPA,EAAU,GAAW,KAAK,QAAQ,SAAW,GACrB,IAApB,EACA,EAAI,YAAY,EAAS,IACE,IAApB,GACP,EAAI,WAAW,EAAS,GAE5B,EAAQ,MAAQ,EAAI,QACb,KAAK,gBAAgB,EAChC,EAGA,uBAAwB,SAAU,EAAG,GACjC,IAAI,EAAO,KACP,EAAa,SAAU,GACnB,OAAO,EAAE,WAAW,YAAY,EAAM,GAAM,SAChD,EACJ,EAAK,QAAU,SAAU,EAAa,GAalC,OAZI,GAAe,KACf,EAAK,cAAgB,KAAK,eACrB,KAAK,eAAiB,EAAW,CAAC,QAAQ,MACvC,WACI,OAAI,EAAK,YACE,EAAE,WACJ,WAAW,EAAM,CAAC,IAAO,UAE3B,EAAW,UACtB,IACF,KAAK,EAAa,IAErB,KAAK,eAAiB,EAAW,CAAC,MAC7C,EACA,EAAK,OAAS,WASV,MARqB,YAAjB,KAAK,UACL,EAAK,MAAQ,KAAK,OAKR,IAJL,EAAK,SACF,SACA,EAAE,MAAM,SAAU,CAAC,eAAgB,IACnC,OACY,EAAK,QAAQ,EAAG,OAEjC,KAAK,OAAS,EAAK,gBAC9B,EACA,EAAK,MAAQ,WACT,OAAI,KAAK,MACE,KAAK,MAAM,SAEtB,KAAK,YAAc,QACnB,EAAK,SAAS,OAAQ,KAAM,MACrB,EAAK,gBAAe,GAC/B,EACA,EAAK,MAAQ,WACT,OAAI,KAAK,MACE,EAAK,kBAAkB,KAAK,OAEnC,KAAK,cACE,EAAK,kBAAkB,KAAK,oBADvC,CAGJ,EACA,EAAK,WAAa,WACd,OAAQ,KAAK,OAAS,KAAK,eACoB,YADH,EACvC,kBAAkB,KAAK,cAChC,EACA,EAAK,SAAW,WACZ,OAAO,KAAK,SAChB,EACA,EAAK,SAAW,WACZ,OAAO,KAAK,SAChB,CACJ,EAIA,kBAAmB,SAAU,GACzB,IAAI,EAAQ,EAAM,kBAAkB,SAChC,EAAQ,GAAS,EAAM,MAAM,KAC7B,EAAgB,GAAS,EAAM,OAAS,GACpC,SAAS,EAAM,GAAI,IAC3B,OAAO,GAAiB,EAAgB,CAC5C,EAOA,eAAgB,SAAU,EAAS,GAC/B,EAAQ,cAAgB,EAAQ,eAAiB,EACjD,IAQI,EACA,EATA,EAAO,KACP,EAAO,EAAQ,MAAM,GACrB,EAAK,EAAK,KACV,EAAK,EAAQ,cACb,EAAM,EAAQ,cAAgB,EAC9B,EAAQ,KAAK,WACb,EAAM,EAAE,WACR,EAAU,EAAI,UAGlB,UAAM,KAAK,aAAa,IAAY,IAAU,IAAuB,aAAhB,EAAE,KAAK,GAAsB,EAAI,GAAW,GAAO,KAChG,EAAQ,UAGZ,IAGA,GAAM,GACN,EAAK,MAAQ,EAAQ,KAAK,iBACnB,KAAK,gBACR,EACA,EAAQ,QACR,CAAC,KAAM,QAAS,EAAK,UAI7B,EAAS,WAEL,IAAI,EAAI,EAAE,OAAO,CAAC,EAAG,GACjB,EAAgB,EAAE,UAAU,OAChC,EAAE,KAAO,EAAM,KACX,EACA,EACA,GAAsB,aAAhB,EAAE,KAAK,GAAsB,EAAI,GAAK,GAC5C,EAAK,MAIT,EAAE,UAAY,EAAE,KAAK,KAErB,EAAE,aAAe,SAAW,EAAK,KAC5B,EAAK,EAAE,UAAY,GAAK,IAAM,EAEnC,EAAK,SAAS,kBAAmB,KAAM,GAEvC,EAAK,aAAa,GAElB,EAAK,sBAAsB,GAC3B,IAAkD,IAAxC,EAAK,SAAS,YAAa,KAAM,IAAgB,EAAE,KAAK,IAC1D,EAAK,gBAAe,EAAO,EAAE,UAChC,MAAK,SAAU,EAAQ,EAAY,GAChC,EAAK,EAAK,kBAAkB,IACvB,EAAK,EAAE,UAIR,EAAgB,EAAE,UAAY,EAAE,UAAU,QAC1C,EAAK,YAAY,EAAE,MAAM,WAAY,CACjC,kBAAkB,EAClB,OAAQ,EAAK,EAAE,cACf,MAAO,EAAK,EAAE,gBACd,GAER,EAAQ,cAAgB,EAAE,cAAgB,EAC1C,EAAE,OAAS,EACX,EAAE,WAAa,EACf,EAAE,MAAQ,EACV,EAAK,SAAS,YAAa,KAAM,GACjC,EAAK,SAAS,cAAe,KAAM,GAC/B,EAAK,EAGL,IAEA,EAAI,YACA,EAAE,QACF,CAAC,EAAQ,EAAY,GAGjC,IACC,MAAK,SAAU,EAAO,EAAY,GAC/B,EAAE,MAAQ,EACV,EAAE,WAAa,EACf,EAAE,YAAc,EAChB,EAAK,SAAS,YAAa,KAAM,GACjC,EAAK,SAAS,cAAe,KAAM,GACnC,EAAI,WACA,EAAE,QACF,CAAC,EAAO,EAAY,GAE5B,IACC,QAAO,WACJ,EAAK,wBAAwB,EACjC,GACR,EACA,KAAK,gBAAgB,GACrB,EAAQ,MAAQ,WACZ,OAAO,EAAM,OACjB,EACA,IACO,IACX,EAEA,YAAa,SAAU,EAAG,GACD,IAAjB,KAAK,UAIL,KAAK,SAAS,SAEd,KAAK,cAAgB,IAAI,KAAK,cAE9B,KAAK,UAAU,OAAS,KAAK,UAAU,MAAQ,EAC/C,KAAK,UAAU,QAAU,GAK7B,KAAK,oBAAoB,GACzB,KAAK,oBAAoB,GACzB,EAAK,UAAU,OAAS,EAAK,OAAS,EAAK,eAAiB,EAC5D,EAAK,UAAU,MAAQ,EAAK,MAAQ,KAAK,UAAU,EAAK,QAAU,EAClE,EAAK,UAAU,QAAU,EAAK,QAAU,EACxC,KAAK,SAAW,EAEhB,KAAK,UAAU,QAAU,EAAK,OAC9B,KAAK,UAAU,OAAS,EAAK,KACjC,EAEA,QAAS,SAAU,EAAQ,EAAY,EAAO,GAC1C,IAAI,EAAQ,EAAQ,UAAU,MAC1B,EAAW,EAAQ,UACnB,EAAQ,UAAU,OAAS,GAG3B,KAAK,YAAY,EAAE,MAAM,WAAY,CACjC,kBAAkB,EAClB,OAAQ,EACR,MAAO,IACP,GAER,EAAS,OAAS,EAAQ,OAAS,EACnC,EAAS,WAAa,EAAQ,WAAa,EAC3C,EAAS,MAAQ,EAAQ,MAAQ,EACjC,KAAK,SAAS,OAAQ,KAAM,EAChC,EAEA,QAAS,SAAU,EAAO,EAAY,EAAa,GAC/C,IAAI,EAAW,EAAQ,UACnB,EAAQ,sBAGR,KAAK,UAAU,QAAU,EAAQ,UAAU,OAC3C,KAAK,UAAU,OAAS,EAAQ,UAAU,OAE9C,EAAS,MAAQ,EAAQ,MAAQ,EACjC,EAAS,WAAa,EAAQ,WAAa,EAC3C,EAAS,YAAc,EAAQ,YAAc,EAC7C,KAAK,SAAS,OAAQ,KAAM,EAChC,EAEA,UAAW,SAAU,EAAe,EAAY,EAAc,GAG1D,KAAK,SAAS,SAAU,KAAM,EAClC,EAEA,QAAS,SAAU,EAAG,GACb,EAAK,QACN,KAAK,uBAAuB,EAAG,GAEnC,IACI,EACA,EACA,EACA,EAJA,EAAO,KAKP,EAAU,EAAK,iBAAiB,GAChC,EAAO,WA6CH,OA5CA,EAAK,UAAY,EAEjB,EAAQ,cAAgB,IAAI,EAAK,cACjC,EAAQ,KACF,IAII,IAJO,EAAK,SACd,OACA,EAAE,MAAM,OAAQ,CAAC,eAAgB,IACjC,KAEJ,EAAK,gBAAe,EAAO,EAAQ,QAAS,IAC5C,EAAK,eAAe,IAAY,EAAE,KAAK,IACzC,MAAK,SAAU,EAAQ,EAAY,GACjC,EAAK,QAAQ,EAAQ,EAAY,EAAO,EAC5C,IAAG,MAAK,SAAU,EAAO,EAAY,GACjC,EAAK,QAAQ,EAAO,EAAY,EAAa,EACjD,IAAG,QAAO,SAAU,EAAe,EAAY,GAU3C,GATA,EAAK,wBAAwB,GAC7B,EAAK,UACD,EACA,EACA,EACA,GAEJ,EAAK,UAAY,EACjB,EAAK,SAAW,EACZ,EAAQ,wBACJ,EAAQ,uBAAyB,EAAK,SAI1C,IADA,IAAI,EAAW,EAAK,OAAO,QACpB,GAAU,CACb,GAAyC,YAArC,EAAK,kBAAkB,GAAyB,CAChD,EAAS,UACT,KACJ,CACA,EAAW,EAAK,OAAO,OAC3B,CAEiB,IAAjB,EAAK,SAGL,EAAK,SAAS,OAEtB,GAEJ,EAEJ,OADA,KAAK,YAAY,EAAG,GAChB,KAAK,QAAQ,mBACR,KAAK,QAAQ,wBACd,KAAK,QAAQ,wBAA0B,KAAK,UAC5C,KAAK,QAAQ,uBAAyB,GACtC,EAAO,EAAE,WACT,KAAK,OAAO,KAAK,GACjB,EAAO,EAAK,KAAK,KAEjB,KAAK,UAAY,KAAK,UAAU,KAAK,EAAM,GAC3C,EAAO,KAAK,WAKhB,EAAK,MAAQ,WAET,OADA,EAAU,MAAC,EAAW,QAAS,SAC1B,EAME,EAAM,SALL,GACA,EAAK,WAAW,EAAQ,QAAS,GAE9B,IAGf,EACO,KAAK,gBAAgB,IAEzB,GACX,EAEA,OAAQ,SAAU,EAAG,GACjB,IAUI,EACA,EACA,EACA,EAbA,EAAO,KACP,GAAS,EACT,EAAU,EAAE,OAAO,CAAC,EAAG,KAAK,QAAS,GACrC,EAAQ,EAAK,MACb,EAAc,EAAM,OACpB,EAAQ,EAAQ,sBAChB,EAAY,EAAQ,yBACpB,EAAW,EAAQ,iCACnB,EAAY,EACZ,EAAY,KAAK,cAAc,GAK/B,EAAI,EACR,IAAK,EACD,OAAO,EAKX,GAHI,QAA+B,IAAlB,EAAM,GAAG,OACtB,OAAY,IAEV,EAAQ,mBAAqB,GAAS,IACnC,KAAK,aAAa,GAGpB,GAAM,EAAQ,mBAAqB,IAAc,EAWjD,IAAK,EAAQ,mBAAqB,EAGrC,IAFA,EAAU,GACV,EAAe,GACV,EAAI,EAAG,EAAI,EAAa,GAAQ,EACjC,GAAa,EAAM,GAAG,KAAO,GACzB,EAAI,IAAM,GACJ,EAAY,EAAM,EAAI,GAAG,KAAO,EAAY,GAC7C,GAAS,EAAI,EAAI,GAAK,KAC3B,EAAQ,KAAK,EAAM,MAAM,EAAG,EAAI,KAChC,EAAiB,EAAU,MAAM,EAAG,EAAI,IACpB,SAChB,EAAiB,GAErB,EAAa,KAAK,GAClB,EAAI,EAAI,EACR,EAAY,QAIpB,EAAe,OA3Bf,IAFA,EAAU,GACV,EAAe,GACV,EAAI,EAAG,EAAI,EAAa,GAAK,EAC9B,EAAQ,KAAK,EAAM,MAAM,EAAG,EAAI,KAChC,EAAiB,EAAU,MAAM,EAAG,EAAI,IACpB,SAChB,EAAiB,GAErB,EAAa,KAAK,QAXtB,EAAU,CAAC,GACX,EAAe,CAAC,GAgDpB,OAfA,EAAK,cAAgB,EACrB,EAAE,KAAK,GAAW,GAAO,SAAU,EAAO,GACtC,IAAI,EAAU,EAAE,OAAO,CAAC,EAAG,GAW3B,OAVA,EAAQ,MAAQ,EAAU,EAAU,CAAC,GACrC,EAAQ,UAAY,EAAa,GACjC,EAAK,oBAAoB,GACzB,EAAK,oBAAoB,GACzB,EAAK,uBAAuB,EAAG,GAC/B,EAAS,EAAK,SACV,MACA,EAAE,MAAM,MAAO,CAAC,eAAgB,IAChC,EAGR,IACO,CACX,EAEA,kBAAmB,SAAU,GACzB,IAAI,EAAQ,EAAK,UACb,EAAa,EAAM,OAAM,GACzB,EAAe,EAAM,GAAG,SAAS,eAErC,EAAK,eAAiB,EACtB,EAAE,iBAAiB,OAAO,GAAY,GAAG,QAGzC,EAAM,MAAM,GAAY,SAGpB,GACA,EAAW,QAGf,EAAE,UAAU,EAAM,OAAO,WAIzB,KAAK,QAAQ,UAAY,KAAK,QAAQ,UAAU,KAAI,SAAU,EAAG,GAC7D,OAAI,IAAO,EAAM,GACN,EAAW,GAEf,CACX,IAGI,EAAM,KAAO,KAAK,QAAQ,KAC1B,KAAK,QAAU,EAEvB,EAEA,qBAAsB,SAAU,EAAO,GACnC,IAGI,EAHA,EAAO,KACP,EAAM,EAAE,WACR,EAAU,GAEV,EAAe,SAAU,GACjB,IAAM,EAAE,QACR,EAAE,MAAQ,GAMd,EAAI,QAAQ,CAAC,GACjB,EASA,EAAc,WACV,EAAU,aAAY,SAAU,GACvB,EAAQ,QAGT,EAAU,EAAQ,OAAO,GACzB,KAdK,SAAU,GACvB,EAAK,uBACD,EACA,EAAO,EAAM,KAAO,KACtB,MAAK,SAAU,GACb,EAAI,QAAQ,EAChB,IAAG,KAAK,EACZ,CAIY,CAAe,EAKvB,GAAG,EACP,EAqBJ,OApBA,EAAO,GAAQ,GACX,EAAM,OACF,EAAM,OAEN,EAAM,MAAM,aAAe,EAC3B,EAAI,QAAQ,EAAM,QAElB,EAAM,MAAK,SAAU,GACjB,EAAK,aAAe,EACpB,EAAI,QAAQ,EAChB,GAAG,GAEA,EAAM,aACb,EAAY,EAAM,eAClB,KAIA,EAAI,QAAQ,IAET,EAAI,SACf,EAEA,uBAAwB,SAAU,EAAS,GACvC,IAAI,EAAO,KACX,OAAO,EAAE,KAAK,MACV,EACA,EAAE,IAAI,GAAS,SAAU,GACrB,OAAO,EAAK,qBAAqB,EAAO,EAC5C,KACF,MAAK,WACH,OAAO,MAAM,UAAU,OAAO,MAC1B,GACA,UAER,GACJ,EAEA,iBAAkB,SAAU,GAExB,IAAI,GADJ,EAAe,GAAgB,CAAC,GACP,MACzB,OAAI,GAAS,EAAM,SAAW,EAAM,GAAG,kBAC/B,EAAM,GAAG,YACN,KAAK,uBACR,EAAE,IAAI,GAAO,SAAU,GACnB,IAAI,EACJ,OAAI,EAAK,mBACL,EAAQ,EAAK,sBAGT,EAAM,MAAQ,EAAK,aAEhB,GAEJ,EAAK,YAChB,KAGD,EAAE,WAAW,QAChB,EAAE,UAAU,EAAa,QAC3B,SACN,EAEA,yBAA0B,SAAU,GAEhC,IAEI,EACA,EAHA,GADJ,EAAY,EAAE,IACU,KAAK,kBACrB,EAAU,KAAK,WAGvB,GAAI,GAAW,EAAQ,OACnB,OAAO,KAAK,uBAAuB,GAGvC,IADA,EAAQ,EAAE,UAAU,EAAU,KAAK,WACxB,YASkB,IAAlB,EAAM,GAAG,MAAsB,EAAM,GAAG,UAE/C,EAAE,KAAK,GAAO,SAAU,EAAO,GAC3B,EAAK,KAAO,EAAK,SACjB,EAAK,KAAO,EAAK,QACrB,QAde,CAEf,KADA,EAAQ,EAAU,KAAK,UAEnB,OAAO,EAAE,WAAW,QAAQ,IAAI,UAKpC,EAAQ,CAAC,CAAC,KAAM,EAAM,QAAQ,QAAS,KAC3C,CAOA,OAAO,EAAE,WAAW,QAAQ,GAAO,SACvC,EAEA,mBAAoB,SAAU,GAC1B,OAAM,aAAqB,GAA2B,IAArB,EAAU,OAGpC,EAAE,KAAK,MACV,EACA,EAAE,IAAI,EAAW,KAAK,2BACxB,MAAK,WACH,OAAO,MAAM,UAAU,OAAO,MAC1B,GACA,UAER,IAVW,KAAK,yBAAyB,EAW7C,EAEA,UAAW,SAAU,GACjB,IAAI,EAAO,KACP,EAAO,CACH,UAAW,EAAE,EAAE,QACf,KAAM,EAAE,EAAE,OAAO,OAEzB,KAAK,mBAAmB,EAAK,WAAW,QAAO,SAAU,GACrD,EAAK,MAAQ,EACT,EAAK,QAAQ,kBACb,EAAK,kBAAkB,IAMjB,IAJN,EAAK,SACD,SACA,EAAE,MAAM,SAAU,CAAC,eAAgB,IACnC,IAEJ,EAAK,OAAO,EAAG,EAEvB,GACJ,EAEA,SAAU,SAAU,GAChB,IAAI,EAAQ,EAAE,eAAiB,EAAE,cAAc,eACvC,EAAE,cAAc,cAAc,MAClC,EAAO,CAAC,MAAO,IACf,GAAS,EAAM,SACf,EAAE,KAAK,GAAO,SAAU,EAAO,GAC3B,IAAI,EAAO,EAAK,WAAa,EAAK,YAC9B,GACA,EAAK,MAAM,KAAK,EAExB,KAKU,IAJN,KAAK,SACD,QACA,EAAE,MAAM,QAAS,CAAC,eAAgB,IAClC,IAEJ,KAAK,OAAO,EAAG,GAG3B,EAEA,QAAS,SAAU,GACf,EAAE,aAAe,EAAE,eAAiB,EAAE,cAAc,aACpD,IAAI,EAAO,KACP,EAAe,EAAE,aACjB,EAAO,CAAC,EACR,GAAgB,EAAa,OAAS,EAAa,MAAM,SACzD,EAAE,iBACF,KAAK,iBAAiB,GAAc,QAAO,SAAU,GACjD,EAAK,MAAQ,GAKH,IAJN,EAAK,SACD,OACA,EAAE,MAAM,OAAQ,CAAC,eAAgB,IACjC,IAEJ,EAAK,OAAO,EAAG,EAEvB,IAER,EAEA,YAAa,EAAe,YAE5B,aAAc,EAAe,aAE7B,aAAc,EAAe,aAE7B,mBAAoB,WACZ,KAAK,aAAa,KAAK,WACvB,KAAK,IAAI,KAAK,QAAQ,SAAU,CAC5B,SAAU,KAAK,YACf,KAAM,KAAK,QAEX,UAAW,KAAK,aAEhB,UAAW,KAAK,eAEpB,KAAK,IAAI,KAAK,QAAQ,UAAW,CAC7B,MAAO,KAAK,YAGhB,EAAE,QAAQ,WACV,KAAK,IAAI,KAAK,QAAQ,UAAW,CAC7B,OAAQ,KAAK,WAGzB,EAEA,sBAAuB,WACnB,KAAK,KAAK,KAAK,QAAQ,SAAU,qCACjC,KAAK,KAAK,KAAK,QAAQ,UAAW,SAClC,KAAK,KAAK,KAAK,QAAQ,UAAW,SACtC,EAEA,SAAU,WACN,KAAK,uBACT,EAEA,WAAY,SAAU,EAAK,GACvB,IAAI,GAAmD,IAA1C,EAAE,QAAQ,EAAK,KAAK,iBAC7B,GACA,KAAK,wBAET,KAAK,OAAO,EAAK,GACb,IACA,KAAK,sBACL,KAAK,qBAEb,EAEA,oBAAqB,WACjB,IAAI,EAAU,KAAK,aACO,IAAtB,EAAQ,UACR,EAAQ,UAAY,KAAK,QAAQ,GAAG,sBAC5B,KAAK,QAAU,KAAK,QAAQ,KAAK,sBAChC,EAAQ,qBAAqB,IACtC,EAAQ,UAAY,EAAE,EAAQ,YAE5B,EAAQ,oBAAoB,IAC9B,EAAQ,SAAW,EAAE,EAAQ,WAE3B,EAAQ,qBAAqB,IAC/B,EAAQ,UAAY,EAAE,EAAQ,WAEtC,EAEA,WAAY,SAAU,GAClB,IAAI,EAAQ,EAAI,MAAM,KAClB,EAAY,EAAM,MAEtB,OADA,EAAM,QACC,IAAI,OAAO,EAAM,KAAK,KAAM,EACvC,EAEA,gBAAiB,SAAU,EAAK,GAC5B,MAAe,QAAR,GAAmC,WAAlB,EAAE,KAAK,IAC3B,qBAAqB,KAAK,EAClC,EAEA,oBAAqB,WACjB,IAAI,EAAO,KACP,EAAU,KAAK,QACf,EAAO,KAAK,QAAQ,OAExB,EAAE,KACE,KAAK,QAAQ,GAAG,YAChB,SAAU,EAAO,GACb,IACI,EADA,EAAM,EAAK,KAAK,cAEhB,SAAS,KAAK,KAEd,EAAM,EAAI,MAAM,GAAG,QAAQ,WAAW,SAAU,GAC5C,OAAO,EAAI,OAAO,GAAG,aACzB,IACA,EAAQ,EAAK,GACT,EAAK,gBAAgB,EAAK,KAC1B,EAAQ,EAAK,WAAW,IAE5B,EAAQ,GAAO,EAEvB,GAER,EAEA,QAAS,WACL,KAAK,sBACL,KAAK,sBACL,KAAK,OAAS,GACd,KAAK,UAAY,KAAK,gBAAe,GACrC,KAAK,SAAW,KAAK,QAAU,EAC/B,KAAK,oBAAoB,MACzB,KAAK,oBACT,EAIA,OAAQ,WACJ,OAAO,KAAK,OAChB,EAMA,SAAU,WACN,OAAO,KAAK,SAChB,EAMA,IAAK,SAAU,GACX,IAAI,EAAO,KACN,IAAQ,KAAK,QAAQ,WAGtB,EAAK,YAAc,EAAK,MACxB,KAAK,mBAAmB,EAAK,WAAW,QAAO,SAAU,GACrD,EAAK,MAAQ,EACb,EAAK,OAAO,KAAM,EACtB,KAEA,EAAK,MAAQ,EAAE,UAAU,EAAK,OAC9B,KAAK,OAAO,KAAM,IAE1B,EAOA,KAAM,SAAU,GACZ,GAAI,IAAS,KAAK,QAAQ,SAAU,CAChC,GAAI,EAAK,YAAc,EAAK,MAAO,CAC/B,IAGI,EACA,EAJA,EAAO,KACP,EAAM,EAAE,WACR,EAAU,EAAI,UAgClB,OA7BA,EAAQ,MAAQ,WAEZ,OADA,GAAU,EACN,EACO,EAAM,SAEjB,EAAI,OAAO,KAAM,QAAS,SACnB,EACX,EACA,KAAK,mBAAmB,EAAK,WAAW,QACpC,SAAU,GACF,IAGC,EAAM,QAIX,EAAK,MAAQ,GACb,EAAQ,EAAK,QAAQ,KAAM,IACrB,MACF,SAAU,EAAQ,EAAY,GAC1B,EAAI,QAAQ,EAAQ,EAAY,EACpC,IACA,SAAU,EAAO,EAAY,GACzB,EAAI,OAAO,EAAO,EAAY,EAClC,KAXA,EAAI,SAaZ,IAEG,KAAK,gBAAgB,EAChC,CAEA,GADA,EAAK,MAAQ,EAAE,UAAU,EAAK,OAC1B,EAAK,MAAM,OACX,OAAO,KAAK,QAAQ,KAAM,EAElC,CACA,OAAO,KAAK,gBAAe,EAAO,GAAQ,EAAK,QACnD,GAIR","file":"/npm/blueimp-file-upload@9.34.0/js/jquery.fileupload.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/blueimp-file-upload@9.34.0/js/jquery.fileupload.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/*\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            // By default, duplicate file names are expected to be handled on\n            // the server-side. If this is not possible (e.g. when uploading\n            // files directly to Amazon S3), the following option can be set to\n            // an empty object or an object mapping existing filenames, e.g.:\n            // { \"image.jpg\": true, \"image (1).jpg\": true }\n            // If it is set, all files will be uploaded with unique filenames,\n            // adding increasing number suffixes if necessary, e.g.:\n            // \"image (2).jpg\"\n            uniqueFilenames: undefined,\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        _getUniqueFilename: function (name, map) {\n            name = String(name);\n            if (map[name]) {\n                name = name.replace(\n                    /(?: \\(([\\d]+)\\))?(\\.[^.]+)?$/,\n                    function (_, p1, p2) {\n                        var index = p1 ? Number(p1) + 1 : 1;\n                        var ext = p2 || '';\n                        return ' (' + index + ')' + ext;\n                    }\n                );\n                return this._getUniqueFilename(name, map);\n            }\n            map[name] = true;\n            return name;\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                                var fileName = file.uploadName || file.name;\n                                if (options.uniqueFilenames) {\n                                    fileName = that._getUniqueFilename(\n                                        fileName,\n                                        options.uniqueFilenames\n                                    );\n                                }\n                                formData.append(\n                                    ($.type(options.paramName) === 'array' &&\n                                        options.paramName[index]) || paramName,\n                                    file,\n                                    fileName\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"]}