Commit 9b27fc14 by 陈雨佳

Initial commit

parents
# rails-assets-moxiecode--plupload
> The Bower package inside a gem
This gem was automatically generated. You can visit [rails-assets.org](https://rails-assets.org) for more information.
## Usage
Add rails-assets source block to your `Gemfile`:
```ruby
source "https://rails-assets.org" do
gem "rails-assets-moxiecode--plupload"
end
```
Then, import the asset using Sprockets’ `require` directive:
```js
//= require "plupload"
```
require "bundler/gem_tasks"
//= require plupload/plupload.dev.js
// Arabic (ar)
plupload.addI18n({"Stop Upload":"أيقاف التحميل","Upload URL might be wrong or doesn't exist.":"عنوان التحميل ربما يكون خاطئ أو غير متوفر","tb":"تيرابايت","Size":"الحجم","Close":"أغلاق","Init error.":"خطأ في تهيئة","Add files to the upload queue and click the start button.":"أضف ملفات إلى القائمة إنتظار التحميل ثم أضغط على زر البداية","Filename":"أسم الملف","Image format either wrong or not supported.":"صيغة الصورة أما خطاء أو غير مدعومه","Status":"الحالة","HTTP Error.":"خطأ في برتوكول نقل الملفات","Start Upload":"أبدا التحميل","mb":"ميجابايت","kb":"كيلوبايت","Duplicate file error.":"خطاء في تكرار الملف","File size error.":"خطأ في حجم الملف","N/A":"لا شي","gb":"جيجابايت","Error: Invalid file extension:":"خطاء : أمتداد الملف غير صالح :","Select files":"أختر الملفات","%s already present in the queue.":"%s الملف موجود بالفعل في قائمة الانتظار","File: %s":"ملف: %s","b":"بايت","Uploaded %d/%d files":"تحميل %d/%d ملف","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"العناصر المقبوله لتحميل هي %d ملف في هذا الوقت. الملفات الاضافية أزيلة.","%d files queued":"%d الملفات في قائمة الانتظار","File: %s, size: %d, max file size: %d":"ملف: %s, أقصى حجم للملف: %d, حجم: %d","Drag files here.":"سحب الملف هنا","Runtime ran out of available memory.":"الذاكرة المتوفره أنتهت لمدة التشغيل","File count error.":"خطاء في عد الملفات","File extension error.":"خطأ في أمتداد الملف","Error: File too large:":" خطاء : حجم الملف كبير :","Add Files":"أضف ملفات"});
\ No newline at end of file
// Azerbaijani (az)
plupload.addI18n({"Stop Upload":"Yükləməni saxla","Upload URL might be wrong or doesn't exist.":"Yükləmə ünvanı səhvdir və ya mövcud deyil","tb":"tb","Size":"Həcm","Close":"Bağla","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Faylları əlavə edin və yüklə düyməsinə klikləyin.","Filename":"Faylın adı","Image format either wrong or not supported.":"Şəklin formatı uyğun deyil və ya dəstəklənmir.","Status":"Status","HTTP Error.":"HTTP xətası.","Start Upload":"Yüklə","mb":"mb","kb":"kb","Duplicate file error.":"Bu fayl artıq növbədə var.","File size error.":"Fayl həcmi xətası.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Xəta: Yanlış fayl uzantısı:","Select files":"Faylları seçin","%s already present in the queue.":"%s artıq növbədə var.","File: %s":"Fayl: %s","b":"b","Uploaded %d/%d files":"%d/%d fayl yüklənib","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"Növbədə %d fayl var","File: %s, size: %d, max file size: %d":"Fayl: %s, həcm: %d, max fayl həcmi: %d","Drag files here.":"Faylları bura çəkin.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Fayl sayı çox böyükdür.","File extension error.":"Fayl uzantısı xətası.","Error: File too large:":"Xəta:Fayl həcmi çox böyükdür.","Add Files":"Fayl əlavə et"});
\ No newline at end of file
// Belarusian (Belarus) (be_BY)
plupload.addI18n({"Stop Upload":"","Upload URL might be wrong or doesn't exist.":"","tb":"","Size":"","Close":"","Init error.":"","Add files to the upload queue and click the start button.":"","Filename":"","Image format either wrong or not supported.":"","Status":"","HTTP Error.":"","Start Upload":"","mb":"","kb":"","Duplicate file error.":"","File size error.":"","N/A":"","gb":"","Error: Invalid file extension:":"","Select files":"","%s already present in the queue.":"","File: %s":"","b":"","Uploaded %d/%d files":"","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"","%d files queued":"","File: %s, size: %d, max file size: %d":"","Drag files here.":"","Runtime ran out of available memory.":"","File count error.":"","File extension error.":"","Error: File too large:":"","Add Files":""});
\ No newline at end of file
// Bulgarian (bg)
plupload.addI18n({"Stop Upload":"Спрете качването","Upload URL might be wrong or doesn't exist.":"URL за качване може да е грешен или да не съществува.","tb":"tb","Size":"Размер","Close":"Затвори","Init error.":"Грешка: инициализиране.","Add files to the upload queue and click the start button.":"Добавете файлове в опашката за качване, и щракнете бутона старт.","Filename":"Име на файла","Image format either wrong or not supported.":"Формата на изображението или е объркан, или не се поддържа.","Status":"Статус","HTTP Error.":"Грешка: HTTP .","Start Upload":"Започнете качването","mb":"mb","kb":"kb","Duplicate file error.":"Грешка: файла е вече качен на сървъра.","File size error.":"Грешка: размер на файла.","N/A":"не приложимо","gb":"gb","Error: Invalid file extension:":"Грешка: Невалидно разширение на файл:","Select files":"Изберете файлове","%s already present in the queue.":"%s вече го има в опашката.","File: %s":"Файл: %s","b":"b","Uploaded %d/%d files":"Качени %d/%d файла","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Елемента за качване приема само %d файл(а) наведнъж. Допълнителните файлове бяха отстранени.","%d files queued":"%d файла в опашката","File: %s, size: %d, max file size: %d":"Файл: %s, размер: %d, максимален размер: %d","Drag files here.":"Довлечете файловете тук.","Runtime ran out of available memory.":"Недостатъчна свободна памет.","File count error.":"Грешка в броя на файловете.","File extension error.":"Грешка: разширение на файла.","Error: File too large:":"Грешка: Файла е твърде голям:","Add Files":"Добавете файлове"});
\ No newline at end of file
// Bosnian (bs)
plupload.addI18n({"Stop Upload":"Prekini dodavanje","Upload URL might be wrong or doesn't exist.":"URL za dodavanje je neispravan ili ne postoji.","tb":"tb","Size":"Veličina","Close":"Zatvori","Init error.":"Inicijalizacijska greška.","Add files to the upload queue and click the start button.":"Dodajte datoteke u red i kliknite na dugme za pokretanje.","Filename":"Naziv datoteke","Image format either wrong or not supported.":"Format slike je neispravan ili nije podržan.","Status":"Status","HTTP Error.":"HTTP greška.","Start Upload":"Započni dodavanje","mb":"mb","kb":"kb","Duplicate file error.":"Dupla datoteka.","File size error.":"Greška u veličini datoteke.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Greška! Neispravan ekstenzija datoteke:","Select files":"Odaberite datoteke","%s already present in the queue.":"%s se već nalazi u redu.","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Dodano %d/%d datoteka","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Dodavanje trenutno dozvoljava samo %d datoteka istovremeno. Dodatne datoteke su uklonjene.","%d files queued":"%d datoteka čeka","File: %s, size: %d, max file size: %d":"Datoteka: %s, veličina: %d, maksimalna veličina: %d","Drag files here.":"Dovucite datoteke ovdje.","Runtime ran out of available memory.":"Nema više dostupne memorije.","File count error.":"Greška u brojanju datoeka.","File extension error.":"Greška u ekstenziji datoteke.","Error: File too large:":"Greška! Datoteka je prevelika:","Add Files":"Dodaj datoteke"});
\ No newline at end of file
// Catalan (ca)
plupload.addI18n({"Stop Upload":"Parar pujada","Upload URL might be wrong or doesn't exist.":"La URL de càrrega no és correcte o bé no existeix.","tb":"Tb","Size":"Tamany","Close":"Tancar","Init error.":"Error d´inicialització.","Add files to the upload queue and click the start button.":"Afegeixi els fitxers a la cua de pujada i cliqui el botó Iniciar","Filename":"Nom de fitxer","Image format either wrong or not supported.":"Format d'imatge incorrecte o no suportat.","Status":"Estat","HTTP Error.":"Error HTTP.","Start Upload":"Començar pujada","mb":"Mb","kb":"Kb","Duplicate file error.":"Error per duplicitat de fitxer.","File size error.":"Error en la mida del fitxer.","N/A":"N/D","gb":"Gb","Error: Invalid file extension:":"Error: Extensió de fitxer no vàlida:","Select files":"Seleccionar fitxers","%s already present in the queue.":"%s ja existeix a la cua.","File: %s":"Fitxer: %s","b":"b","Uploaded %d/%d files":"Pujats %d/%d fitxers","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"La càrrega d'elements tan sols accepta %d fitxer(s) alhora. Els fitxers sobrants seran descartats.","%d files queued":"%d fitxers en cua","File: %s, size: %d, max file size: %d":"Fitxer: %s, mida: %d, mida màxima de fitxer: %d","Drag files here.":"Arrossegui fitxers aquí","Runtime ran out of available memory.":"L'execució ha arribat al límit de memòria.","File count error.":"Error en el recompte de fitxers","File extension error.":"Error en l´extensió del fitxer.","Error: File too large:":"Error: Fitxer massa gran:","Add Files":"Afegir fitxers"});
\ No newline at end of file
// Czech (cs)
plupload.addI18n({"Stop Upload":"Zastavit nahrávání","Upload URL might be wrong or doesn't exist.":"URL uploadu je možná špatně, nebo neexistuje.","tb":"tb","Size":"Velikost","Close":"Zavřít","Init error.":"Chyba inicializace.","Add files to the upload queue and click the start button.":"Přidejte soubory do fronty a pak spusťte nahrávání.","Filename":"Název souboru","Image format either wrong or not supported.":"Špatný, nebo nepodporovaný formát obrázku.","Status":"Stav","HTTP Error.":"Chyba HTTP.","Start Upload":"Spustit nahrávání","mb":"mb","kb":"kb","Duplicate file error.":"Chyba - duplikovaný soubor.","File size error.":"Chyba velikosti souboru.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Chyba: Neplatná koncovka souboru:","Select files":"Vyberte soubory","%s already present in the queue.":"%s je již zařazen ve frontě.","File: %s":"Soubor: %s","b":"b","Uploaded %d/%d files":"Nahráno %d/%d souborů","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload akceptuje pouze %d soubor(ů) najednou. Další soubory byly odstraněny.","%d files queued":"%d souborů ve frontě","File: %s, size: %d, max file size: %d":"Soubor: %s, velikost: %d, maximální velikost souboru: %d","Drag files here.":"Sem přetáhněte soubory.","Runtime ran out of available memory.":"Běh skriptu přesáhl dostupnou paměť.","File count error.":"Chyba v počtu souborů.","File extension error.":"Chyba přípony souboru.","Error: File too large:":"Chyba: Soubor je příliš veliký:","Add Files":"Přidat soubory"});
\ No newline at end of file
// Welsh (cy)
plupload.addI18n({"Stop Upload":"Atal Lanlwytho","Upload URL might be wrong or doesn't exist.":"URL y lanlwythiad ynb anghywir neu ddim yn bodoli.","tb":"tb","Size":"Maint","Close":"Cau","Init error.":"Gwall cych.","Add files to the upload queue and click the start button.":"Ychwanegwch ffeiliau i'r ciw lanlwytho a chlicio'r botwm dechrau.","Filename":"Enw'r ffeil","Image format either wrong or not supported.":"Fformat delwedd yn anghywir neu heb ei gynnal.","Status":"Statws","HTTP Error.":"Gwall HTTP.","Start Upload":"Dechrau Lanlwytho","mb":"mb","kb":"kb","Duplicate file error.":"Gwall ffeil ddyblyg.","File size error.":"Gwall maint ffeil.","N/A":"Dd/A","gb":"gb","Error: Invalid file extension:":"Gwall: estyniad ffeil annilys:","Select files":"Dewis ffeiliau","%s already present in the queue.":"%s yn y ciw yn barod.","File: %s":"Ffeil: %s","b":"b","Uploaded %d/%d files":"Lanlwythwyd %d/%d ffeil","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Mae'r elfen lanlwytho yn derbyn %d ffeil ar y tro. Caiff ffeiliau ychwanegol eu tynnu.","%d files queued":"%d ffeil mewn ciw","File: %s, size: %d, max file size: %d":"Ffeil: %s, maint: %d, maint mwyaf ffeil: %d","Drag files here.":"Llusgwch ffeiliau yma.","Runtime ran out of available memory.":"Allan o gof.","File count error.":"Gwall cyfri ffeiliau.","File extension error.":"Gwall estyniad ffeil.","Error: File too large:":"Gwall: Ffeil yn rhy fawr:","Add Files":"Ychwanegu Ffeiliau"});
\ No newline at end of file
// Danish (da)
plupload.addI18n({"Stop Upload":"Stop upload","Upload URL might be wrong or doesn't exist.":"Upload URL kan være forkert eller ikke eksisterende.","tb":"tb","Size":"Størrelse","Close":"Luk","Init error.":"Opstarts fejl.","Add files to the upload queue and click the start button.":"Tilføj filer til køen og klik Start upload knappen.","Filename":"Filnavn","Image format either wrong or not supported.":"Billede format er enten forkert eller ikke understøttet.","Status":"Status","HTTP Error.":"HTTP fejl.","Start Upload":"Start upload","mb":"mb","kb":"kb","Duplicate file error.":"Filen findes allerede.","File size error.":"Filstørrelse fejl.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Fejl: Ugyldigt fil format:","Select files":"Vælg filer","%s already present in the queue.":"%s findes allerede i køen.","File: %s":"Fil: %s","b":"b","Uploaded %d/%d files":"Uploaded %d/%d filer","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload accepterer kun %d fil(er) af gangen. Ekstra filer blev skippet.","%d files queued":"%d filer i kø","File: %s, size: %d, max file size: %d":"Fil: %s, størrelse: %d, maks. filstørrelse: %d","Drag files here.":"Træk filer her.","Runtime ran out of available memory.":"Runtime mangler tilgængelige hukommelse.","File count error.":"Fil antal fejl.","File extension error.":"Fil format fejl.","Error: File too large:":"Fejl: Filen er for stor:","Add Files":"Tilføj filer"});
\ No newline at end of file
// German (de)
plupload.addI18n({"Stop Upload":"Hochladen stoppen","Upload URL might be wrong or doesn't exist.":"Upload-URL ist falsch oder existiert nicht.","tb":"TB","Size":"Größe","Close":"Schließen","Init error.":"Initialisierungsfehler","Add files to the upload queue and click the start button.":"Dateien hinzufügen und auf 'Hochladen' klicken.","Filename":"Dateiname","Image format either wrong or not supported.":"Bildformat falsch oder nicht unterstützt.","Status":"Status","HTTP Error.":"HTTP-Fehler","Start Upload":"Hochladen beginnen","mb":"MB","kb":"KB","Duplicate file error.":"Datei bereits hochgeladen","File size error.":"Fehler bei Dateigröße","N/A":"Nicht verfügbar","gb":"GB","Error: Invalid file extension:":"Fehler: Ungültige Dateiendung:","Select files":"Dateien auswählen","%s already present in the queue.":"%s ist bereits in der Warteschlange","File: %s":"Datei: %s","b":"B","Uploaded %d/%d files":"%d/%d Dateien wurden hochgeladen","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Pro Durchgang können nur %d Datei(en) akzeptiert werden. Überzählige Dateien wurden ignoriert.","%d files queued":"%d Dateien in der Warteschlange","File: %s, size: %d, max file size: %d":"Datei: %s, Größe: %d, maximale Dateigröße: %d","Drag files here.":"Dateien hier hin ziehen.","Runtime ran out of available memory.":"Nicht genügend Speicher verfügbar.","File count error.":"Fehlerhafte Dateianzahl.","File extension error.":"Fehler bei Dateiendung","Error: File too large:":"Fehler: Datei zu groß:","Add Files":"Dateien hinzufügen"});
\ No newline at end of file
// Greek (el)
plupload.addI18n({"Stop Upload":"Ακύρωση Μεταφόρτωσης","Upload URL might be wrong or doesn't exist.":"Το URL μεταφόρτωσης είναι λάθος ή δεν υπάρχει.","tb":"tb","Size":"Μέγεθος","Close":"Κλείσιμο","Init error.":"Σφάλμα αρχικοποίησης.","Add files to the upload queue and click the start button.":"Προσθέστε αρχεία στην ουρά μεταφόρτωσης και πατήστε το κουμπί εκκίνησης.","Filename":"Όνομα Αρχείου","Image format either wrong or not supported.":"Ο τύπος εικόνας είναι λάθος ή δεν υποστηρίζεται.","Status":"Κατάσταση","HTTP Error.":"Σφάλμα HTTP.","Start Upload":"Εκκίνηση Μεταφόρτωσης","mb":"mb","kb":"kb","Duplicate file error.":"Το αρχείο έχει ξαναπροστεθεί.","File size error.":"Σφάλμα με το μέγεθος του αρχείου.","N/A":"Δεν ισχύει","gb":"gb","Error: Invalid file extension:":"Σφάλμα: Μη έγκυρος τύπος αρχείου:","Select files":"Επιλέξτε Αρχεία","%s already present in the queue.":"Το «%s» βρίσκεται ήδη στην ουρά.","File: %s":"Αρχείο: %s","b":"b","Uploaded %d/%d files":"Μεταφορτώθηκαν %d/%d αρχεία","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Μπορείτε να μεταφορτώσετε μεχρι και %d αρχείο/α κάθε φορά. Τα επιπλέον αρχεία αφαιρέθηκαν.","%d files queued":"%d αρχεία στην ουρά","File: %s, size: %d, max file size: %d":"Αρχείο: %s, μέγεθος: %d, μέγιστο μέγεθος αρχείου: %d","Drag files here.":"Σύρετε αρχεία εδώ","Runtime ran out of available memory.":"Δεν υπάρχει αρκετή διαθέσιμη μνήμη.","File count error.":"Σφάλμα με τον αριθμό αρχείων.","File extension error.":"Σφάλμα με τον τύπο αρχείου.","Error: File too large:":"Σφάλμα: Πολύ μεγάλο αρχείο:","Add Files":"Προσθέστε Αρχεία"});
\ No newline at end of file
// English (en)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Size","Close":"Close","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Add files to the upload queue and click the start button.","Filename":"Filename","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Start Upload","mb":"mb","kb":"kb","Duplicate file error.":"Duplicate file error.","File size error.":"File size error.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Select files","%s already present in the queue.":"%s already present in the queue.","File: %s":"File: %s","b":"b","Uploaded %d/%d files":"Uploaded %d/%d files","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d files queued","File: %s, size: %d, max file size: %d":"File: %s, size: %d, max file size: %d","Drag files here.":"Drag files here.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"File count error.","File extension error.":"File extension error.","Error: File too large:":"Error: File too large:","Add Files":"Add Files"});
\ No newline at end of file
// Spanish (es)
plupload.addI18n({"Stop Upload":"Detener Subida.","Upload URL might be wrong or doesn't exist.":"URL de carga inexistente.","tb":"TB","Size":"Tamaño","Close":"Cerrar","Init error.":"Error de inicialización.","Add files to the upload queue and click the start button.":"Agregue archivos a la lista de subida y pulse clic en el botón de Iniciar carga","Filename":"Nombre de archivo","Image format either wrong or not supported.":"Formato de imagen no soportada.","Status":"Estado","HTTP Error.":"Error de HTTP.","Start Upload":"Iniciar carga","mb":"MB","kb":"KB","Duplicate file error.":"Error, archivo duplicado","File size error.":"Error de tamaño de archivo.","N/A":"No disponible","gb":"GB","Error: Invalid file extension:":"Error: Extensión de archivo inválida:","Select files":"Elija archivos","%s already present in the queue.":"%s ya se encuentra en la lista.","File: %s":"Archivo: %s","b":"B","Uploaded %d/%d files":"Subidos %d/%d archivos","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Se aceptan sólo %d archivo(s) al tiempo. Más, no se tienen en cuenta.","%d files queued":"%d archivos en cola.","File: %s, size: %d, max file size: %d":"Archivo: %s, tamaño: %d, tamaño máximo de archivo: %d","Drag files here.":"Arrastre archivos aquí","Runtime ran out of available memory.":"No hay memoria disponible.","File count error.":"Error en contador de archivos.","File extension error.":"Error de extensión de archivo.","Error: File too large:":"Error: archivo demasiado grande:","Add Files":"Agregar archivos"});
\ No newline at end of file
// Estonian (et)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Üleslaadimise URL võib olla vale või seda pole.","tb":"","Size":"Suurus","Close":"Sulge","Init error.":"Lähtestamise viga.","Add files to the upload queue and click the start button.":"Lisa failid üleslaadimise järjekorda ja klõpsa alustamise nupule.","Filename":"Failinimi","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Olek","HTTP Error.":"HTTP ühenduse viga.","Start Upload":"Start Upload","mb":"","kb":"","Duplicate file error.":"","File size error.":"Failisuuruse viga.","N/A":"N/A","gb":"","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Vali faile","%s already present in the queue.":"","File: %s":"Fail: %s","b":"","Uploaded %d/%d files":"Üles laaditud %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Üleslaadimise element saab vastu võtta ainult %d faili ühe korraga. Ülejäänud failid jäetakse laadimata.","%d files queued":"Järjekorras on %d faili","File: %s, size: %d, max file size: %d":"","Drag files here.":"Lohista failid siia.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Failide arvu viga.","File extension error.":"Faililaiendi viga.","Error: File too large:":"Error: File too large:","Add Files":"Add Files"});
\ No newline at end of file
// Persian (fa)
plupload.addI18n({"Stop Upload":"توقف انتقال","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"ترابایت","Size":"سایز","Close":"بستن","Init error.":"خطا در استارت اسکریپت","Add files to the upload queue and click the start button.":"اضافه کنید فایل ها را به صف آپلود و دکمه شروع را کلیک کنید.","Filename":"نام فایل","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"وضعیت","HTTP Error.":"HTTP خطای","Start Upload":"شروع انتقال","mb":"مگابایت","kb":"کیلوبایت","Duplicate file error.":"خطای فایل تکراری","File size error.":"خطای سایز فایل","N/A":"N/A","gb":"گیگابایت","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"انتخاب فایل","%s already present in the queue.":"%s در لیست آپلود وجود دارد.","File: %s":" فایل ها : %s","b":"بایت","Uploaded %d/%d files":"منتقل شد %d/%d از فایلها","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"عنصر بارگذار فقط %d فایل رو در یک زمان می پذیرد. سایر فایل ها مجرد از این موضوع هستند.","%d files queued":"%d فایل در صف","File: %s, size: %d, max file size: %d":"فایل: %s, اندازه: %d, محدودیت اندازه فایل: %d","Drag files here.":"بکشید فایل ها رو به اینجا","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"خطای تعداد فایل","File extension error.":"خطا پیشوند فایل","Error: File too large:":"Error: File too large:","Add Files":"افزودن فایل"});
\ No newline at end of file
// Finnish (fi)
plupload.addI18n({"Stop Upload":"Pysäytä lähetys","Upload URL might be wrong or doesn't exist.":"Lähetyksen URL-osoite saattaa olla väärä tai sitä ei ole olemassa.","tb":"TB","Size":"Koko","Close":"Sulje","Init error.":"Init virhe.","Add files to the upload queue and click the start button.":"Lisää tiedostoja lähetysjonoon ja klikkaa aloita-nappia.","Filename":"Tiedostonimi","Image format either wrong or not supported.":"Kuvaformaatti on joko väärä tai ei tuettu.","Status":"Tila","HTTP Error.":"HTTP-virhe.","Start Upload":"Aloita lähetys","mb":"MB","kb":"kB","Duplicate file error.":"Tuplatiedostovirhe.","File size error.":"Tiedostokokovirhe.","N/A":"N/A","gb":"GB","Error: Invalid file extension:":"Virhe: Virheellinen tiedostopääte:","Select files":"Valitse tiedostoja","%s already present in the queue.":"%s on jo jonossa.","File: %s":"Tiedosto: %s","b":"B","Uploaded %d/%d files":"Lähetetty %d/%d tiedostoa","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Vain %d tiedosto(a) voidaan lähettää kerralla. Ylimääräiset tiedostot ohitettiin.","%d files queued":"%d tiedostoa jonossa","File: %s, size: %d, max file size: %d":"Tiedosto: %s, koko: %d, suurin sallittu tiedostokoko: %d","Drag files here.":"Raahaa tiedostot tähän.","Runtime ran out of available memory.":"Toiminnon käytettävissä oleva muisti loppui kesken.","File count error.":"Tiedostolaskentavirhe.","File extension error.":"Tiedostopäätevirhe.","Error: File too large:":"Virhe: Liian suuri tiedosto:","Add Files":"Lisää tiedostoja"});
\ No newline at end of file
// French (fr)
plupload.addI18n({"Stop Upload":"Arrêter l'envoi.","Upload URL might be wrong or doesn't exist.":"L'URL d'envoi est soit erronée soit n'existe pas.","tb":"To","Size":"Taille","Close":"Fermer","Init error.":"Erreur d'initialisation.","Add files to the upload queue and click the start button.":"Ajoutez des fichiers à la file d'attente de téléchargement et appuyez sur le bouton 'Démarrer l'envoi'","Filename":"Nom du fichier","Image format either wrong or not supported.":"Le format d'image est soit erroné soit pas géré.","Status":"État","HTTP Error.":"Erreur HTTP.","Start Upload":"Démarrer l'envoi","mb":"Mo","kb":"Ko","Duplicate file error.":"Erreur: Fichier déjà sélectionné.","File size error.":"Erreur de taille de fichier.","N/A":"Non applicable","gb":"Go","Error: Invalid file extension:":"Erreur: Extension de fichier non valide:","Select files":"Sélectionnez les fichiers","%s already present in the queue.":"%s déjà présent dans la file d'attente.","File: %s":"Fichier: %s","b":"o","Uploaded %d/%d files":"%d fichiers sur %d ont été envoyés","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Que %d fichier(s) peuvent être envoyé(s) à la fois. Les fichiers supplémentaires ont été ignorés.","%d files queued":"%d fichiers en attente","File: %s, size: %d, max file size: %d":"Fichier: %s, taille: %d, taille max. d'un fichier: %d","Drag files here.":"Déposez les fichiers ici.","Runtime ran out of available memory.":"Le traitement a manqué de mémoire disponible.","File count error.":"Erreur: Nombre de fichiers.","File extension error.":"Erreur d'extension de fichier","Error: File too large:":"Erreur: Fichier trop volumineux:","Add Files":"Ajouter des fichiers"});
\ No newline at end of file
// Hebrew (he)
plupload.addI18n({"Stop Upload":"בטל העלאה","Upload URL might be wrong or doesn't exist.":"כתובת URL שגויה או לא קיימת.","tb":"tb","Size":"גודל","Close":"סגור","Init error.":"שגיאת איתחול","Add files to the upload queue and click the start button.":"הוסף קבצים לרשימה ולחץ על כפתור שליחה להתחלת פעולות העלאה","Filename":"שם קובץ","Image format either wrong or not supported.":"תמונה פגומה או סוג תמונה לא נתמך","Status":"אחוז","HTTP Error.":"שגיאת פרוטוקול","Start Upload":"שליחה","mb":"MB","kb":"KB","Duplicate file error.":"קובץ כפול","File size error.":"גודל קובץ חורג מהמותר","N/A":"שגיאה","gb":"GB","Error: Invalid file extension:":"שגיאה: סוג קובץ לא נתמך:","Select files":"בחר קבצים","%s already present in the queue.":"%sקובץ נמצא כבר ברשימת הקבצים.","File: %s":"קובץ: %s","b":"B","Uploaded %d/%d files":"מעלה: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"אלמנטי ההעלאה מקבלים רק %d קובץ(ים) בפעם אחת. קבצים נוספים הוסרו.","%d files queued":"%d קבצים נותרו","File: %s, size: %d, max file size: %d":"קובץ: %s, גודל: %d, גודל מקסימלי: %d","Drag files here.":"גרור קבצים לכאן","Runtime ran out of available memory.":"שגיאת מחסור בזיכרון","File count error.":"שגיאת מספר קבצים","File extension error.":"קובץ זה לא נתמך","Error: File too large:":"שגיאה: קובץ חורג מהגודל המותר:","Add Files":"הוסף קבצים"});
\ No newline at end of file
// Croatian (hr)
plupload.addI18n({"Stop Upload":"Zaustavi upload.","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Veličina","Close":"Zatvori","Init error.":"Greška inicijalizacije.","Add files to the upload queue and click the start button.":"Dodajte datoteke u listu i kliknite Upload.","Filename":"Ime datoteke","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP greška.","Start Upload":"Pokreni upload.","mb":"mb","kb":"kb","Duplicate file error.":"Pogreška dvostruke datoteke.","File size error.":"Greška veličine datoteke.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Pogreška: Nevažeći nastavak datoteke:","Select files":"Odaberite datoteke:","%s already present in the queue.":"%s je već prisutan u listi čekanja.","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Uploadano %d/%d datoteka","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d datoteka na čekanju.","File: %s, size: %d, max file size: %d":"Datoteka: %s, veličina: %d, maksimalna veličina: %d","Drag files here.":"Dovucite datoteke ovdje","Runtime ran out of available memory.":"Runtime aplikaciji je ponestalo memorije.","File count error.":"Pogreška u broju datoteka.","File extension error.":"Pogreška u nastavku datoteke.","Error: File too large:":"Pogreška: Datoteka je prevelika:","Add Files":"Dodaj datoteke"});
\ No newline at end of file
// Hungarian (hu)
plupload.addI18n({"Stop Upload":"Feltöltés leállítása","Upload URL might be wrong or doesn't exist.":"A feltöltő URL hibás vagy nem létezik.","tb":"TB","Size":"Méret","Close":"Bezárás","Init error.":"Init hiba.","Add files to the upload queue and click the start button.":"A fájlok feltöltési sorhoz való hozzáadása után az Indítás gombra kell kattintani.","Filename":"Fájlnév","Image format either wrong or not supported.":"Rossz vagy nem támogatott képformátum.","Status":"Állapot","HTTP Error.":"HTTP-hiba.","Start Upload":"Feltöltés indítása","mb":"MB","kb":"kB","Duplicate file error.":"Duplikáltfájl-hiba.","File size error.":"Hibás fájlméret.","N/A":"Nem elérhető","gb":"GB","Error: Invalid file extension:":"Hiba: érvénytelen fájlkiterjesztés:","Select files":"Fájlok kiválasztása","%s already present in the queue.":"%s már szerepel a listában.","File: %s":"Fájl: %s","b":"b","Uploaded %d/%d files":"Feltöltött fájlok: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"A feltöltés egyszerre csak %d fájlt fogad el, a többi fájl nem lesz feltöltve.","%d files queued":"%d fájl sorbaállítva","File: %s, size: %d, max file size: %d":"Fájl: %s, méret: %d, legnagyobb fájlméret: %d","Drag files here.":"Ide lehet húzni a fájlokat.","Runtime ran out of available memory.":"Futásidőben elfogyott a rendelkezésre álló memória.","File count error.":"A fájlok számával kapcsolatos hiba.","File extension error.":"Hibás fájlkiterjesztés.","Error: File too large:":"Hiba: a fájl túl nagy:","Add Files":"Fájlok hozzáadása"});
\ No newline at end of file
// Armenian (hy)
plupload.addI18n({"Stop Upload":"Կանգնեցնել","Upload URL might be wrong or doesn't exist.":"Ավեցաված URL-ը սխալ է կամ գոյություն չունի։","tb":"տբ","Size":"Չափ","Close":"Փակել","Init error.":"Ստեղծման սխալ","Add files to the upload queue and click the start button.":"Ավելացրեք ֆայլեր ցուցակում և սեղմեք \"Վերբեռնել\"։","Filename":"Ֆայլի անուն","Image format either wrong or not supported.":"Նկարի ֆորմատը սխալ է կամ չի ընդունվում։","Status":"Կարգավիճակ","HTTP Error.":"HTTP սխալ","Start Upload":"Վերբեռնել","mb":"մբ","kb":"կբ","Duplicate file error.":"Ֆայլի կրկնման սխալ","File size error.":"Ֆայլի չափի սխալ","N/A":"N/A","gb":"գբ","Error: Invalid file extension:":"Սխալ։ Ֆայլի ընդլայնումը սխալ է։","Select files":"Ընտրեք ֆայլերը","%s already present in the queue.":"%s ֆայլը արդեն ավելացված է ցուցակում.","File: %s":"Ֆայլ: %s","b":"բ","Uploaded %d/%d files":"Վերբեռնվել են %d/%d ֆայլերը","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Վերբեռնիչը միանգամից ըդունում է միայն %d ֆայլ(եր). Ավելորդ ֆայլերը հեռացվել են.","%d files queued":"ցուցակում կա %d ֆայլ","File: %s, size: %d, max file size: %d":"Ֆայլ: %s, չափ: %d, ֆայլի մաքսիմում չափ: %d","Drag files here.":"Տեղափոխեք ֆայլերը այստեղ","Runtime ran out of available memory.":"Օպերատիվ հիշողության անբավարարուտյուն.","File count error.":"Ֆայլերի քանակի սխալ","File extension error.":"Ֆայլի ընդլայնման սխալ","Error: File too large:":"Սխալ։ Ֆայլի չափը մեծ է։","Add Files":"Ավելացնել ֆայլեր"});
\ No newline at end of file
// Indonesian (id)
plupload.addI18n({"Stop Upload":"Hentikan Upload","Upload URL might be wrong or doesn't exist.":"Alamat URL untuk upload tidak benar atau tidak ada","tb":"tb","Size":"Ukuran","Close":"Tutup","Init error.":"Kesalahan pada Init","Add files to the upload queue and click the start button.":"Tambahkan file kedalam antrian upload dan klik tombol Mulai","Filename":"Nama File","Image format either wrong or not supported.":"Kesalahan pada jenis gambar atau jenis file tidak didukung","Status":"Status","HTTP Error.":"HTTP Bermasalah","Start Upload":"Mulai Upload","mb":"mb","kb":"kb","Duplicate file error.":"Terjadi duplikasi file","File size error.":"Kesalahan pada ukuran file","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Kesalahan: Ekstensi file tidak dikenal","Select files":"Pilih file","%s already present in the queue.":"%s sudah ada dalam daftar antrian","File: %s":"File: %s","b":"b","Uploaded %d/%d files":"File terupload %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Tempat untuk upload hanya menerima %d file(s) dalam setiap upload. File lainnya tidak akan disertakan","%d files queued":"%d file dalam antrian","File: %s, size: %d, max file size: %d":"File: %s, ukuran: %d, maksimum ukuran file: %d","Drag files here.":"Tarik file kesini","Runtime ran out of available memory.":"Tidak cukup memori","File count error.":"Kesalahan pada jumlah file","File extension error.":"Kesalahan pada ekstensi file","Error: File too large:":"Kesalahan: File terlalu besar","Add Files":"Tambah File"});
\ No newline at end of file
// Italian (it)
plupload.addI18n({"Stop Upload":"Ferma Upload","Upload URL might be wrong or doesn't exist.":"URL di Upload errata o non esistente","tb":"tb","Size":"Dimensione","Close":"Chiudi","Init error.":"Errore inizializzazione.","Add files to the upload queue and click the start button.":"Aggiungi i file alla coda di caricamento e clicca il pulsante di avvio.","Filename":"Nome file","Image format either wrong or not supported.":"Formato immagine errato o non supportato.","Status":"Stato","HTTP Error.":"Errore HTTP.","Start Upload":"Inizia Upload","mb":"mb","kb":"kb","Duplicate file error.":"Errore file duplicato.","File size error.":"Errore dimensione file.","N/A":"N/D","gb":"gb","Error: Invalid file extension:":"Errore: Estensione file non valida:","Select files":"Seleziona i files","%s already present in the queue.":"%s già presente nella coda.","File: %s":"File: %s","b":"byte","Uploaded %d/%d files":"Caricati %d/%d file","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d file in coda","File: %s, size: %d, max file size: %d":"File: %s, dimensione: %d, dimensione max file: %d","Drag files here.":"Trascina i files qui.","Runtime ran out of available memory.":"Runtime ha esaurito la memoria disponibile.","File count error.":"File count error.","File extension error.":"Errore estensione file.","Error: File too large:":"Errore: File troppo grande:","Add Files":"Aggiungi file"});
\ No newline at end of file
// Japanese (ja)
plupload.addI18n({"Stop Upload":"アップロード停止","Upload URL might be wrong or doesn't exist.":"アップロード先の URL が存在しません","tb":"TB","Size":"サイズ","Close":"閉じる","Init error.":"イニシャライズエラー","Add files to the upload queue and click the start button.":"ファイルをアップロードキューに追加してスタートボタンをクリックしてください","Filename":"ファイル名","Image format either wrong or not supported.":"画像形式が間違っているかサポートされていません","Status":"ステータス","HTTP Error.":"HTTP エラー","Start Upload":"アップロード開始","mb":"MB","kb":"KB","Duplicate file error.":"重複ファイルエラー","File size error.":"ファイルサイズエラー","N/A":"N/A","gb":"GB","Error: Invalid file extension:":"エラー: ファイルの拡張子が無効です:","Select files":"ファイル選択","%s already present in the queue.":"%s 既にキューに存在しています","File: %s":"ファイル: %s","b":"B","Uploaded %d/%d files":"アップロード中 %d/%d ファイル","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"アップロード可能なファイル数は %d です 余分なファイルは削除されました","%d files queued":"%d ファイルが追加されました","File: %s, size: %d, max file size: %d":"ファイル: %s, サイズ: %d, 最大ファイルサイズ: %d","Drag files here.":"ここにファイルをドラッグ","Runtime ran out of available memory.":"ランタイムが使用するメモリが不足しました","File count error.":"ファイル数エラー","File extension error.":"ファイル拡張子エラー","Error: File too large:":"エラー: ファイルが大きすぎます:","Add Files":"ファイルを追加"});
\ No newline at end of file
// Georgian (ka)
plupload.addI18n({"Stop Upload":"ატვირთვის შეჩერება","Upload URL might be wrong or doesn't exist.":"ატვირთვის მისამართი არასწორია ან არ არსებობს.","tb":"ტბ","Size":"ზომა","Close":"დავხუროთ","Init error.":"ინიციალიზაციის შეცდომა.","Add files to the upload queue and click the start button.":"დაამატეთ ფაილები და დააჭირეთ ღილაკს - ატვირთვა.","Filename":"ფაილის სახელი","Image format either wrong or not supported.":"ფაილის ფორმატი არ არის მხარდაჭერილი ან არასწორია.","Status":"სტატუსი","HTTP Error.":"HTTP შეცდომა.","Start Upload":"ატვირთვა","mb":"მბ","kb":"კბ","Duplicate file error.":"ესეთი ფაილი უკვე დამატებულია.","File size error.":"ფაილის ზომა დაშვებულზე დიდია.","N/A":"N/A","gb":"გბ","Error: Invalid file extension:":"შეცდომა: ფაილს აქვს არასწორი გაფართოება.","Select files":"ფაილების მონიშვნა","%s already present in the queue.":"%s უკვე დამატებულია.","File: %s":"ფაილი: %s","b":"ბ","Uploaded %d/%d files":"ატვირთულია %d/%d ფაილი","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"ერთდროულად დაშვებულია მხოლოდ %d ფაილის დამატება.","%d files queued":"რიგშია %d ფაილი","File: %s, size: %d, max file size: %d":"ფაილი: %s, ზომა: %d, მაქსიმალური დაშვებული ზომა: %d","Drag files here.":"ჩააგდეთ ფაილები აქ.","Runtime ran out of available memory.":"ხელმისაწვდომი მეხსიერება გადაივსო.","File count error.":"აღმოჩენილია ზედმეტი ფაილები.","File extension error.":"ფაილის ფორმატი დაშვებული არ არის.","Error: File too large:":"შეცდომა: ფაილი ზედმეტად დიდია.","Add Files":"დაამატეთ ფაილები"});
\ No newline at end of file
// Kazakh (kk)
plupload.addI18n({"Stop Upload":"Жүктеуді тоқтату","Upload URL might be wrong or doesn't exist.":"Жүктеуді қабылдаушы URL қате не мүлдем көрсетілмеген.","tb":"тб","Size":"Өлшемі","Close":"Жабу","Init error.":"Инициализация қатесі.","Add files to the upload queue and click the start button.":"Жүктеу кезегіне файлдар қосып, Бастау кнопкасын басыңыз.","Filename":"Файл аты","Image format either wrong or not supported.":"Сурет форматы қате немесе оның қолдауы жоқ.","Status":"Күйі","HTTP Error.":"HTTP қатесі.","Start Upload":"Жүктеуді бастау","mb":"мб","kb":"кб","Duplicate file error.":"Файл қайталамасының қатесі.","File size error.":"Файл өлшемінің қатесі.","N/A":"Қ/Ж","gb":"гб","Error: Invalid file extension:":"Қате: Файл кеңейтілуі қате:","Select files":"Файлдар таңдаңыз","%s already present in the queue.":"%s файлы кезекте бұрыннан бар.","File: %s":"Файл: %s","b":"б","Uploaded %d/%d files":"Жүктелген: %d/%d файл","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Жүктеу элементі бір кезде %d файл ғана жүктей алады. Артық файлдар жүктелмейді.","%d files queued":"%d файл кезекке қойылды","File: %s, size: %d, max file size: %d":"Файл: %s, өлшемі: %d, макс. файл өлшемі: %d","Drag files here.":"Файлдарды мына жерге тастаңыз.","Runtime ran out of available memory.":"Орындау кезінде жады жетпей қалды.","File count error.":"Файл санының қатесі.","File extension error.":"Файл кеңейтілуінің қатесі.","Error: File too large:":"Қате: Файл мөлшері тым үлкен:","Add Files":"Файл қосу"});
\ No newline at end of file
// Khmer (km)
plupload.addI18n({"Stop Upload":"បញ្ឈប់​ការ​ផ្ទុក​ឡើង","Upload URL might be wrong or doesn't exist.":"URL ផ្ទុក​ឡើង​អាច​ខុស ឬ​ក៏​គ្មាន។","tb":"tb","Size":"ទំហំ","Close":"បិទ","Init error.":"កំហុស Init។","Add files to the upload queue and click the start button.":"បន្ថែម​ឯកសារ​ទៅ​ក្នុង​ជួរ​លំដាប់​ផ្ទុក​ឡើង ហើយ​ចុច​ប៊ូតុង​ចាប់​ផ្ដើម។","Filename":"ឈ្មោះ​ឯកសារ","Image format either wrong or not supported.":"ទ្រង់​ទ្រាយ​រូបភាព​អាច​ខុស ឬ​ក៏​មិន​ស្គាល់​តែ​ម្ដង។","Status":"ស្ថានភាព","HTTP Error.":"កំហុស HTTP ។","Start Upload":"ចាប់​ផ្ដើម​ផ្ទុក​ឡើង","mb":"mb","kb":"kb","Duplicate file error.":"កំហុស​ឯកសារ​ស្ទួន​គ្នា។","File size error.":"កំហុស​ទំហំ​ឯកសារ។","N/A":"គ្មាន","gb":"gb","Error: Invalid file extension:":"កំហុស៖ កន្ទុយ​ឯកសារ​មិន​ត្រឹម​ត្រូវ៖","Select files":"ជ្រើស​ឯកសារ","%s already present in the queue.":"មាន %s នៅ​ក្នុង​ជួរ​លំដាប់​ហើយ។","File: %s":"ឯកសារ៖ %s","b":"b","Uploaded %d/%d files":"បាន​ផ្ទុក​ឡើង​ឯកសារ %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"ការ​ផ្ទុក​ឡើង​ទទួល​ឯកសារ​បាន​តែ %d ប៉ុណ្ណោះ​ក្នុង​ពេល​តែ​មួយ។ ឯកសារ​ផ្សេង​ទៀត​នឹង​ត្រូវ​ដក​ចេញ។","%d files queued":"បាន​ដាក់​ឯកសារ %d បន្ត​គ្នា","File: %s, size: %d, max file size: %d":"ឯកសារ៖ %s, size: %d, ទំហំ​ឯកសារ​អតិបរមា៖ %d","Drag files here.":"អូស​ឯកសារ​មក​ទីនេះ។","Runtime ran out of available memory.":"ពេល​ដំណើរ​ការ​អស់​អង្គ​ចងចាំ​ទំនេរ​ហើយ។","File count error.":"កំហុស​ការ​រាប់​ឯកសារ។","File extension error.":"កំហុស​កន្ទុយ​ឯកសារ។","Error: File too large:":"កំហុស៖ ឯកសារ​ធំ​ពេក៖","Add Files":"បន្ថែម​ឯកសារ"});
\ No newline at end of file
// Korean (ko)
plupload.addI18n({"Stop Upload":"업로드 중지","Upload URL might be wrong or doesn't exist.":"업로드할 URL이 존재하지 않습니다.","tb":"tb","Size":"크기","Close":"닫기","Init error.":"초기화 오류.","Add files to the upload queue and click the start button.":"파일을 업로드 큐에 추가한 후 시작 버튼을 클릭하십시오.","Filename":"파일명","Image format either wrong or not supported.":"지원되지 않는 이미지 형식입니다.","Status":"상태","HTTP Error.":"HTTP 오류.","Start Upload":"업로드 시작","mb":"mb","kb":"kb","Duplicate file error.":"파일 중복 오류.","File size error.":"파일 크기 오류.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"오류: 허용되지 않은 확장자입니다.","Select files":"파일 선택","%s already present in the queue.":"%s 파일이 이미 대기열에 존재합니다.","File: %s":"파일: %s","b":"b","Uploaded %d/%d files":"%d / %d 파일 업로드 완료","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"업로드 가능한 파일의 수는 %d 입니다. 불필요한 파일은 삭제되었습니다.","%d files queued":"%d 파일이 추가됨","File: %s, size: %d, max file size: %d":"파일: %s, 크기: %d, 최대 파일 크기: %d","Drag files here.":"이곳에 파일을 드래그 하세요.","Runtime ran out of available memory.":"런타임 메모리가 부족합니다.","File count error.":"파일 갯수 오류.","File extension error.":"파일 확장자 오류.","Error: File too large:":"오류: 파일 크기가 너무 큽니다.","Add Files":"파일 추가"});
\ No newline at end of file
// Kurdish (Iraq) (ku_IQ)
plupload.addI18n({"Stop Upload":"وەستانی بارکردن","Upload URL might be wrong or doesn't exist.":".بەستەری بارکراو نادروستە یان بەردەست نییە","tb":"تێرابایت","Size":"قەبارە","Close":"داخستن","Init error.":".هەڵەی ئامادەکردن","Add files to the upload queue and click the start button.":".زیادکردنی پەڕگەکان بۆ ڕیزی بارکردن و کرتەکردن لە دوگمەی دەستپێکردن","Filename":"ناوی پەڕگە","Image format either wrong or not supported.":".شێوازی وێنە هەڵەیە یان پاڵپشتی ناکرێت","Status":"ڕەوش","HTTP Error.":".HTTP هەڵەی","Start Upload":"دەستپێکردنی بارکردن","mb":"مێگابایت","kb":"کیلۆبایت","Duplicate file error.":".هەڵەی پەڕگەی دوبارە","File size error.":".هەڵەی قەبارەی پەڕگە","N/A":"بەردەست نییە","gb":"گێگابایت","Error: Invalid file extension:":":هەڵە: پاشگری پەڕگەی نادروست","Select files":"دیاریکردنی پەڕگەکان","%s already present in the queue.":".ئامادەیی هەیە لە ڕیز %s","File: %s":"%s :پەڕگە","b":"بایت","Uploaded %d/%d files":"پەڕگە بارکران %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"بەشی بارکردن تەنها %d پەڕگە(کان) وەردەگرێت لەیەک کاتدا. پەڕگە زیادەکان .جیادەکرێنەوە","%d files queued":"پەڕگە ڕیزکران %d","File: %s, size: %d, max file size: %d":"پەڕگە: %s، قەبارە: %d، گەورەترین قەبارەی پەڕگە: %d","Drag files here.":".پەڕگەکان ڕاکێشە بۆ ئێرە","Runtime ran out of available memory.":"هەڵەی دەرچوون لە بیرگەی بەردەست.","File count error.":".هەڵەی ژماردنی پەڕگە","File extension error.":".هەڵەی پاشگری پەڕگە","Error: File too large:":":هەڵە: پەڕگەکە زۆر گەورەیە","Add Files":"زیادکردنی پەڕگەکان"});
\ No newline at end of file
// Lithuanian (lt)
plupload.addI18n({"Stop Upload":"Stabdyti įkėlimą","Upload URL might be wrong or doesn't exist.":"Klaidinga arba neegzistuojanti įkėlimo nuoroda.","tb":"tb","Size":"Dydis","Close":"Uždaryti","Init error.":"Įkrovimo klaida.","Add files to the upload queue and click the start button.":"Pridėkite bylas į įkėlimo eilę ir paspauskite starto mygtuką.","Filename":"Bylos pavadinimas","Image format either wrong or not supported.":"Paveiksliuko formatas klaidingas arba nebepalaikomas.","Status":"Statusas","HTTP Error.":"HTTP klaida.","Start Upload":"Pradėti įkėlimą","mb":"mb","kb":"kb","Duplicate file error.":"Pasikartojanti byla.","File size error.":"Netinkamas bylos dydis.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Klaida: Netinkamas bylos plėtinys:","Select files":"Žymėti bylas","%s already present in the queue.":"%s jau yra eilėje.","File: %s":"Byla: %s","b":"b","Uploaded %d/%d files":"Įkelta bylų: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Vienu metu galima įkelti tik %d bylas(ų). Papildomos bylos buvo pašalintos.","%d files queued":"%d bylų eilėje","File: %s, size: %d, max file size: %d":"Byla: %s, dydis: %d, galimas dydis: %d","Drag files here.":"Padėti bylas čia.","Runtime ran out of available memory.":"Išeikvota darbinė atmintis.","File count error.":"Netinkamas bylų kiekis.","File extension error.":"Netinkamas pletinys.","Error: File too large:":"Klaida: Byla per didelė:","Add Files":"Pridėti bylas"});
\ No newline at end of file
// Latvian (lv)
plupload.addI18n({"Stop Upload":"Apturēt augšupielādi","Upload URL might be wrong or doesn't exist.":"Augšupielādes saite neeksistē vai ir nepareiza.","tb":"terabaiti","Size":"Izmērs","Close":"Aizvērt","Init error.":"Inicializācijas kļūda.","Add files to the upload queue and click the start button.":"Pievienojiet failus rindai un klikšķiniet uz pogas \"Sākt augšupielādi\".","Filename":"Faila nosaukums","Image format either wrong or not supported.":"Attēla formāts ir nepareizs vai arī netiek atbalstīts.","Status":"Statuss","HTTP Error.":"HTTP kļūda.","Start Upload":"Sākt augšupielādi","mb":"megabaiti","kb":"kilobaiti","Duplicate file error.":"Atkārtota faila kļūda","File size error.":"Faila izmēra kļūda.","N/A":"N/A","gb":"gigabaiti","Error: Invalid file extension:":"Kļūda: Nepareizs faila paplašinājums:","Select files":"Izvēlieties failus","%s already present in the queue.":"%s jau ir atrodams rindā.","File: %s":"Fails: %s","b":"baiti","Uploaded %d/%d files":"Augšupielādēti %d/%d faili","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Iespējams ielādēt tikai %d failus vienā reizē. Atlikušie faili netika pievienoti","%d files queued":"%d faili pievienoti rindai","File: %s, size: %d, max file size: %d":"Fails: %s, izmērs: %d, max faila izmērs: %d","Drag files here.":"Ievelciet failus šeit","Runtime ran out of available memory.":"Pietrūkst izmantojamās atmiņas.","File count error.":"Failu skaita kļūda","File extension error.":"Faila paplašinājuma kļūda.","Error: File too large:":"Kļūda: Fails pārāk liels:","Add Files":"Pievienot failus"});
\ No newline at end of file
// Malay (ms)
plupload.addI18n({"Stop Upload":"Berhenti Muat naik","Upload URL might be wrong or doesn't exist.":"URL muat naik mungkin salah atau tidak wujud.","tb":"tb","Size":"saiz","Close":"Tutup","Init error.":"Ralat perlaksanaan.","Add files to the upload queue and click the start button.":"Tambah fail ke dalam giliran muat naik dan klik butang Muat Naik.","Filename":"Nama fail","Image format either wrong or not supported.":"Format imej sama ada salah atau tidak disokong.","Status":"Status","HTTP Error.":"Ralat HTTP.","Start Upload":"Muat Naik","mb":"mb","kb":"kb","Duplicate file error.":"Ralat menggandakan fail.","File size error.":"Ralat saiz fail.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Ralat: Sambungan fail tidak sah:","Select files":"Pilih fail","%s already present in the queue.":"%s telah ada dalam barisan.","File: %s":"Fail: %s","b":"b","Uploaded %d/%d files":"%d/%d telah dimuat naik","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Element muat naik hanya menerima %d fail(-fail) pada satu masa. Fail tambahan telah digugurkan.","%d files queued":"%d fail dalam barisan","File: %s, size: %d, max file size: %d":"Fail: %s, saiz: %d, saiz maks fail: %d","Drag files here.":"Seret fail ke sini.","Runtime ran out of available memory.":"Ruang ingatan masa larian tidak mencukupi.","File count error.":"Ralat bilangan fail.","File extension error.":"Ralat sambungan fail.","Error: File too large:":"Ralat: Fail terlalu bersar:","Add Files":"Tambah Fail"});
\ No newline at end of file
// Dutch (nl)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL is verkeerd of bestaat niet.","tb":"tb","Size":"Grootte","Close":"Sluiten","Init error.":"Initialisatie error.","Add files to the upload queue and click the start button.":"Voeg bestanden toe aan de wachtrij en druk op 'Start'.","Filename":"Bestandsnaam","Image format either wrong or not supported.":"bestandsextensie is verkeerd of niet ondersteund.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Start Upload","mb":"mb","kb":"kb","Duplicate file error.":"Bestand bestaat al.","File size error.":"Bestandsgrootte error.","N/A":"Niet beschikbaar","gb":"gb","Error: Invalid file extension:":"Error: Ongeldige bestandsextensie:","Select files":"Selecteer bestand(en):","%s already present in the queue.":"%s is al aan de wachtrij toegevoegd.","File: %s":"Bestand: %s","b":"b","Uploaded %d/%d files":"%d/%d bestanden ge-upload","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload accepteert alleen %d bestand(en) tegelijk. Extra bestanden zijn verwijderd.","%d files queued":"%d bestand(en) in de wachtrij","File: %s, size: %d, max file size: %d":"Bestand: %s, grootte: %d, maximale bestandsgrootte: %d","Drag files here.":"Sleep bestanden hierheen.","Runtime ran out of available memory.":"Het maximum bruikbare geheugen is overschreden.","File count error.":"Teveel bestand(en) error.","File extension error.":"Ongeldig bestandsextensie.","Error: File too large:":"Error: Bestand te groot:","Add Files":"Bestand(en) toevoegen"});
\ No newline at end of file
// Polish (pl)
plupload.addI18n({"Stop Upload":"Przerwij transfer.","Upload URL might be wrong or doesn't exist.":"Adres URL moze bys nieprawidlowy lub moze nieistniec","tb":"tb","Size":"Rozmiar","Close":"Zamknij","Init error.":"Błąd inicjalizacji.","Add files to the upload queue and click the start button.":"Dodaj pliki i kliknij 'Rozpocznij transfer'.","Filename":"Nazwa pliku","Image format either wrong or not supported.":"Format zdjecia jest zly lub nieobslugiwany","Status":"Status","HTTP Error.":"Błąd HTTP.","Start Upload":"Wyslij","mb":"mb","kb":"kb","Duplicate file error.":"Blad: duplikacja pliku.","File size error.":"Plik jest zbyt duży.","N/A":"Nie dostępne","gb":"gb","Error: Invalid file extension:":"Blad: Nieprawidlowe rozszerzenie pliku:","Select files":"Wybierz pliki:","%s already present in the queue.":"%s juz wystepuje w kolejce.","File: %s":"Plik: %s","b":"b","Uploaded %d/%d files":"Wysłano %d/%d plików","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d plików w kolejce.","File: %s, size: %d, max file size: %d":"Plik: %s, rozmiar: %d, maksymalny rozmiar pliku: %d","Drag files here.":"Przeciągnij tu pliki","Runtime ran out of available memory.":"Wyczerpano pamiec RAM.","File count error.":"Blad liczenia pliku.","File extension error.":"Nieobsługiwany format pliku.","Error: File too large:":"Blad: Plik za duzy:","Add Files":"Dodaj pliki"});
\ No newline at end of file
// Portuguese (Brazil) (pt_BR)
plupload.addI18n({"Stop Upload":"Parar o envio","Upload URL might be wrong or doesn't exist.":"URL de envio está errada ou não existe","tb":"TB","Size":"Tamanho","Close":"Fechar","Init error.":"Erro inicializando.","Add files to the upload queue and click the start button.":"Adicione os arquivos abaixo e clique no botão \"Iniciar o envio\".","Filename":"Nome do arquivo","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"Erro HTTP.","Start Upload":"Iniciar o envio","mb":"MB","kb":"KB","Duplicate file error.":"Erro: Arquivo duplicado.","File size error.":"Tamanho de arquivo não permitido.","N/A":"N/D","gb":"GB","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Escolha os arquivos","%s already present in the queue.":"%s já presentes na fila.","File: %s":"Arquivo: %s","b":"Bytes","Uploaded %d/%d files":"Enviado(s) %d/%d arquivo(s)","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Só são aceitos %d arquivos por vez. O que passou disso foi descartado.","%d files queued":"%d arquivo(s)","File: %s, size: %d, max file size: %d":"Arquivo: %s, Tamanho: %d , Tamanho Máximo do Arquivo: %d","Drag files here.":"Arraste os arquivos pra cá","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Erro na contagem dos arquivos","File extension error.":"Tipo de arquivo não permitido.","Error: File too large:":"Error: File too large:","Add Files":"Adicionar arquivo(s)"});
\ No newline at end of file
// Romanian (ro)
plupload.addI18n({"Stop Upload":"Oprește încărcarea","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Mărime","Close":"Închide","Init error.":"Eroare inițializare.","Add files to the upload queue and click the start button.":"Adaugă fișiere în lista apoi apasă butonul \"Începe încărcarea\".","Filename":"Nume fișier","Image format either wrong or not supported.":"Formatul de imagine ori este greșit ori nu este suportat.","Status":"Stare","HTTP Error.":"Eroare HTTP","Start Upload":"Începe încărcarea","mb":"mb","kb":"kb","Duplicate file error.":"Eroare duplicat fișier.","File size error.":"Eroare dimensiune fișier.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Eroare: Extensia fișierului este invalidă:","Select files":"Selectează fișierele","%s already present in the queue.":"%s există deja în lista de așteptare.","File: %s":"Fișier: %s","b":"b","Uploaded %d/%d files":"Fișiere încărcate %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d fișiere listate","File: %s, size: %d, max file size: %d":"Fișier: %s, mărime: %d, mărime maximă: %d","Drag files here.":"Trage aici fișierele.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Eroare numărare fișiere.","File extension error.":"Eroare extensie fișier.","Error: File too large:":"Eroare: Fișierul este prea mare:","Add Files":"Adaugă fișiere"});
\ No newline at end of file
// Russian (ru)
plupload.addI18n({"Stop Upload":"Остановить Загрузку","Upload URL might be wrong or doesn't exist.":"Адрес заргузки неправильный или он не существует.","tb":"тб","Size":"Размер","Close":"Закрыть","Init error.":"Ошибка инициализации.","Add files to the upload queue and click the start button.":"Добавьте файлы в очередь и нажмите кнопку \"Загрузить файлы\".","Filename":"Имя файла","Image format either wrong or not supported.":"Формат картинки неправильный или он не поддерживается.","Status":"Статус","HTTP Error.":"Ошибка HTTP.","Start Upload":"Начать загрузку","mb":"мб","kb":"кб","Duplicate file error.":"Такой файл уже присутствует в очереди.","File size error.":"Неправильный размер файла.","N/A":"N/A","gb":"гб","Error: Invalid file extension:":"Ошибка: У файла неправильное расширение:","Select files":"Выберите файлы","%s already present in the queue.":"%s уже присутствует в очереди.","File: %s":"Файл: %s","b":"б","Uploaded %d/%d files":"Загружено %d/%d файлов","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Загрузочный элемент за раз принимает только %d файл(ов). Лишние файлы были отброшены.","%d files queued":"В очереди %d файл(ов)","File: %s, size: %d, max file size: %d":"Файл: %s, размер: %d, макс. размер файла: %d","Drag files here.":"Перетащите файлы сюда.","Runtime ran out of available memory.":"Рабочая среда превысила лимит достуной памяти.","File count error.":"Слишком много файлов.","File extension error.":"Неправильное расширение файла.","Error: File too large:":"Ошибка: Файл слишком большой:","Add Files":"Добавьте файлы"});
\ No newline at end of file
// Slovak (sk)
plupload.addI18n({"Stop Upload":"Zastaviť nahrávanie","Upload URL might be wrong or doesn't exist.":"URL pre nahratie nie je správna alebo neexistuje.","tb":"tb","Size":"Veľkosť","Close":"Zatvoriť","Init error.":"Chyba inicializácie.","Add files to the upload queue and click the start button.":"Pridajte súbory do zoznamu a potom spustite nahrávanie.","Filename":"Názov súboru","Image format either wrong or not supported.":"Formát obrázku je nesprávny alebo nie je podporovaný.","Status":"Stav","HTTP Error.":"HTTP Chyba.","Start Upload":"Spustiť nahrávanie","mb":"mb","kb":"kb","Duplicate file error.":"Duplicitný súbor.","File size error.":"Súbor je príliš veľký.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Error: Nesprávny typ súboru:","Select files":"Vyberte súbory","%s already present in the queue.":"%s sa už nachádza v zozname.","File: %s":"Súbor: %s","b":"b","Uploaded %d/%d files":"Nahraných %d/%d súborov","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d súborov pridaných do zoznamu","File: %s, size: %d, max file size: %d":"Súbor: %s, veľkosť: %d, max. veľkosť súboru: %d","Drag files here.":"Sem pretiahnite súbory.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Nesprávny počet súborov.","File extension error.":"Chybný typ súboru.","Error: File too large:":"Chyba: Súbor je príliš veľký:","Add Files":"Pridať súbory"});
\ No newline at end of file
// Albanian (sq)
plupload.addI18n({"Stop Upload":"Ndalimi i ngarkimit","Upload URL might be wrong or doesn't exist.":"Ngarkimi i URL-s është i gabuar ose nuk ekziston.","tb":"TB","Size":"Madhësia","Close":"Mbyll","Init error.":"Init gabim.","Add files to the upload queue and click the start button.":"Mbas ngarkimit të dosjeve sipas rradhës duhet të klikoni butonin Start.","Filename":"Emri i dosjes","Image format either wrong or not supported.":"Formati i fotove është i keq ose nuk është i pranueshëm.","Status":"Statusi","HTTP Error.":"HTTP Gabim.","Start Upload":"Nisja e ngarkimit","mb":"MB","kb":"KB","Duplicate file error.":"Gabim i dublikimit të dosjes.","File size error.":"Gabim i madhësisë së dosjes.","N/A":"Nuk është në dispozicion","gb":"GB","Error: Invalid file extension:":"Gabim: përhapja e llojit të dosjes është e pavlefshme:","Select files":"Zhgjidhni dosjet","%s already present in the queue.":"%s tashmë ekziston në list.","File: %s":"Dosje: %s","b":"B","Uploaded %d/%d files":"Dosjet e ngarkuara: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Ngarkimi pranon njëherësh vetëm %d dosje, dosjet e tjera nuk do të jenë të ngarkuara.","%d files queued":"Dosja %d e vendosur në rradhë","File: %s, size: %d, max file size: %d":"Dosje: %s, madhësia: %d, madhësia maximale e dosjes: %d","Drag files here.":"Këtu mund të tërhiqni dosjet","Runtime ran out of available memory.":"Memoria që ishte në dispozicion ka mbaruar.","File count error.":"Gabim në lidhje me numrin e dosjeve.","File extension error.":"Gabim i zgjerimit të dosjes.","Error: File too large:":"Gabim: dosja është shumë e madhe:","Add Files":"Shtoni dosjet"});
\ No newline at end of file
// Serbian (sr)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"","Size":"Veličina","Close":"Close","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Dodajte fajlove u listu i kliknite na dugme Start.","Filename":"Naziv fajla","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Počni upload","mb":"","kb":"","Duplicate file error.":"","File size error.":"File size error.","N/A":"N/A","gb":"","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Izaberite fajlove","%s already present in the queue.":"","File: %s":"File: %s","b":"","Uploaded %d/%d files":"Snimljeno %d/%d fajlova","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d files queued","File: %s, size: %d, max file size: %d":"","Drag files here.":"Prevucite fajlove ovde.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"File count error.","File extension error.":"File extension error.","Error: File too large:":"Error: File too large:","Add Files":"Dodaj fajlove"});
\ No newline at end of file
// Swedish (sv)
plupload.addI18n({"Stop Upload":"Avbryt","Upload URL might be wrong or doesn't exist.":"URL:en va fel eller existerar inte.","tb":"tb","Size":"Storlek","Close":"Stäng","Init error.":"Problem vid initialisering.","Add files to the upload queue and click the start button.":"Lägg till filer till kön och tryck på start.","Filename":"Filnamn","Image format either wrong or not supported.":"Bildformatet är fel eller så finns inte stöd för det.","Status":"Status","HTTP Error.":"HTTP problem.","Start Upload":"Starta","mb":"mb","kb":"kb","Duplicate file error.":"Problem med dubbla filer.","File size error.":"Problem med filstorlek.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Fel: Ej godkänd filändelse.","Select files":"Välj filer","%s already present in the queue.":"%s är redan tillagd.","File: %s":"Fil: %s","b":"b","Uploaded %d/%d files":"Laddade upp %d/%d filer","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Det går bara lägga till %d filer åt gången, allt utöver detta togs bort.","%d files queued":"%d filer i kö","File: %s, size: %d, max file size: %d":"Fil: %s, storlek: %d, max storlek: %d","Drag files here.":"Dra filer hit","Runtime ran out of available memory.":"Slut på minne.","File count error.":"Räknefel.","File extension error.":"Problem med filändelse.","Error: File too large:":"Fel: Filen är för stor:","Add Files":"Lägg till"});
\ No newline at end of file
// Thai (Thailand) (th_TH)
plupload.addI18n({"Stop Upload":"หยุดอัพโหลด","Upload URL might be wrong or doesn't exist.":"URL ของการอัพโหลดอาจจะผิดหรือไม่มีอยู่","tb":"เทราไบต์","Size":"ขนาด","Close":"ปิด","Init error.":"Init เกิดข้อผิดพลาด","Add files to the upload queue and click the start button.":"เพิ่มไฟล์ไปยังคิวอัพโหลดและคลิกที่ปุ่มเริ่ม","Filename":"ชื่อไฟล์","Image format either wrong or not supported.":"รูปแบบรูปภาพทั้งสองผิดหรือไม่รองรับ","Status":"สถานะ","HTTP Error.":"HTTP เกิดข้อผิดพลาด","Start Upload":"เริ่มอัพโหลด","mb":"เมกะไบต์","kb":"กิโลไบต์","Duplicate file error.":"ไฟล์ที่ซ้ำกันเกิดข้อผิดพลาด","File size error.":"ขนาดไฟล์เกิดข้อผิดพลาด","N/A":"N/A","gb":"กิกะไบต์","Error: Invalid file extension:":"ข้อผิดพลาด: นามสกุลไฟล์ไม่ถูกต้อง:","Select files":"เลือกไฟล์","%s already present in the queue.":"%s อยู่ในคิวแล้ว","File: %s":"ไฟล์: %s","b":"ไบต์","Uploaded %d/%d files":"อัพโหลดแล้ว %d/%d ไฟล์","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"การอัพโหลดจะยอมรับเฉพาะ %d ไฟล์(s) ในช่วงเวลาเดียวกัน เมื่อไฟล์พิเศษถูกปลดออก","%d files queued":"%d ไฟล์ที่อยู่ในคิว","File: %s, size: %d, max file size: %d":"ไฟล์: %s, ขนาด: %d, ขนาดไฟล์สูงสุด: %d","Drag files here.":"ลากไฟล์มาที่นี่","Runtime ran out of available memory.":"รันไทม์วิ่งออกมาจากหน่วยความจำ","File count error.":"การนับไฟล์เกิดข้อผิดพลาด","File extension error.":"นามสกุลไฟล์เกิดข้อผิดพลาด","Error: File too large:":"ข้อผิดพลาด: ไฟล์ใหญ่เกินไป:","Add Files":"เพิ่มไฟล์"});
\ No newline at end of file
// Turkish (tr)
plupload.addI18n({"Stop Upload":"Yüklemeyi durdur","Upload URL might be wrong or doesn't exist.":"URL yok ya da hatalı olabilir.","tb":"tb","Size":"Boyut","Close":"Kapat","Init error.":"Başlangıç hatası.","Add files to the upload queue and click the start button.":"Dosyaları kuyruğa ekleyin ve başlatma butonuna tıklayın.","Filename":"Dosya adı","Image format either wrong or not supported.":"Resim formatı yanlış ya da desteklenmiyor.","Status":"Durum","HTTP Error.":"HTTP hatası.","Start Upload":"Yüklemeyi başlat","mb":"mb","kb":"kb","Duplicate file error.":"Yinelenen dosya hatası.","File size error.":"Dosya boyutu hatası.","N/A":"-","gb":"gb","Error: Invalid file extension:":"Hata: Geçersiz dosya uzantısı:","Select files":"Dosyaları seç","%s already present in the queue.":"%s kuyrukta zaten mevcut.","File: %s":"Dosya: %s","b":"bayt","Uploaded %d/%d files":"%d/%d dosya yüklendi","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Yükleme elemanı aynı anda %d dosya kabul eder. Ekstra dosyalar işleme konulmaz.","%d files queued":"Kuyrukta %d dosya var.","File: %s, size: %d, max file size: %d":"Dosya: %s, boyut: %d, maksimum dosya boyutu: %d","Drag files here.":"Dosyaları buraya bırakın.","Runtime ran out of available memory.":"İşlem için yeterli bellek yok.","File count error.":"Dosya sayım hatası.","File extension error.":"Dosya uzantısı hatası.","Error: File too large:":"Hata: Dosya çok büyük:","Add Files":"Dosya ekle"});
\ No newline at end of file
// Ukrainian (Ukraine) (uk_UA)
plupload.addI18n({"Stop Upload":"Зупинити завантаження","Upload URL might be wrong or doesn't exist.":"Адреса завантаження неправильна або не існує.","tb":"тб","Size":"Розмір","Close":"Закрити","Init error.":"Помилка ініціалізації.","Add files to the upload queue and click the start button.":"Додайте файли в чергу та натисніть кнопку \"Завантажити файли\".","Filename":"Назва файлу","Image format either wrong or not supported.":"Формат картинки не правильний або не підтримується.","Status":"Статус","HTTP Error.":"Помилка HTTP.","Start Upload":"Почати завантаження","mb":"мб","kb":"кб","Duplicate file error.":"Такий файл вже присутній в черзі.","File size error.":"Неправильний розмір файлу.","N/A":"Н/Д","gb":"гб","Error: Invalid file extension:":"Помилка: У файлу неправильне розширення:","Select files":"Оберіть файли","%s already present in the queue.":"%s вже присутній у черзі.","File: %s":"Файл: %s","b":"б","Uploaded %d/%d files":"Завантажено %d/%d файлів","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Завантажувальний елемент приймає лише %d файл(ів) одночасно. Зайві файли було відкинуто.","%d files queued":"В черзі %d файл(ів)","File: %s, size: %d, max file size: %d":"Файл: %s, розмір: %d, макс. розмір файлу: %d","Drag files here.":"Перетягніть файли сюди.","Runtime ran out of available memory.":"Робоче середовище перевищило ліміт доступної пам'яті.","File count error.":"Занадто багато файлів.","File extension error.":"Неправильне розширення файлу.","Error: File too large:":"Помилка: Файл занадто великий:","Add Files":"Додати файли"});
\ No newline at end of file
// Vietnamese (vi)
plupload.addI18n({"Stop Upload":"Dừng","Upload URL might be wrong or doesn't exist.":"Đường dẫn URL tải lên không đúng hoặc không tồn tại.","tb":"TB","Size":"Dung lượng","Close":"Đóng","Init error.":"Lỗi khởi tạo","Add files to the upload queue and click the start button.":"Thêm tập tin để tải lên và bấm vào nút bắt đầu","Filename":"Tên tập tin","Image format either wrong or not supported.":"Địng dạng hình ảnh không đúng hoặc không được hỗ trợ.","Status":"Trạng thái","HTTP Error.":"Lỗi HTTP","Start Upload":"Bắt đầu","mb":"MB","kb":"KB","Duplicate file error.":"Tập tin đã tồn tại","File size error.":"Lỗi dung lượng tập tin","N/A":"Chưa có thông tin","gb":"GB","Error: Invalid file extension:":"Lỗi: Định dạng tập tin không xác định:","Select files":"Chọn tập tin","%s already present in the queue.":"%s đã có trong danh sách chờ tải lên","File: %s":"Tập tin: %s","b":"B","Uploaded %d/%d files":"Đã tải lên %d/%d tập tin","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Chỉ có thể tải lên (%d) tập tin cùng một lúc. Những tập tin còn lại đã bị huỷ bỏ.","%d files queued":"%d tập tin trong danh sách chờ","File: %s, size: %d, max file size: %d":"Tập tin: %s, dung lượng %d, dung lượng tối đa: %d","Drag files here.":"Ném vào đây","Runtime ran out of available memory.":"Thời gian chạy vượt quá giới hạn bộ nhớ cho phép.","File count error.":"Lỗi đếm tập tin","File extension error.":"Lỗi định dạng tập tin","Error: File too large:":"Lỗi: Dung lượng tập tin quá lớn:","Add Files":"Thêm tập tin"});
\ No newline at end of file
// Chinese (China) (zh_CN)
plupload.addI18n({"Stop Upload":"停止上传","Upload URL might be wrong or doesn't exist.":"上传的URL可能是错误的或不存在。","tb":"tb","Size":"大小","Close":"关闭","Init error.":"初始化错误。","Add files to the upload queue and click the start button.":"将文件添加到上传队列,然后点击”开始上传“按钮。","Filename":"文件名","Image format either wrong or not supported.":"图片格式错误或者不支持。","Status":"状态","HTTP Error.":"HTTP 错误。","Start Upload":"开始上传","mb":"mb","kb":"kb","Duplicate file error.":"重复文件错误。","File size error.":"文件大小错误。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"错误:无效的文件扩展名:","Select files":"选择文件","%s already present in the queue.":"%s 已经在当前队列里。","File: %s":"文件: %s","b":"b","Uploaded %d/%d files":"已上传 %d/%d 个文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只接受同时上传 %d 个文件,多余的文件将会被删除。","%d files queued":"%d 个文件加入到队列","File: %s, size: %d, max file size: %d":"文件: %s, 大小: %d, 最大文件大小: %d","Drag files here.":"把文件拖到这里。","Runtime ran out of available memory.":"运行时已消耗所有可用内存。","File count error.":"文件数量错误。","File extension error.":"文件扩展名错误。","Error: File too large:":"错误: 文件太大:","Add Files":"增加文件"});
\ No newline at end of file
// Chinese (Taiwan) (zh_TW)
plupload.addI18n({"Stop Upload":"停止上傳","Upload URL might be wrong or doesn't exist.":"檔案URL可能有誤或者不存在。","tb":"tb","Size":"大小","Close":"關閉","Init error.":"初始化錯誤。","Add files to the upload queue and click the start button.":"將檔案加入上傳序列,然後點選”開始上傳“按鈕。","Filename":"檔案名稱","Image format either wrong or not supported.":"圖片格式錯誤或者不支援。","Status":"狀態","HTTP Error.":"HTTP 錯誤。","Start Upload":"開始上傳","mb":"mb","kb":"kb","Duplicate file error.":"錯誤:檔案重複。","File size error.":"錯誤:檔案大小超過限制。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"錯誤:不接受的檔案格式:","Select files":"選擇檔案","%s already present in the queue.":"%s 已經存在目前的檔案序列。","File: %s":"檔案: %s","b":"b","Uploaded %d/%d files":"已上傳 %d/%d 個文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只能上傳 %d 個檔案,超過限制數量的檔案將被忽略。","%d files queued":"%d 個檔案加入到序列","File: %s, size: %d, max file size: %d":"檔案: %s, 大小: %d, 檔案大小上限: %d","Drag files here.":"把檔案拖曳到這裡。","Runtime ran out of available memory.":"執行時耗盡了所有可用的記憶體。","File count error.":"檔案數量錯誤。","File extension error.":"檔案副檔名錯誤。","Error: File too large:":"錯誤: 檔案大小太大:","Add Files":"增加檔案"});
\ No newline at end of file
/**
* jquery.plupload.queue.js
*
* Copyright 2009, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/* global jQuery:true, alert:true */
/**
jQuery based implementation of the Plupload API - multi-runtime file uploading API.
To use the widget you must include _jQuery_. It is not meant to be extended in any way and is provided to be
used as it is.
@example
<!-- Instantiating: -->
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<script>
$('#uploader').pluploadQueue({
url : '../upload.php',
filters : [
{title : "Image files", extensions : "jpg,gif,png"}
],
rename: true,
flash_swf_url : '../../js/Moxie.swf',
silverlight_xap_url : '../../js/Moxie.xap',
});
</script>
@example
// Retrieving a reference to plupload.Uploader object
var uploader = $('#uploader').pluploadQueue();
uploader.bind('FilesAdded', function() {
// Autostart
setTimeout(uploader.start, 1); // "detach" from the main thread
});
@class pluploadQueue
@constructor
@param {Object} settings For detailed information about each option check documentation.
@param {String} settings.url URL of the server-side upload handler.
@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
@param {Array} [settings.filters=[]] Set of file type filters, each one defined by hash of title and extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
@param {String} [settings.flash_swf_url] URL of the Flash swf.
@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
@param {Number} [settings.resize.width] If image is bigger, it will be resized.
@param {Number} [settings.resize.height] If image is bigger, it will be resized.
@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
*/
;(function($, o) {
var uploaders = {};
function _(str) {
return plupload.translate(str) || str;
}
function renderUI(id, target) {
// Remove all existing non plupload items
target.contents().each(function(i, node) {
node = $(node);
if (!node.is('.plupload')) {
node.remove();
}
});
target.prepend(
'<div class="plupload_wrapper plupload_scroll">' +
'<div id="' + id + '_container" class="plupload_container">' +
'<div class="plupload">' +
'<div class="plupload_header">' +
'<div class="plupload_header_content">' +
'<div class="plupload_header_title">' + _('Select files') + '</div>' +
'<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
'</div>' +
'</div>' +
'<div class="plupload_content">' +
'<div class="plupload_filelist_header">' +
'<div class="plupload_file_name">' + _('Filename') + '</div>' +
'<div class="plupload_file_action">&nbsp;</div>' +
'<div class="plupload_file_status"><span>' + _('Status') + '</span></div>' +
'<div class="plupload_file_size">' + _('Size') + '</div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'<ul id="' + id + '_filelist" class="plupload_filelist"></ul>' +
'<div class="plupload_filelist_footer">' +
'<div class="plupload_file_name">' +
'<div class="plupload_buttons">' +
'<a href="#" class="plupload_button plupload_add" id="' + id + '_browse">' + _('Add Files') + '</a>' +
'<a href="#" class="plupload_button plupload_start">' + _('Start Upload') + '</a>' +
'</div>' +
'<span class="plupload_upload_status"></span>' +
'</div>' +
'<div class="plupload_file_action"></div>' +
'<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>' +
'<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>' +
'<div class="plupload_progress">' +
'<div class="plupload_progress_container">' +
'<div class="plupload_progress_bar"></div>' +
'</div>' +
'</div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'<input type="hidden" id="' + id + '_count" name="' + id + '_count" value="0" />' +
'</div>'
);
}
$.fn.pluploadQueue = function(settings) {
if (settings) {
this.each(function() {
var uploader, target, id, contents_bak;
target = $(this);
id = target.attr('id');
if (!id) {
id = plupload.guid();
target.attr('id', id);
}
contents_bak = target.html();
renderUI(id, target);
settings = $.extend({
dragdrop : true,
browse_button : id + '_browse',
container : id
}, settings);
// Enable drag/drop (see PostInit handler as well)
if (settings.dragdrop) {
settings.drop_element = id + '_filelist';
}
uploader = new plupload.Uploader(settings);
uploaders[id] = uploader;
function handleStatus(file) {
var actionClass;
if (file.status == plupload.DONE) {
actionClass = 'plupload_done';
}
if (file.status == plupload.FAILED) {
actionClass = 'plupload_failed';
}
if (file.status == plupload.QUEUED) {
actionClass = 'plupload_delete';
}
if (file.status == plupload.UPLOADING) {
actionClass = 'plupload_uploading';
}
var icon = $('#' + file.id).attr('class', actionClass).find('a').css('display', 'block');
if (file.hint) {
icon.attr('title', file.hint);
}
}
function updateTotalProgress() {
$('span.plupload_total_status', target).html(uploader.total.percent + '%');
$('div.plupload_progress_bar', target).css('width', uploader.total.percent + '%');
$('span.plupload_upload_status', target).html(
o.sprintf(_('Uploaded %d/%d files'), uploader.total.uploaded, uploader.files.length)
);
}
function updateList() {
var fileList = $('ul.plupload_filelist', target).html(''), inputCount = 0, inputHTML;
$.each(uploader.files, function(i, file) {
inputHTML = '';
if (file.status == plupload.DONE) {
if (file.target_name) {
inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_tmpname" value="' + plupload.xmlEncode(file.target_name) + '" />';
}
inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_name" value="' + plupload.xmlEncode(file.name) + '" />';
inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_status" value="' + (file.status == plupload.DONE ? 'done' : 'failed') + '" />';
inputCount++;
$('#' + id + '_count').val(inputCount);
}
fileList.append(
'<li id="' + file.id + '">' +
'<div class="plupload_file_name"><span>' + file.name + '</span></div>' +
'<div class="plupload_file_action"><a href="#"></a></div>' +
'<div class="plupload_file_status">' + file.percent + '%</div>' +
'<div class="plupload_file_size">' + plupload.formatSize(file.size) + '</div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
inputHTML +
'</li>'
);
handleStatus(file);
$('#' + file.id + '.plupload_delete a').click(function(e) {
$('#' + file.id).remove();
uploader.removeFile(file);
e.preventDefault();
});
});
$('span.plupload_total_file_size', target).html(plupload.formatSize(uploader.total.size));
if (uploader.total.queued === 0) {
$('span.plupload_add_text', target).html(_('Add Files'));
} else {
$('span.plupload_add_text', target).html(o.sprintf(_('%d files queued'), uploader.total.queued));
}
$('a.plupload_start', target).toggleClass('plupload_disabled', uploader.files.length == (uploader.total.uploaded + uploader.total.failed));
// Scroll to end of file list
fileList[0].scrollTop = fileList[0].scrollHeight;
updateTotalProgress();
// Re-add drag message if there is no files
if (!uploader.files.length && uploader.features.dragdrop && uploader.settings.dragdrop) {
$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
}
}
function destroy() {
delete uploaders[id];
uploader.destroy();
target.html(contents_bak);
uploader = target = contents_bak = null;
}
uploader.bind("UploadFile", function(up, file) {
$('#' + file.id).addClass('plupload_current_file');
});
uploader.bind('Init', function(up, res) {
// Enable rename support
if (!settings.unique_names && settings.rename) {
target.on('click', '#' + id + '_filelist div.plupload_file_name span', function(e) {
var targetSpan = $(e.target), file, parts, name, ext = "";
// Get file name and split out name and extension
file = up.getFile(targetSpan.parents('li')[0].id);
name = file.name;
parts = /^(.+)(\.[^.]+)$/.exec(name);
if (parts) {
name = parts[1];
ext = parts[2];
}
// Display input element
targetSpan.hide().after('<input type="text" />');
targetSpan.next().val(name).focus().blur(function() {
targetSpan.show().next().remove();
}).keydown(function(e) {
var targetInput = $(this);
if (e.keyCode == 13) {
e.preventDefault();
// Rename file and glue extension back on
file.name = targetInput.val() + ext;
targetSpan.html(file.name);
targetInput.blur();
}
});
});
}
$('#' + id + '_container').attr('title', 'Using runtime: ' + res.runtime);
$('a.plupload_start', target).click(function(e) {
if (!$(this).hasClass('plupload_disabled')) {
uploader.start();
}
e.preventDefault();
});
$('a.plupload_stop', target).click(function(e) {
e.preventDefault();
uploader.stop();
});
$('a.plupload_start', target).addClass('plupload_disabled');
});
uploader.bind("Error", function(up, err) {
var file = err.file, message;
if (file) {
message = err.message;
if (err.details) {
message += " (" + err.details + ")";
}
if (err.code == plupload.FILE_SIZE_ERROR) {
alert(_("Error: File too large:") + " " + file.name);
}
if (err.code == plupload.FILE_EXTENSION_ERROR) {
alert(_("Error: Invalid file extension:") + " " + file.name);
}
file.hint = message;
$('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'block').attr('title', message);
}
if (err.code === plupload.INIT_ERROR) {
setTimeout(function() {
destroy();
}, 1);
}
});
uploader.bind("PostInit", function(up) {
// features are populated only after input components are fully instantiated
if (up.settings.dragdrop && up.features.dragdrop) {
$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
}
});
uploader.init();
uploader.bind('StateChanged', function() {
if (uploader.state === plupload.STARTED) {
$('li.plupload_delete a,div.plupload_buttons', target).hide();
uploader.disableBrowse(true);
$('span.plupload_upload_status,div.plupload_progress,a.plupload_stop', target).css('display', 'block');
$('span.plupload_upload_status', target).html('Uploaded ' + uploader.total.uploaded + '/' + uploader.files.length + ' files');
if (settings.multiple_queues) {
$('span.plupload_total_status,span.plupload_total_file_size', target).show();
}
} else {
updateList();
$('a.plupload_stop,div.plupload_progress', target).hide();
$('a.plupload_delete', target).css('display', 'block');
if (settings.multiple_queues && uploader.total.uploaded + uploader.total.failed == uploader.files.length) {
$(".plupload_buttons,.plupload_upload_status", target).css("display", "inline");
uploader.disableBrowse(false);
$(".plupload_start", target).addClass("plupload_disabled");
$('span.plupload_total_status,span.plupload_total_file_size', target).hide();
}
}
});
uploader.bind('FilesAdded', updateList);
uploader.bind('FilesRemoved', function() {
// since the whole file list is redrawn for every change in the queue
// we need to scroll back to the file removal point to avoid annoying
// scrolling to the bottom bug (see #926)
var scrollTop = $('#' + id + '_filelist').scrollTop();
updateList();
$('#' + id + '_filelist').scrollTop(scrollTop);
});
uploader.bind('FileUploaded', function(up, file) {
handleStatus(file);
});
uploader.bind("UploadProgress", function(up, file) {
// Set file specific progress
$('#' + file.id + ' div.plupload_file_status', target).html(file.percent + '%');
handleStatus(file);
updateTotalProgress();
});
// Call setup function
if (settings.setup) {
settings.setup(uploader);
}
});
return this;
} else {
// Get uploader instance for specified element
return uploaders[$(this[0]).attr('id')];
}
};
})(jQuery, mOxie);
/**
* jquery.ui.plupload.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.button.js
* jquery.ui.progressbar.js
*
* Optionally:
* jquery.ui.sortable.js
*/
/* global jQuery:true */
/**
jQuery UI based implementation of the Plupload API - multi-runtime file uploading API.
To use the widget you must include _jQuery_ and _jQuery UI_ bundle (including `ui.core`, `ui.widget`, `ui.button`,
`ui.progressbar` and `ui.sortable`).
In general the widget is designed the way that you do not usually need to do anything to it after you instantiate it.
But! You still can intervenue, to some extent, in case you need to. Although, due to the fact that widget is based on
_jQuery UI_ widget factory, there are some specifics. See examples below for more details.
@example
<!-- Instantiating: -->
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<script>
$('#uploader').plupload({
url : '../upload.php',
filters : [
{title : "Image files", extensions : "jpg,gif,png"}
],
rename: true,
sortable: true,
flash_swf_url : '../../js/Moxie.swf',
silverlight_xap_url : '../../js/Moxie.xap',
});
</script>
@example
// Invoking methods:
$('#uploader').plupload(options);
// Display welcome message in the notification area
$('#uploader').plupload('notify', 'info', "This might be obvious, but you need to click 'Add Files' to add some files.");
@example
// Subscribing to the events...
// ... on initialization:
$('#uploader').plupload({
...
viewchanged: function(event, args) {
// stuff ...
}
});
// ... or after initialization
$('#uploader').on("viewchanged", function(event, args) {
// stuff ...
});
@class UI.Plupload
@constructor
@param {Object} settings For detailed information about each option check documentation.
@param {String} settings.url URL of the server-side upload handler.
@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
@param {Object} [settings.filters={}] Set of file type filters.
@param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
@param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {Number} [settings.filters.max_file_count=0] Limit the number of files that can reside in the queue at the same time (default is 0 - no limit).
@param {String} [settings.flash_swf_url] URL of the Flash swf.
@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
@param {Number} [settings.resize.width] If image is bigger, it will be resized.
@param {Number} [settings.resize.height] If image is bigger, it will be resized.
@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
@param {Boolean} [settings.autostart=false] Whether to auto start uploading right after file selection.
@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
@param {Boolean} [settings.sortable=false] Enable ability to sort files in the queue, changing their uploading priority.
@param {Object} [settings.buttons] Control the visibility of functional buttons.
@param {Boolean} [settings.buttons.browse=true] Display browse button.
@param {Boolean} [settings.buttons.start=true] Display start button.
@param {Boolean} [settings.buttons.stop=true] Display stop button.
@param {Object} [settings.views] Control various views of the file queue.
@param {Boolean} [settings.views.list=true] Enable list view.
@param {Boolean} [settings.views.thumbs=false] Enable thumbs view.
@param {String} [settings.views.default='list'] Default view.
@param {Boolean} [settings.views.remember=true] Whether to remember the current view (requires jQuery Cookie plugin).
@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
*/
;(function(window, document, plupload, o, $) {
/**
Dispatched when the widget is initialized and ready.
@event ready
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Dispatched when file dialog is closed.
@event selected
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of selected files represented by plupload.File objects
*/
/**
Dispatched when file dialog is closed.
@event removed
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of removed files represented by plupload.File objects
*/
/**
Dispatched when upload is started.
@event started
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Dispatched when upload is stopped.
@event stopped
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Dispatched during the upload process.
@event progress
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that is being uploaded (includes loaded and percent properties among others).
@param {Number} size Total file size in bytes.
@param {Number} loaded Number of bytes uploaded of the files total size.
@param {Number} percent Number of percentage uploaded of the file.
*/
/**
Dispatched when file is uploaded.
@event uploaded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that was uploaded.
@param {Enum} status Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
*/
/**
Dispatched when upload of the whole queue is complete.
@event complete
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of uploaded files represented by plupload.File objects
*/
/**
Dispatched when the view is changed, e.g. from `list` to `thumbs` or vice versa.
@event viewchanged
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {String} type Current view type.
*/
/**
Dispatched when error of some kind is detected.
@event error
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {String} error Error message.
@param {plupload.File} file File that was uploaded.
@param {Enum} status Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
*/
var uploaders = {};
function _(str) {
return plupload.translate(str) || str;
}
function renderUI(obj) {
obj.id = obj.attr('id');
obj.html(
'<div class="plupload_wrapper">' +
'<div class="ui-widget-content plupload_container">' +
'<div class="ui-state-default ui-widget-header plupload_header">' +
'<div class="plupload_header_content">' +
'<div class="plupload_logo"> </div>' +
'<div class="plupload_header_title">' + _("Select files") + '</div>' +
'<div class="plupload_header_text">' + _("Add files to the upload queue and click the start button.") + '</div>' +
'<div class="plupload_view_switch">' +
'<input type="radio" id="'+obj.id+'_view_list" name="view_mode_'+obj.id+'" checked="checked" /><label class="plupload_button" for="'+obj.id+'_view_list" data-view="list">' + _('List') + '</label>' +
'<input type="radio" id="'+obj.id+'_view_thumbs" name="view_mode_'+obj.id+'" /><label class="plupload_button" for="'+obj.id+'_view_thumbs" data-view="thumbs">' + _('Thumbnails') + '</label>' +
'</div>' +
'</div>' +
'</div>' +
'<table class="plupload_filelist plupload_filelist_header ui-widget-header">' +
'<tr>' +
'<td class="plupload_cell plupload_file_name">' + _('Filename') + '</td>' +
'<td class="plupload_cell plupload_file_status">' + _('Status') + '</td>' +
'<td class="plupload_cell plupload_file_size">' + _('Size') + '</td>' +
'<td class="plupload_cell plupload_file_action">&nbsp;</td>' +
'</tr>' +
'</table>' +
'<div class="plupload_content">' +
'<div class="plupload_droptext">' + _("Drag files here.") + '</div>' +
'<ul class="plupload_filelist_content"> </ul>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'<table class="plupload_filelist plupload_filelist_footer ui-widget-header">' +
'<tr>' +
'<td class="plupload_cell plupload_file_name">' +
'<div class="plupload_buttons"><!-- Visible -->' +
'<a class="plupload_button plupload_add">' + _("Add Files") + '</a>&nbsp;' +
'<a class="plupload_button plupload_start">' + _("Start Upload") + '</a>&nbsp;' +
'<a class="plupload_button plupload_stop plupload_hidden">'+_("Stop Upload") + '</a>&nbsp;' +
'</div>' +
'<div class="plupload_started plupload_hidden"><!-- Hidden -->' +
'<div class="plupload_progress plupload_right">' +
'<div class="plupload_progress_container"></div>' +
'</div>' +
'<div class="plupload_cell plupload_upload_status"></div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'</td>' +
'<td class="plupload_file_status"><span class="plupload_total_status">0%</span></td>' +
'<td class="plupload_file_size"><span class="plupload_total_file_size">0 kb</span></td>' +
'<td class="plupload_file_action"></td>' +
'</tr>' +
'</table>' +
'</div>' +
'<input class="plupload_count" value="0" type="hidden">' +
'</div>'
);
}
$.widget("ui.plupload", {
widgetEventPrefix: '',
contents_bak: '',
options: {
browse_button_hover: 'ui-state-hover',
browse_button_active: 'ui-state-active',
filters: {},
// widget specific
buttons: {
browse: true,
start: true,
stop: true
},
views: {
list: true,
thumbs: false,
active: 'list',
remember: true // requires: https://github.com/carhartl/jquery-cookie, otherwise disabled even if set to true
},
thumb_width: 100,
thumb_height: 60,
multiple_queues: true, // re-use widget by default
dragdrop : true,
autostart: false,
sortable: false,
rename: false
},
FILE_COUNT_ERROR: -9001,
_create: function() {
var id = this.element.attr('id');
if (!id) {
id = plupload.guid();
this.element.attr('id', id);
}
this.id = id;
// backup the elements initial state
this.contents_bak = this.element.html();
renderUI(this.element);
// container, just in case
this.container = $('.plupload_container', this.element).attr('id', id + '_container');
this.content = $('.plupload_content', this.element);
if ($.fn.resizable) {
this.container.resizable({
handles: 's',
minHeight: 300
});
}
// list of files, may become sortable
this.filelist = $('.plupload_filelist_content', this.container)
.attr({
id: id + '_filelist',
unselectable: 'on'
});
// buttons
this.browse_button = $('.plupload_add', this.container).attr('id', id + '_browse');
this.start_button = $('.plupload_start', this.container).attr('id', id + '_start');
this.stop_button = $('.plupload_stop', this.container).attr('id', id + '_stop');
this.thumbs_switcher = $('#' + id + '_view_thumbs');
this.list_switcher = $('#' + id + '_view_list');
if ($.ui.button) {
this.browse_button.button({
icons: { primary: 'ui-icon-circle-plus' },
disabled: true
});
this.start_button.button({
icons: { primary: 'ui-icon-circle-arrow-e' },
disabled: true
});
this.stop_button.button({
icons: { primary: 'ui-icon-circle-close' }
});
this.list_switcher.button({
text: false,
icons: { secondary: "ui-icon-grip-dotted-horizontal" }
});
this.thumbs_switcher.button({
text: false,
icons: { secondary: "ui-icon-image" }
});
}
// progressbar
this.progressbar = $('.plupload_progress_container', this.container);
if ($.ui.progressbar) {
this.progressbar.progressbar();
}
// counter
this.counter = $('.plupload_count', this.element)
.attr({
id: id + '_count',
name: id + '_count'
});
// initialize uploader instance
this._initUploader();
},
_initUploader: function() {
var self = this
, id = this.id
, uploader
, options = {
container: id + '_buttons',
browse_button: id + '_browse'
}
;
$('.plupload_buttons', this.element).attr('id', id + '_buttons');
if (self.options.dragdrop) {
this.filelist.parent().attr('id', this.id + '_dropbox');
options.drop_element = this.id + '_dropbox';
}
this.filelist.on('click', function(e) {
if ($(e.target).hasClass('plupload_action_icon')) {
self.removeFile($(e.target).closest('.plupload_file').attr('id'));
e.preventDefault();
}
});
uploader = this.uploader = uploaders[id] = new plupload.Uploader($.extend(this.options, options));
// retrieve full normalized set of options
this.options = uploader.getOption();
if (self.options.views.thumbs) {
uploader.settings.required_features.display_media = true;
}
// for backward compatibility
if (self.options.max_file_count) {
plupload.extend(uploader.getOption('filters'), {
max_file_count: self.options.max_file_count
});
}
plupload.addFileFilter('max_file_count', function(maxCount, file, cb) {
if (maxCount <= this.files.length - (this.total.uploaded + this.total.failed)) {
self.browse_button.button('disable');
this.disableBrowse();
this.trigger('Error', {
code : self.FILE_COUNT_ERROR,
message : _("File count error."),
file : file
});
cb(false);
} else {
cb(true);
}
});
uploader.bind('Error', function(up, err) {
var message, details = "";
message = '<strong>' + err.message + '</strong>';
switch (err.code) {
case plupload.FILE_EXTENSION_ERROR:
details = o.sprintf(_("File: %s"), err.file.name);
break;
case plupload.FILE_SIZE_ERROR:
details = o.sprintf(_("File: %s, size: %d, max file size: %d"), err.file.name, plupload.formatSize(err.file.size), plupload.formatSize(plupload.parseSize(up.getOption('filters').max_file_size)));
break;
case plupload.FILE_DUPLICATE_ERROR:
details = o.sprintf(_("%s already present in the queue."), err.file.name);
break;
case self.FILE_COUNT_ERROR:
details = o.sprintf(_("Upload element accepts only %d file(s) at a time. Extra files were stripped."), up.getOption('filters').max_file_count || 0);
break;
case plupload.IMAGE_FORMAT_ERROR :
details = _("Image format either wrong or not supported.");
break;
case plupload.IMAGE_MEMORY_ERROR :
details = _("Runtime ran out of available memory.");
break;
/* // This needs a review
case plupload.IMAGE_DIMENSIONS_ERROR :
details = o.sprintf(_('Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.'), up.runtime, up.features.maxWidth, up.features.maxHeight);
break; */
case plupload.HTTP_ERROR:
details = _("Upload URL might be wrong or doesn't exist.");
break;
}
message += " <br /><i>" + details + "</i>";
self._trigger('error', null, { up: up, error: err } );
// do not show UI if no runtime can be initialized
if (err.code === plupload.INIT_ERROR) {
setTimeout(function() {
self.destroy();
}, 1);
} else {
self.notify('error', message);
}
});
uploader.bind('PostInit', function(up) {
// all buttons are optional, so they can be disabled and hidden
if (!self.options.buttons.browse) {
self.browse_button.button('disable').hide();
up.disableBrowse(true);
} else {
self.browse_button.button('enable');
}
if (!self.options.buttons.start) {
self.start_button.button('disable').hide();
}
if (!self.options.buttons.stop) {
self.stop_button.button('disable').hide();
}
if (!self.options.unique_names && self.options.rename) {
self._enableRenaming();
}
if (self.options.dragdrop && up.features.dragdrop) {
self.filelist.parent().addClass('plupload_dropbox');
}
self._enableViewSwitcher();
self.start_button.click(function(e) {
if (!$(this).button('option', 'disabled')) {
self.start();
}
e.preventDefault();
});
self.stop_button.click(function(e) {
self.stop();
e.preventDefault();
});
self._trigger('ready', null, { up: up });
});
// uploader internal events must run first
uploader.init();
uploader.bind('FileFiltered', function(up, file) {
self._addFiles(file);
});
uploader.bind('FilesAdded', function(up, files) {
self._trigger('selected', null, { up: up, files: files } );
// re-enable sortable
if (self.options.sortable && $.ui.sortable) {
self._enableSortingList();
}
self._trigger('updatelist', null, { filelist: self.filelist });
if (self.options.autostart) {
// set a little delay to make sure that QueueChanged triggered by the core has time to complete
setTimeout(function() {
self.start();
}, 10);
}
});
uploader.bind('FilesRemoved', function(up, files) {
// destroy sortable if enabled
if ($.ui.sortable && self.options.sortable) {
$('tbody', self.filelist).sortable('destroy');
}
$.each(files, function(i, file) {
$('#' + file.id).toggle("highlight", function() {
$(this).remove();
});
});
if (up.files.length) {
// re-initialize sortable
if (self.options.sortable && $.ui.sortable) {
self._enableSortingList();
}
}
self._trigger('updatelist', null, { filelist: self.filelist });
self._trigger('removed', null, { up: up, files: files } );
});
uploader.bind('QueueChanged', function() {
self._handleState();
});
uploader.bind('StateChanged', function(up) {
self._handleState();
if (plupload.STARTED === up.state) {
self._trigger('started', null, { up: this.uploader });
} else if (plupload.STOPPED === up.state) {
self._trigger('stopped', null, { up: this.uploader });
}
});
uploader.bind('UploadFile', function(up, file) {
self._handleFileStatus(file);
});
uploader.bind('FileUploaded', function(up, file, result) {
self._handleFileStatus(file);
self._trigger('uploaded', null, { up: up, file: file, result: result } );
});
uploader.bind('UploadProgress', function(up, file) {
self._handleFileStatus(file);
self._updateTotalProgress();
self._trigger('progress', null, { up: up, file: file } );
});
uploader.bind('UploadComplete', function(up, files) {
self._addFormFields();
self._trigger('complete', null, { up: up, files: files } );
});
},
_setOption: function(key, value) {
var self = this;
if (key == 'buttons' && typeof(value) == 'object') {
value = $.extend(self.options.buttons, value);
if (!value.browse) {
self.browse_button.button('disable').hide();
self.uploader.disableBrowse(true);
} else {
self.browse_button.button('enable').show();
self.uploader.disableBrowse(false);
}
if (!value.start) {
self.start_button.button('disable').hide();
} else {
self.start_button.button('enable').show();
}
if (!value.stop) {
self.stop_button.button('disable').hide();
} else {
self.start_button.button('enable').show();
}
}
self.uploader.setOption(key, value);
},
/**
Start upload. Triggers `start` event.
@method start
*/
start: function() {
this.uploader.start();
},
/**
Stop upload. Triggers `stop` event.
@method stop
*/
stop: function() {
this.uploader.stop();
},
/**
Enable browse button.
@method enable
*/
enable: function() {
this.browse_button.button('enable');
this.uploader.disableBrowse(false);
},
/**
Disable browse button.
@method disable
*/
disable: function() {
this.browse_button.button('disable');
this.uploader.disableBrowse(true);
},
/**
Retrieve file by its unique id.
@method getFile
@param {String} id Unique id of the file
@return {plupload.File}
*/
getFile: function(id) {
var file;
if (typeof id === 'number') {
file = this.uploader.files[id];
} else {
file = this.uploader.getFile(id);
}
return file;
},
/**
Return array of files currently in the queue.
@method getFiles
@return {Array} Array of files in the queue represented by plupload.File objects
*/
getFiles: function() {
return this.uploader.files;
},
/**
Remove the file from the queue.
@method removeFile
@param {plupload.File|String} file File to remove, might be specified directly or by its unique id
*/
removeFile: function(file) {
if (plupload.typeOf(file) === 'string') {
file = this.getFile(file);
}
this.uploader.removeFile(file);
},
/**
Clear the file queue.
@method clearQueue
*/
clearQueue: function() {
this.uploader.splice();
},
/**
Retrieve internal plupload.Uploader object (usually not required).
@method getUploader
@return {plupload.Uploader}
*/
getUploader: function() {
return this.uploader;
},
/**
Trigger refresh procedure, specifically browse_button re-measure and re-position operations.
Might get handy, when UI Widget is placed within the popup, that is constantly hidden and shown
again - without calling this method after each show operation, dialog trigger might get displaced
and disfunctional.
@method refresh
*/
refresh: function() {
this.uploader.refresh();
},
/**
Display a message in notification area.
@method notify
@param {Enum} type Type of the message, either `error` or `info`
@param {String} message The text message to display.
*/
notify: function(type, message) {
var popup = $(
'<div class="plupload_message">' +
'<span class="plupload_message_close ui-icon ui-icon-circle-close" title="'+_('Close')+'"></span>' +
'<p><span class="ui-icon"></span>' + message + '</p>' +
'</div>'
);
popup
.addClass('ui-state-' + (type === 'error' ? 'error' : 'highlight'))
.find('p .ui-icon')
.addClass('ui-icon-' + (type === 'error' ? 'alert' : 'info'))
.end()
.find('.plupload_message_close')
.click(function() {
popup.remove();
})
.end();
$('.plupload_header', this.container).append(popup);
},
/**
Destroy the widget, the uploader, free associated resources and bring back original html.
@method destroy
*/
destroy: function() {
// destroy uploader instance
this.uploader.destroy();
// unbind all button events
$('.plupload_button', this.element).unbind();
// destroy buttons
if ($.ui.button) {
$('.plupload_add, .plupload_start, .plupload_stop', this.container)
.button('destroy');
}
// destroy progressbar
if ($.ui.progressbar) {
this.progressbar.progressbar('destroy');
}
// destroy sortable behavior
if ($.ui.sortable && this.options.sortable) {
$('tbody', this.filelist).sortable('destroy');
}
// restore the elements initial state
this.element
.empty()
.html(this.contents_bak);
this.contents_bak = '';
$.Widget.prototype.destroy.apply(this);
},
_handleState: function() {
var up = this.uploader
, filesPending = up.files.length - (up.total.uploaded + up.total.failed)
, maxCount = up.getOption('filters').max_file_count || 0
;
if (plupload.STARTED === up.state) {
$([])
.add(this.stop_button)
.add('.plupload_started')
.removeClass('plupload_hidden');
this.start_button.button('disable');
if (!this.options.multiple_queues) {
this.browse_button.button('disable');
up.disableBrowse();
}
$('.plupload_upload_status', this.element).html(o.sprintf(_('Uploaded %d/%d files'), up.total.uploaded, up.files.length));
$('.plupload_header_content', this.element).addClass('plupload_header_content_bw');
}
else if (plupload.STOPPED === up.state) {
$([])
.add(this.stop_button)
.add('.plupload_started')
.addClass('plupload_hidden');
if (filesPending) {
this.start_button.button('enable');
} else {
this.start_button.button('disable');
}
if (this.options.multiple_queues) {
$('.plupload_header_content', this.element).removeClass('plupload_header_content_bw');
}
// if max_file_count defined, only that many files can be queued at once
if (this.options.multiple_queues && maxCount && maxCount > filesPending) {
this.browse_button.button('enable');
up.disableBrowse(false);
}
this._updateTotalProgress();
}
if (up.total.queued === 0) {
$('.ui-button-text', this.browse_button).html(_('Add Files'));
} else {
$('.ui-button-text', this.browse_button).html(o.sprintf(_('%d files queued'), up.total.queued));
}
up.refresh();
},
_handleFileStatus: function(file) {
var $file = $('#' + file.id), actionClass, iconClass;
// since this method might be called asynchronously, file row might not yet be rendered
if (!$file.length) {
return;
}
switch (file.status) {
case plupload.DONE:
actionClass = 'plupload_done';
iconClass = 'plupload_action_icon ui-icon ui-icon-circle-check';
break;
case plupload.FAILED:
actionClass = 'ui-state-error plupload_failed';
iconClass = 'plupload_action_icon ui-icon ui-icon-alert';
break;
case plupload.QUEUED:
actionClass = 'plupload_delete';
iconClass = 'plupload_action_icon ui-icon ui-icon-circle-minus';
break;
case plupload.UPLOADING:
actionClass = 'ui-state-highlight plupload_uploading';
iconClass = 'plupload_action_icon ui-icon ui-icon-circle-arrow-w';
// scroll uploading file into the view if its bottom boundary is out of it
var scroller = $('.plupload_scroll', this.container)
, scrollTop = scroller.scrollTop()
, scrollerHeight = scroller.height()
, rowOffset = $file.position().top + $file.height()
;
if (scrollerHeight < rowOffset) {
scroller.scrollTop(scrollTop + rowOffset - scrollerHeight);
}
// Set file specific progress
$file
.find('.plupload_file_percent')
.html(file.percent + '%')
.end()
.find('.plupload_file_progress')
.css('width', file.percent + '%')
.end()
.find('.plupload_file_size')
.html(plupload.formatSize(file.size));
break;
}
actionClass += ' ui-state-default plupload_file';
$file
.attr('class', actionClass)
.find('.plupload_action_icon')
.attr('class', iconClass);
},
_updateTotalProgress: function() {
var up = this.uploader;
// Scroll to end of file list
this.filelist[0].scrollTop = this.filelist[0].scrollHeight;
this.progressbar.progressbar('value', up.total.percent);
this.element
.find('.plupload_total_status')
.html(up.total.percent + '%')
.end()
.find('.plupload_total_file_size')
.html(plupload.formatSize(up.total.size))
.end()
.find('.plupload_upload_status')
.html(o.sprintf(_('Uploaded %d/%d files'), up.total.uploaded, up.files.length));
},
_displayThumbs: function() {
var self = this
, tw, th // thumb width/height
, cols
, num = 0 // number of simultaneously visible thumbs
, thumbs = [] // array of thumbs to preload at any given moment
, loading = false
;
if (!this.options.views.thumbs) {
return;
}
function onLast(el, eventName, cb) {
var timer;
el.on(eventName, function() {
clearTimeout(timer);
timer = setTimeout(function() {
clearTimeout(timer);
cb();
}, 300);
});
}
// calculate number of simultaneously visible thumbs
function measure() {
if (!tw || !th) {
var wrapper = $('.plupload_file:eq(0)', self.filelist);
tw = wrapper.outerWidth(true);
th = wrapper.outerHeight(true);
}
var aw = self.content.width(), ah = self.content.height();
cols = Math.floor(aw / tw);
num = cols * (Math.ceil(ah / th) + 1);
}
function pickThumbsToLoad() {
// calculate index of virst visible thumb
var startIdx = Math.floor(self.content.scrollTop() / th) * cols;
// get potentially visible thumbs that are not yet visible
thumbs = $('.plupload_file .plupload_file_thumb', self.filelist)
.slice(startIdx, startIdx + num)
.filter('.plupload_thumb_toload')
.get();
}
function init() {
function mpl() { // measure, pick, load
if (self.view_mode !== 'thumbs') {
return;
}
measure();
pickThumbsToLoad();
lazyLoad();
}
if ($.fn.resizable) {
onLast(self.container, 'resize', mpl);
}
onLast(self.window, 'resize', mpl);
onLast(self.content, 'scroll', mpl);
self.element.on('viewchanged selected', mpl);
mpl();
}
function preloadThumb(file, cb) {
var img = new o.Image();
img.onload = function() {
var thumb = $('#' + file.id + ' .plupload_file_thumb', self.filelist);
this.embed(thumb[0], {
width: self.options.thumb_width,
height: self.options.thumb_height,
crop: true,
preserveHeaders: false,
swf_url: o.resolveUrl(self.options.flash_swf_url),
xap_url: o.resolveUrl(self.options.silverlight_xap_url)
});
};
img.bind("embedded error", function(e) {
$('#' + file.id, self.filelist)
.find('.plupload_file_thumb')
.removeClass('plupload_thumb_loading')
.addClass('plupload_thumb_' + e.type)
;
this.destroy();
setTimeout(cb, 1); // detach, otherwise ui might hang (in SilverLight for example)
});
$('#' + file.id, self.filelist)
.find('.plupload_file_thumb')
.removeClass('plupload_thumb_toload')
.addClass('plupload_thumb_loading')
;
img.load(file.getSource());
}
function lazyLoad() {
if (self.view_mode !== 'thumbs' || loading) {
return;
}
pickThumbsToLoad();
if (!thumbs.length) {
return;
}
loading = true;
preloadThumb(self.getFile($(thumbs.shift()).closest('.plupload_file').attr('id')), function() {
loading = false;
lazyLoad();
});
}
// this has to run only once to measure structures and bind listeners
this.element.on('selected', function onselected() {
self.element.off('selected', onselected);
init();
});
},
_addFiles: function(files) {
var self = this, file_html, html = '';
file_html = '<li class="plupload_file ui-state-default plupload_delete" id="{id}" style="width:{thumb_width}px;">' +
'<div class="plupload_file_thumb plupload_thumb_toload" style="width: {thumb_width}px; height: {thumb_height}px;">' +
'<div class="plupload_file_dummy ui-widget-content" style="line-height: {thumb_height}px;"><span class="ui-state-disabled">{ext} </span></div>' +
'</div>' +
'<div class="plupload_file_status">' +
'<div class="plupload_file_progress ui-widget-header" style="width: 0%"> </div>' +
'<span class="plupload_file_percent">{percent} </span>' +
'</div>' +
'<div class="plupload_file_name" title="{name}">' +
'<span class="plupload_file_name_wrapper">{name} </span>' +
'</div>' +
'<div class="plupload_file_action">' +
'<div class="plupload_action_icon ui-icon ui-icon-circle-minus"> </div>' +
'</div>' +
'<div class="plupload_file_size">{size} </div>' +
'<div class="plupload_file_fields"> </div>' +
'</li>';
if (plupload.typeOf(files) !== 'array') {
files = [files];
}
$.each(files, function(i, file) {
var ext = o.Mime.getFileExtension(file.name) || 'none';
html += file_html.replace(/\{(\w+)\}/g, function($0, $1) {
switch ($1) {
case 'thumb_width':
case 'thumb_height':
return self.options[$1];
case 'size':
return plupload.formatSize(file.size);
case 'ext':
return ext;
default:
return file[$1] || '';
}
});
});
self.filelist.append(html);
},
_addFormFields: function() {
var self = this;
// re-add from fresh
$('.plupload_file_fields', this.filelist).html('');
plupload.each(this.uploader.files, function(file, count) {
var fields = ''
, id = self.id + '_' + count
;
if (file.target_name) {
fields += '<input type="hidden" name="' + id + '_tmpname" value="'+plupload.xmlEncode(file.target_name)+'" />';
}
fields += '<input type="hidden" name="' + id + '_name" value="'+plupload.xmlEncode(file.name)+'" />';
fields += '<input type="hidden" name="' + id + '_status" value="' + (file.status === plupload.DONE ? 'done' : 'failed') + '" />';
$('#' + file.id).find('.plupload_file_fields').html(fields);
});
this.counter.val(this.uploader.files.length);
},
_viewChanged: function(view) {
// update or write a new cookie
if (this.options.views.remember && $.cookie) {
$.cookie('plupload_ui_view', view, { expires: 7, path: '/' });
}
// ugly fix for IE6 - make content area stretchable
if (o.Env.browser === 'IE' && o.Env.version < 7) {
this.content.attr('style', 'height:expression(document.getElementById("' + this.id + '_container' + '").clientHeight - ' + (view === 'list' ? 132 : 102) + ')');
}
this.container.removeClass('plupload_view_list plupload_view_thumbs').addClass('plupload_view_' + view);
this.view_mode = view;
this._trigger('viewchanged', null, { view: view });
},
_enableViewSwitcher: function() {
var self = this
, view
, switcher = $('.plupload_view_switch', this.container)
, buttons
, button
;
plupload.each(['list', 'thumbs'], function(view) {
if (!self.options.views[view]) {
switcher.find('[for="' + self.id + '_view_' + view + '"], #'+ self.id +'_view_' + view).remove();
}
});
// check if any visible left
buttons = switcher.find('.plupload_button');
if (buttons.length === 1) {
switcher.hide();
view = buttons.eq(0).data('view');
this._viewChanged(view);
} else if ($.ui.button && buttons.length > 1) {
if (this.options.views.remember && $.cookie) {
view = $.cookie('plupload_ui_view');
}
// if wierd case, bail out to default
if (!~plupload.inArray(view, ['list', 'thumbs'])) {
view = this.options.views.active;
}
switcher
.show()
.buttonset()
.find('.ui-button')
.click(function(e) {
view = $(this).data('view');
self._viewChanged(view);
e.preventDefault(); // avoid auto scrolling to widget in IE and FF (see #850)
});
// if view not active - happens when switcher wasn't clicked manually
button = switcher.find('[for="' + self.id + '_view_'+view+'"]');
if (button.length) {
button.trigger('click');
}
} else {
switcher.show();
this._viewChanged(this.options.views.active);
}
// initialize thumb viewer if requested
if (this.options.views.thumbs) {
this._displayThumbs();
}
},
_enableRenaming: function() {
var self = this;
this.filelist.dblclick(function(e) {
var nameSpan = $(e.target), nameInput, file, parts, name, ext = "";
if (!nameSpan.hasClass('plupload_file_name_wrapper')) {
return;
}
// Get file name and split out name and extension
file = self.uploader.getFile(nameSpan.closest('.plupload_file')[0].id);
name = file.name;
parts = /^(.+)(\.[^.]+)$/.exec(name);
if (parts) {
name = parts[1];
ext = parts[2];
}
// Display input element
nameInput = $('<input class="plupload_file_rename" type="text" />').width(nameSpan.width()).insertAfter(nameSpan.hide());
nameInput.val(name).blur(function() {
nameSpan.show().parent().scrollLeft(0).end().next().remove();
}).keydown(function(e) {
var nameInput = $(this);
if ($.inArray(e.keyCode, [13, 27]) !== -1) {
e.preventDefault();
// Rename file and glue extension back on
if (e.keyCode === 13) {
file.name = nameInput.val() + ext;
nameSpan.html(file.name);
}
nameInput.blur();
}
})[0].focus();
});
},
_enableSortingList: function() {
var self = this;
if ($('.plupload_file', this.filelist).length < 2) {
return;
}
// destroy sortable if enabled
$('tbody', this.filelist).sortable('destroy');
// enable
this.filelist.sortable({
items: '.plupload_delete',
cancel: 'object, .plupload_clearer',
stop: function() {
var files = [];
$.each($(this).sortable('toArray'), function(i, id) {
files[files.length] = self.uploader.getFile(id);
});
files.unshift(files.length);
files.unshift(0);
// re-populate files array
Array.prototype.splice.apply(self.uploader.files, files);
}
});
}
});
} (window, document, plupload, mOxie, jQuery));
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* Plupload - multi-runtime File Uploader
* v2.1.8
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Date: 2015-07-21
*/
/**
* Plupload.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/*global mOxie:true */
;(function(window, o, undef) {
var delay = window.setTimeout
, fileFilters = {}
;
// convert plupload features to caps acceptable by mOxie
function normalizeCaps(settings) {
var features = settings.required_features, caps = {};
function resolve(feature, value, strict) {
// Feature notation is deprecated, use caps (this thing here is required for backward compatibility)
var map = {
chunks: 'slice_blob',
jpgresize: 'send_binary_string',
pngresize: 'send_binary_string',
progress: 'report_upload_progress',
multi_selection: 'select_multiple',
dragdrop: 'drag_and_drop',
drop_element: 'drag_and_drop',
headers: 'send_custom_headers',
urlstream_upload: 'send_binary_string',
canSendBinary: 'send_binary',
triggerDialog: 'summon_file_dialog'
};
if (map[feature]) {
caps[map[feature]] = value;
} else if (!strict) {
caps[feature] = value;
}
}
if (typeof(features) === 'string') {
plupload.each(features.split(/\s*,\s*/), function(feature) {
resolve(feature, true);
});
} else if (typeof(features) === 'object') {
plupload.each(features, function(value, feature) {
resolve(feature, value);
});
} else if (features === true) {
// check settings for required features
if (settings.chunk_size > 0) {
caps.slice_blob = true;
}
if (settings.resize.enabled || !settings.multipart) {
caps.send_binary_string = true;
}
plupload.each(settings, function(value, feature) {
resolve(feature, !!value, true); // strict check
});
}
return caps;
}
/**
* @module plupload
* @static
*/
var plupload = {
/**
* Plupload version will be replaced on build.
*
* @property VERSION
* @for Plupload
* @static
* @final
*/
VERSION : '2.1.8',
/**
* The state of the queue before it has started and after it has finished
*
* @property STOPPED
* @static
* @final
*/
STOPPED : 1,
/**
* Upload process is running
*
* @property STARTED
* @static
* @final
*/
STARTED : 2,
/**
* File is queued for upload
*
* @property QUEUED
* @static
* @final
*/
QUEUED : 1,
/**
* File is being uploaded
*
* @property UPLOADING
* @static
* @final
*/
UPLOADING : 2,
/**
* File has failed to be uploaded
*
* @property FAILED
* @static
* @final
*/
FAILED : 4,
/**
* File has been uploaded successfully
*
* @property DONE
* @static
* @final
*/
DONE : 5,
// Error constants used by the Error event
/**
* Generic error for example if an exception is thrown inside Silverlight.
*
* @property GENERIC_ERROR
* @static
* @final
*/
GENERIC_ERROR : -100,
/**
* HTTP transport error. For example if the server produces a HTTP status other than 200.
*
* @property HTTP_ERROR
* @static
* @final
*/
HTTP_ERROR : -200,
/**
* Generic I/O error. For example if it wasn't possible to open the file stream on local machine.
*
* @property IO_ERROR
* @static
* @final
*/
IO_ERROR : -300,
/**
* @property SECURITY_ERROR
* @static
* @final
*/
SECURITY_ERROR : -400,
/**
* Initialization error. Will be triggered if no runtime was initialized.
*
* @property INIT_ERROR
* @static
* @final
*/
INIT_ERROR : -500,
/**
* File size error. If the user selects a file that is too large it will be blocked and an error of this type will be triggered.
*
* @property FILE_SIZE_ERROR
* @static
* @final
*/
FILE_SIZE_ERROR : -600,
/**
* File extension error. If the user selects a file that isn't valid according to the filters setting.
*
* @property FILE_EXTENSION_ERROR
* @static
* @final
*/
FILE_EXTENSION_ERROR : -601,
/**
* Duplicate file error. If prevent_duplicates is set to true and user selects the same file again.
*
* @property FILE_DUPLICATE_ERROR
* @static
* @final
*/
FILE_DUPLICATE_ERROR : -602,
/**
* Runtime will try to detect if image is proper one. Otherwise will throw this error.
*
* @property IMAGE_FORMAT_ERROR
* @static
* @final
*/
IMAGE_FORMAT_ERROR : -700,
/**
* While working on files runtime may run out of memory and will throw this error.
*
* @since 2.1.2
* @property MEMORY_ERROR
* @static
* @final
*/
MEMORY_ERROR : -701,
/**
* Each runtime has an upper limit on a dimension of the image it can handle. If bigger, will throw this error.
*
* @property IMAGE_DIMENSIONS_ERROR
* @static
* @final
*/
IMAGE_DIMENSIONS_ERROR : -702,
/**
* Mime type lookup table.
*
* @property mimeTypes
* @type Object
* @final
*/
mimeTypes : o.mimes,
/**
* In some cases sniffing is the only way around :(
*/
ua: o.ua,
/**
* Gets the true type of the built-in object (better version of typeof).
* @credits Angus Croll (http://javascriptweblog.wordpress.com/)
*
* @method typeOf
* @static
* @param {Object} o Object to check.
* @return {String} Object [[Class]]
*/
typeOf: o.typeOf,
/**
* Extends the specified object with another object.
*
* @method extend
* @static
* @param {Object} target Object to extend.
* @param {Object..} obj Multiple objects to extend with.
* @return {Object} Same as target, the extended object.
*/
extend : o.extend,
/**
* Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers.
* The only way a user would be able to get the same ID is if the two persons at the same exact millisecond manages
* to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique.
* It's more probable for the earth to be hit with an asteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property
* to an user unique key.
*
* @method guid
* @static
* @return {String} Virtually unique id.
*/
guid : o.guid,
/**
* Get array of DOM Elements by their ids.
*
* @method get
* @for Utils
* @param {String} id Identifier of the DOM Element
* @return {Array}
*/
get : function get(ids) {
var els = [], el;
if (o.typeOf(ids) !== 'array') {
ids = [ids];
}
var i = ids.length;
while (i--) {
el = o.get(ids[i]);
if (el) {
els.push(el);
}
}
return els.length ? els : null;
},
/**
* Executes the callback function for each item in array/object. If you return false in the
* callback it will break the loop.
*
* @method each
* @static
* @param {Object} obj Object to iterate.
* @param {function} callback Callback function to execute for each item.
*/
each : o.each,
/**
* Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields.
*
* @method getPos
* @static
* @param {Element} node HTML element or element id to get x, y position from.
* @param {Element} root Optional root element to stop calculations at.
* @return {object} Absolute position of the specified element object with x, y fields.
*/
getPos : o.getPos,
/**
* Returns the size of the specified node in pixels.
*
* @method getSize
* @static
* @param {Node} node Node to get the size of.
* @return {Object} Object with a w and h property.
*/
getSize : o.getSize,
/**
* Encodes the specified string.
*
* @method xmlEncode
* @static
* @param {String} s String to encode.
* @return {String} Encoded string.
*/
xmlEncode : function(str) {
var xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'}, xmlEncodeRegExp = /[<>&\"\']/g;
return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) {
return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr;
}) : str;
},
/**
* Forces anything into an array.
*
* @method toArray
* @static
* @param {Object} obj Object with length field.
* @return {Array} Array object containing all items.
*/
toArray : o.toArray,
/**
* Find an element in array and return its index if present, otherwise return -1.
*
* @method inArray
* @static
* @param {mixed} needle Element to find
* @param {Array} array
* @return {Int} Index of the element, or -1 if not found
*/
inArray : o.inArray,
/**
* Extends the language pack object with new items.
*
* @method addI18n
* @static
* @param {Object} pack Language pack items to add.
* @return {Object} Extended language pack object.
*/
addI18n : o.addI18n,
/**
* Translates the specified string by checking for the english string in the language pack lookup.
*
* @method translate
* @static
* @param {String} str String to look for.
* @return {String} Translated string or the input string if it wasn't found.
*/
translate : o.translate,
/**
* Checks if object is empty.
*
* @method isEmptyObj
* @static
* @param {Object} obj Object to check.
* @return {Boolean}
*/
isEmptyObj : o.isEmptyObj,
/**
* Checks if specified DOM element has specified class.
*
* @method hasClass
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Class name
*/
hasClass : o.hasClass,
/**
* Adds specified className to specified DOM element.
*
* @method addClass
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Class name
*/
addClass : o.addClass,
/**
* Removes specified className from specified DOM element.
*
* @method removeClass
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Class name
*/
removeClass : o.removeClass,
/**
* Returns a given computed style of a DOM element.
*
* @method getStyle
* @static
* @param {Object} obj DOM element like object.
* @param {String} name Style you want to get from the DOM element
*/
getStyle : o.getStyle,
/**
* Adds an event handler to the specified object and store reference to the handler
* in objects internal Plupload registry (@see removeEvent).
*
* @method addEvent
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Name to add event listener to.
* @param {Function} callback Function to call when event occurs.
* @param {String} (optional) key that might be used to add specifity to the event record.
*/
addEvent : o.addEvent,
/**
* Remove event handler from the specified object. If third argument (callback)
* is not specified remove all events with the specified name.
*
* @method removeEvent
* @static
* @param {Object} obj DOM element to remove event listener(s) from.
* @param {String} name Name of event listener to remove.
* @param {Function|String} (optional) might be a callback or unique key to match.
*/
removeEvent: o.removeEvent,
/**
* Remove all kind of events from the specified object
*
* @method removeAllEvents
* @static
* @param {Object} obj DOM element to remove event listeners from.
* @param {String} (optional) unique key to match, when removing events.
*/
removeAllEvents: o.removeAllEvents,
/**
* Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _.
*
* @method cleanName
* @static
* @param {String} s String to clean up.
* @return {String} Cleaned string.
*/
cleanName : function(name) {
var i, lookup;
// Replace diacritics
lookup = [
/[\300-\306]/g, 'A', /[\340-\346]/g, 'a',
/\307/g, 'C', /\347/g, 'c',
/[\310-\313]/g, 'E', /[\350-\353]/g, 'e',
/[\314-\317]/g, 'I', /[\354-\357]/g, 'i',
/\321/g, 'N', /\361/g, 'n',
/[\322-\330]/g, 'O', /[\362-\370]/g, 'o',
/[\331-\334]/g, 'U', /[\371-\374]/g, 'u'
];
for (i = 0; i < lookup.length; i += 2) {
name = name.replace(lookup[i], lookup[i + 1]);
}
// Replace whitespace
name = name.replace(/\s+/g, '_');
// Remove anything else
name = name.replace(/[^a-z0-9_\-\.]+/gi, '');
return name;
},
/**
* Builds a full url out of a base URL and an object with items to append as query string items.
*
* @method buildUrl
* @static
* @param {String} url Base URL to append query string items to.
* @param {Object} items Name/value object to serialize as a querystring.
* @return {String} String with url + serialized query string items.
*/
buildUrl : function(url, items) {
var query = '';
plupload.each(items, function(value, name) {
query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value);
});
if (query) {
url += (url.indexOf('?') > 0 ? '&' : '?') + query;
}
return url;
},
/**
* Formats the specified number as a size string for example 1024 becomes 1 KB.
*
* @method formatSize
* @static
* @param {Number} size Size to format as string.
* @return {String} Formatted size string.
*/
formatSize : function(size) {
if (size === undef || /\D/.test(size)) {
return plupload.translate('N/A');
}
function round(num, precision) {
return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision);
}
var boundary = Math.pow(1024, 4);
// TB
if (size > boundary) {
return round(size / boundary, 1) + " " + plupload.translate('tb');
}
// GB
if (size > (boundary/=1024)) {
return round(size / boundary, 1) + " " + plupload.translate('gb');
}
// MB
if (size > (boundary/=1024)) {
return round(size / boundary, 1) + " " + plupload.translate('mb');
}
// KB
if (size > 1024) {
return Math.round(size / 1024) + " " + plupload.translate('kb');
}
return size + " " + plupload.translate('b');
},
/**
* Parses the specified size string into a byte value. For example 10kb becomes 10240.
*
* @method parseSize
* @static
* @param {String|Number} size String to parse or number to just pass through.
* @return {Number} Size in bytes.
*/
parseSize : o.parseSizeStr,
/**
* A way to predict what runtime will be choosen in the current environment with the
* specified settings.
*
* @method predictRuntime
* @static
* @param {Object|String} config Plupload settings to check
* @param {String} [runtimes] Comma-separated list of runtimes to check against
* @return {String} Type of compatible runtime
*/
predictRuntime : function(config, runtimes) {
var up, runtime;
up = new plupload.Uploader(config);
runtime = o.Runtime.thatCan(up.getOption().required_features, runtimes || config.runtimes);
up.destroy();
return runtime;
},
/**
* Registers a filter that will be executed for each file added to the queue.
* If callback returns false, file will not be added.
*
* Callback receives two arguments: a value for the filter as it was specified in settings.filters
* and a file to be filtered. Callback is executed in the context of uploader instance.
*
* @method addFileFilter
* @static
* @param {String} name Name of the filter by which it can be referenced in settings.filters
* @param {String} cb Callback - the actual routine that every added file must pass
*/
addFileFilter: function(name, cb) {
fileFilters[name] = cb;
}
};
plupload.addFileFilter('mime_types', function(filters, file, cb) {
if (filters.length && !filters.regexp.test(file.name)) {
this.trigger('Error', {
code : plupload.FILE_EXTENSION_ERROR,
message : plupload.translate('File extension error.'),
file : file
});
cb(false);
} else {
cb(true);
}
});
plupload.addFileFilter('max_file_size', function(maxSize, file, cb) {
var undef;
maxSize = plupload.parseSize(maxSize);
// Invalid file size
if (file.size !== undef && maxSize && file.size > maxSize) {
this.trigger('Error', {
code : plupload.FILE_SIZE_ERROR,
message : plupload.translate('File size error.'),
file : file
});
cb(false);
} else {
cb(true);
}
});
plupload.addFileFilter('prevent_duplicates', function(value, file, cb) {
if (value) {
var ii = this.files.length;
while (ii--) {
// Compare by name and size (size might be 0 or undefined, but still equivalent for both)
if (file.name === this.files[ii].name && file.size === this.files[ii].size) {
this.trigger('Error', {
code : plupload.FILE_DUPLICATE_ERROR,
message : plupload.translate('Duplicate file error.'),
file : file
});
cb(false);
return;
}
}
}
cb(true);
});
/**
@class Uploader
@constructor
@param {Object} settings For detailed information about each option check documentation.
@param {String|DOMElement} settings.browse_button id of the DOM element or DOM element itself to use as file dialog trigger.
@param {String} settings.url URL of the server-side upload handler.
@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
@param {Boolean} [settings.send_chunk_number=true] Whether to send chunks and chunk numbers, or total and offset bytes.
@param {String|DOMElement} [settings.container] id of the DOM element or DOM element itself that will be used to wrap uploader structures. Defaults to immediate parent of the `browse_button` element.
@param {String|DOMElement} [settings.drop_element] id of the DOM element or DOM element itself to use as a drop zone for Drag-n-Drop.
@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
@param {Object} [settings.filters={}] Set of file type filters.
@param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
@param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {String} [settings.flash_swf_url] URL of the Flash swf.
@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
@param {Number} [settings.resize.width] If image is bigger, it will be resized.
@param {Number} [settings.resize.height] If image is bigger, it will be resized.
@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
@param {Boolean} [settings.send_file_name=true] Whether to send file name as additional argument - 'name' (required for chunked uploads and some other cases where file name cannot be sent via normal ways).
*/
plupload.Uploader = function(options) {
/**
Fires when the current RunTime has been initialized.
@event Init
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires after the init event incase you need to perform actions there.
@event PostInit
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires when the option is changed in via uploader.setOption().
@event OptionChanged
@since 2.1
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {String} name Name of the option that was changed
@param {Mixed} value New value for the specified option
@param {Mixed} oldValue Previous value of the option
*/
/**
Fires when the silverlight/flash or other shim needs to move.
@event Refresh
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires when the overall state is being changed for the upload queue.
@event StateChanged
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires when browse_button is clicked and browse dialog shows.
@event Browse
@since 2.1.2
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires for every filtered file before it is added to the queue.
@event FileFiltered
@since 2.1
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file Another file that has to be added to the queue.
*/
/**
Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance.
@event QueueChanged
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires after files were filtered and added to the queue.
@event FilesAdded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of file objects that were added to queue by the user.
*/
/**
Fires when file is removed from the queue.
@event FilesRemoved
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of files that got removed.
*/
/**
Fires just before a file is uploaded. Can be used to cancel the upload for the specified file
by returning false from the handler.
@event BeforeUpload
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File to be uploaded.
*/
/**
Fires when a file is to be uploaded by the runtime.
@event UploadFile
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File to be uploaded.
*/
/**
Fires while a file is being uploaded. Use this event to update the current file upload progress.
@event UploadProgress
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that is currently being uploaded.
*/
/**
Fires when file chunk is uploaded.
@event ChunkUploaded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that the chunk was uploaded for.
@param {Object} result Object with response properties.
@param {Number} result.offset The amount of bytes the server has received so far, including this chunk.
@param {Number} result.total The size of the file.
@param {String} result.response The response body sent by the server.
@param {Number} result.status The HTTP status code sent by the server.
@param {String} result.responseHeaders All the response headers as a single string.
*/
/**
Fires when a file is successfully uploaded.
@event FileUploaded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that was uploaded.
@param {Object} result Object with response properties.
@param {String} result.response The response body sent by the server.
@param {Number} result.status The HTTP status code sent by the server.
@param {String} result.responseHeaders All the response headers as a single string.
*/
/**
Fires when all files in a queue are uploaded.
@event UploadComplete
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of file objects that was added to queue/selected by the user.
*/
/**
Fires when a error occurs.
@event Error
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Object} error Contains code, message and sometimes file and other details.
@param {Number} error.code The plupload error code.
@param {String} error.message Description of the error (uses i18n).
*/
/**
Fires when destroy method is called.
@event Destroy
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
var uid = plupload.guid()
, settings
, files = []
, preferred_caps = {}
, fileInputs = []
, fileDrops = []
, startTime
, total
, disabled = false
, xhr
;
// Private methods
function uploadNext() {
var file, count = 0, i;
if (this.state == plupload.STARTED) {
// Find first QUEUED file
for (i = 0; i < files.length; i++) {
if (!file && files[i].status == plupload.QUEUED) {
file = files[i];
if (this.trigger("BeforeUpload", file)) {
file.status = plupload.UPLOADING;
this.trigger("UploadFile", file);
}
} else {
count++;
}
}
// All files are DONE or FAILED
if (count == files.length) {
if (this.state !== plupload.STOPPED) {
this.state = plupload.STOPPED;
this.trigger("StateChanged");
}
this.trigger("UploadComplete", files);
}
}
}
function calcFile(file) {
file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100;
calc();
}
function calc() {
var i, file;
// Reset stats
total.reset();
// Check status, size, loaded etc on all files
for (i = 0; i < files.length; i++) {
file = files[i];
if (file.size !== undef) {
// We calculate totals based on original file size
total.size += file.origSize;
// Since we cannot predict file size after resize, we do opposite and
// interpolate loaded amount to match magnitude of total
total.loaded += file.loaded * file.origSize / file.size;
} else {
total.size = undef;
}
if (file.status == plupload.DONE) {
total.uploaded++;
} else if (file.status == plupload.FAILED) {
total.failed++;
} else {
total.queued++;
}
}
// If we couldn't calculate a total file size then use the number of files to calc percent
if (total.size === undef) {
total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0;
} else {
total.bytesPerSec = Math.ceil(total.loaded / ((+new Date() - startTime || 1) / 1000.0));
total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0;
}
}
function getRUID() {
var ctrl = fileInputs[0] || fileDrops[0];
if (ctrl) {
return ctrl.getRuntime().uid;
}
return false;
}
function runtimeCan(file, cap) {
if (file.ruid) {
var info = o.Runtime.getInfo(file.ruid);
if (info) {
return info.can(cap);
}
}
return false;
}
function bindEventListeners() {
this.bind('FilesAdded FilesRemoved', function(up) {
up.trigger('QueueChanged');
up.refresh();
});
this.bind('CancelUpload', onCancelUpload);
this.bind('BeforeUpload', onBeforeUpload);
this.bind('UploadFile', onUploadFile);
this.bind('UploadProgress', onUploadProgress);
this.bind('StateChanged', onStateChanged);
this.bind('QueueChanged', calc);
this.bind('Error', onError);
this.bind('FileUploaded', onFileUploaded);
this.bind('Destroy', onDestroy);
}
function initControls(settings, cb) {
var self = this, inited = 0, queue = [];
// common settings
var options = {
runtime_order: settings.runtimes,
required_caps: settings.required_features,
preferred_caps: preferred_caps,
swf_url: settings.flash_swf_url,
xap_url: settings.silverlight_xap_url
};
// add runtime specific options if any
plupload.each(settings.runtimes.split(/\s*,\s*/), function(runtime) {
if (settings[runtime]) {
options[runtime] = settings[runtime];
}
});
// initialize file pickers - there can be many
if (settings.browse_button) {
plupload.each(settings.browse_button, function(el) {
queue.push(function(cb) {
var fileInput = new o.FileInput(plupload.extend({}, options, {
accept: settings.filters.mime_types,
name: settings.file_data_name,
multiple: settings.multi_selection,
container: settings.container,
browse_button: el
}));
fileInput.onready = function() {
var info = o.Runtime.getInfo(this.ruid);
// for backward compatibility
o.extend(self.features, {
chunks: info.can('slice_blob'),
multipart: info.can('send_multipart'),
multi_selection: info.can('select_multiple')
});
inited++;
fileInputs.push(this);
cb();
};
fileInput.onchange = function() {
self.addFile(this.files);
};
fileInput.bind('mouseenter mouseleave mousedown mouseup', function(e) {
if (!disabled) {
if (settings.browse_button_hover) {
if ('mouseenter' === e.type) {
o.addClass(el, settings.browse_button_hover);
} else if ('mouseleave' === e.type) {
o.removeClass(el, settings.browse_button_hover);
}
}
if (settings.browse_button_active) {
if ('mousedown' === e.type) {
o.addClass(el, settings.browse_button_active);
} else if ('mouseup' === e.type) {
o.removeClass(el, settings.browse_button_active);
}
}
}
});
fileInput.bind('mousedown', function() {
self.trigger('Browse');
});
fileInput.bind('error runtimeerror', function() {
fileInput = null;
cb();
});
fileInput.init();
});
});
}
// initialize drop zones
if (settings.drop_element) {
plupload.each(settings.drop_element, function(el) {
queue.push(function(cb) {
var fileDrop = new o.FileDrop(plupload.extend({}, options, {
drop_zone: el
}));
fileDrop.onready = function() {
var info = o.Runtime.getInfo(this.ruid);
self.features.dragdrop = info.can('drag_and_drop'); // for backward compatibility
inited++;
fileDrops.push(this);
cb();
};
fileDrop.ondrop = function() {
self.addFile(this.files);
};
fileDrop.bind('error runtimeerror', function() {
fileDrop = null;
cb();
});
fileDrop.init();
});
});
}
o.inSeries(queue, function() {
if (typeof(cb) === 'function') {
cb(inited);
}
});
}
function resizeImage(blob, params, cb) {
var img = new o.Image();
try {
img.onload = function() {
// no manipulation required if...
if (params.width > this.width &&
params.height > this.height &&
params.quality === undef &&
params.preserve_headers &&
!params.crop
) {
this.destroy();
return cb(blob);
}
// otherwise downsize
img.downsize(params.width, params.height, params.crop, params.preserve_headers);
};
img.onresize = function() {
cb(this.getAsBlob(blob.type, params.quality));
this.destroy();
};
img.onerror = function() {
cb(blob);
};
img.load(blob);
} catch(ex) {
cb(blob);
}
}
function setOption(option, value, init) {
var self = this, reinitRequired = false;
function _setOption(option, value, init) {
var oldValue = settings[option];
switch (option) {
case 'max_file_size':
if (option === 'max_file_size') {
settings.max_file_size = settings.filters.max_file_size = value;
}
break;
case 'chunk_size':
if (value = plupload.parseSize(value)) {
settings[option] = value;
settings.send_file_name = true;
}
break;
case 'multipart':
settings[option] = value;
if (!value) {
settings.send_file_name = true;
}
break;
case 'unique_names':
settings[option] = value;
if (value) {
settings.send_file_name = true;
}
break;
case 'filters':
// for sake of backward compatibility
if (plupload.typeOf(value) === 'array') {
value = {
mime_types: value
};
}
if (init) {
plupload.extend(settings.filters, value);
} else {
settings.filters = value;
}
// if file format filters are being updated, regenerate the matching expressions
if (value.mime_types) {
settings.filters.mime_types.regexp = (function(filters) {
var extensionsRegExp = [];
plupload.each(filters, function(filter) {
plupload.each(filter.extensions.split(/,/), function(ext) {
if (/^\s*\*\s*$/.test(ext)) {
extensionsRegExp.push('\\.*');
} else {
extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&'));
}
});
});
return new RegExp('(' + extensionsRegExp.join('|') + ')$', 'i');
}(settings.filters.mime_types));
}
break;
case 'resize':
if (init) {
plupload.extend(settings.resize, value, {
enabled: true
});
} else {
settings.resize = value;
}
break;
case 'prevent_duplicates':
settings.prevent_duplicates = settings.filters.prevent_duplicates = !!value;
break;
case 'browse_button':
case 'drop_element':
value = plupload.get(value);
case 'container':
case 'runtimes':
case 'multi_selection':
case 'flash_swf_url':
case 'silverlight_xap_url':
settings[option] = value;
if (!init) {
reinitRequired = true;
}
break;
default:
settings[option] = value;
}
if (!init) {
self.trigger('OptionChanged', option, value, oldValue);
}
}
if (typeof(option) === 'object') {
plupload.each(option, function(value, option) {
_setOption(option, value, init);
});
} else {
_setOption(option, value, init);
}
if (init) {
// Normalize the list of required capabilities
settings.required_features = normalizeCaps(plupload.extend({}, settings));
// Come up with the list of capabilities that can affect default mode in a multi-mode runtimes
preferred_caps = normalizeCaps(plupload.extend({}, settings, {
required_features: true
}));
} else if (reinitRequired) {
self.trigger('Destroy');
initControls.call(self, settings, function(inited) {
if (inited) {
self.runtime = o.Runtime.getInfo(getRUID()).type;
self.trigger('Init', { runtime: self.runtime });
self.trigger('PostInit');
} else {
self.trigger('Error', {
code : plupload.INIT_ERROR,
message : plupload.translate('Init error.')
});
}
});
}
}
// Internal event handlers
function onBeforeUpload(up, file) {
// Generate unique target filenames
if (up.settings.unique_names) {
var matches = file.name.match(/\.([^.]+)$/), ext = "part";
if (matches) {
ext = matches[1];
}
file.target_name = file.id + '.' + ext;
}
}
function onUploadFile(up, file) {
var url = up.settings.url
, chunkSize = up.settings.chunk_size
, retries = up.settings.max_retries
, features = up.features
, offset = 0
, blob
;
// make sure we start at a predictable offset
if (file.loaded) {
offset = file.loaded = chunkSize ? chunkSize * Math.floor(file.loaded / chunkSize) : 0;
}
function handleError() {
if (retries-- > 0) {
delay(uploadNextChunk, 1000);
} else {
file.loaded = offset; // reset all progress
up.trigger('Error', {
code : plupload.HTTP_ERROR,
message : plupload.translate('HTTP Error.'),
file : file,
response : xhr.responseText,
status : xhr.status,
responseHeaders: xhr.getAllResponseHeaders()
});
}
}
function uploadNextChunk() {
var chunkBlob, formData, args = {}, curChunkSize;
// make sure that file wasn't cancelled and upload is not stopped in general
if (file.status !== plupload.UPLOADING || up.state === plupload.STOPPED) {
return;
}
// send additional 'name' parameter only if required
if (up.settings.send_file_name) {
args.name = file.target_name || file.name;
}
if (chunkSize && features.chunks && blob.size > chunkSize) { // blob will be of type string if it was loaded in memory
curChunkSize = Math.min(chunkSize, blob.size - offset);
chunkBlob = blob.slice(offset, offset + curChunkSize);
} else {
curChunkSize = blob.size;
chunkBlob = blob;
}
// If chunking is enabled add corresponding args, no matter if file is bigger than chunk or smaller
if (chunkSize && features.chunks) {
// Setup query string arguments
if (up.settings.send_chunk_number) {
args.chunk = Math.ceil(offset / chunkSize);
args.chunks = Math.ceil(blob.size / chunkSize);
} else { // keep support for experimental chunk format, just in case
args.offset = offset;
args.total = blob.size;
}
}
xhr = new o.XMLHttpRequest();
// Do we have upload progress support
if (xhr.upload) {
xhr.upload.onprogress = function(e) {
file.loaded = Math.min(file.size, offset + e.loaded);
up.trigger('UploadProgress', file);
};
}
xhr.onload = function() {
// check if upload made itself through
if (xhr.status >= 400) {
handleError();
return;
}
retries = up.settings.max_retries; // reset the counter
// Handle chunk response
if (curChunkSize < blob.size) {
chunkBlob.destroy();
offset += curChunkSize;
file.loaded = Math.min(offset, blob.size);
up.trigger('ChunkUploaded', file, {
offset : file.loaded,
total : blob.size,
response : xhr.responseText,
status : xhr.status,
responseHeaders: xhr.getAllResponseHeaders()
});
// stock Android browser doesn't fire upload progress events, but in chunking mode we can fake them
if (o.Env.browser === 'Android Browser') {
// doesn't harm in general, but is not required anywhere else
up.trigger('UploadProgress', file);
}
} else {
file.loaded = file.size;
}
chunkBlob = formData = null; // Free memory
// Check if file is uploaded
if (!offset || offset >= blob.size) {
// If file was modified, destory the copy
if (file.size != file.origSize) {
blob.destroy();
blob = null;
}
up.trigger('UploadProgress', file);
file.status = plupload.DONE;
up.trigger('FileUploaded', file, {
response : xhr.responseText,
status : xhr.status,
responseHeaders: xhr.getAllResponseHeaders()
});
} else {
// Still chunks left
delay(uploadNextChunk, 1); // run detached, otherwise event handlers interfere
}
};
xhr.onerror = function() {
handleError();
};
xhr.onloadend = function() {
this.destroy();
xhr = null;
};
// Build multipart request
if (up.settings.multipart && features.multipart) {
xhr.open("post", url, true);
// Set custom headers
plupload.each(up.settings.headers, function(value, name) {
xhr.setRequestHeader(name, value);
});
formData = new o.FormData();
// Add multipart params
plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) {
formData.append(name, value);
});
// Add file and send it
formData.append(up.settings.file_data_name, chunkBlob);
xhr.send(formData, {
runtime_order: up.settings.runtimes,
required_caps: up.settings.required_features,
preferred_caps: preferred_caps,
swf_url: up.settings.flash_swf_url,
xap_url: up.settings.silverlight_xap_url
});
} else {
// if no multipart, send as binary stream
url = plupload.buildUrl(up.settings.url, plupload.extend(args, up.settings.multipart_params));
xhr.open("post", url, true);
xhr.setRequestHeader('Content-Type', 'application/octet-stream'); // Binary stream header
// Set custom headers
plupload.each(up.settings.headers, function(value, name) {
xhr.setRequestHeader(name, value);
});
xhr.send(chunkBlob, {
runtime_order: up.settings.runtimes,
required_caps: up.settings.required_features,
preferred_caps: preferred_caps,
swf_url: up.settings.flash_swf_url,
xap_url: up.settings.silverlight_xap_url
});
}
}
blob = file.getSource();
// Start uploading chunks
if (up.settings.resize.enabled && runtimeCan(blob, 'send_binary_string') && !!~o.inArray(blob.type, ['image/jpeg', 'image/png'])) {
// Resize if required
resizeImage.call(this, blob, up.settings.resize, function(resizedBlob) {
blob = resizedBlob;
file.size = resizedBlob.size;
uploadNextChunk();
});
} else {
uploadNextChunk();
}
}
function onUploadProgress(up, file) {
calcFile(file);
}
function onStateChanged(up) {
if (up.state == plupload.STARTED) {
// Get start time to calculate bps
startTime = (+new Date());
} else if (up.state == plupload.STOPPED) {
// Reset currently uploading files
for (var i = up.files.length - 1; i >= 0; i--) {
if (up.files[i].status == plupload.UPLOADING) {
up.files[i].status = plupload.QUEUED;
calc();
}
}
}
}
function onCancelUpload() {
if (xhr) {
xhr.abort();
}
}
function onFileUploaded(up) {
calc();
// Upload next file but detach it from the error event
// since other custom listeners might want to stop the queue
delay(function() {
uploadNext.call(up);
}, 1);
}
function onError(up, err) {
if (err.code === plupload.INIT_ERROR) {
up.destroy();
}
// Set failed status if an error occured on a file
else if (err.code === plupload.HTTP_ERROR) {
err.file.status = plupload.FAILED;
calcFile(err.file);
// Upload next file but detach it from the error event
// since other custom listeners might want to stop the queue
if (up.state == plupload.STARTED) { // upload in progress
up.trigger('CancelUpload');
delay(function() {
uploadNext.call(up);
}, 1);
}
}
}
function onDestroy(up) {
up.stop();
// Purge the queue
plupload.each(files, function(file) {
file.destroy();
});
files = [];
if (fileInputs.length) {
plupload.each(fileInputs, function(fileInput) {
fileInput.destroy();
});
fileInputs = [];
}
if (fileDrops.length) {
plupload.each(fileDrops, function(fileDrop) {
fileDrop.destroy();
});
fileDrops = [];
}
preferred_caps = {};
disabled = false;
startTime = xhr = null;
total.reset();
}
// Default settings
settings = {
runtimes: o.Runtime.order,
max_retries: 0,
chunk_size: 0,
multipart: true,
multi_selection: true,
file_data_name: 'file',
flash_swf_url: 'js/Moxie.swf',
silverlight_xap_url: 'js/Moxie.xap',
filters: {
mime_types: [],
prevent_duplicates: false,
max_file_size: 0
},
resize: {
enabled: false,
preserve_headers: true,
crop: false
},
send_file_name: true,
send_chunk_number: true
};
setOption.call(this, options, null, true);
// Inital total state
total = new plupload.QueueProgress();
// Add public methods
plupload.extend(this, {
/**
* Unique id for the Uploader instance.
*
* @property id
* @type String
*/
id : uid,
uid : uid, // mOxie uses this to differentiate between event targets
/**
* Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED.
* These states are controlled by the stop/start methods. The default value is STOPPED.
*
* @property state
* @type Number
*/
state : plupload.STOPPED,
/**
* Map of features that are available for the uploader runtime. Features will be filled
* before the init event is called, these features can then be used to alter the UI for the end user.
* Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize.
*
* @property features
* @type Object
*/
features : {},
/**
* Current runtime name.
*
* @property runtime
* @type String
*/
runtime : null,
/**
* Current upload queue, an array of File instances.
*
* @property files
* @type Array
* @see plupload.File
*/
files : files,
/**
* Object with name/value settings.
*
* @property settings
* @type Object
*/
settings : settings,
/**
* Total progess information. How many files has been uploaded, total percent etc.
*
* @property total
* @type plupload.QueueProgress
*/
total : total,
/**
* Initializes the Uploader instance and adds internal event listeners.
*
* @method init
*/
init : function() {
var self = this;
if (typeof(settings.preinit) == "function") {
settings.preinit(self);
} else {
plupload.each(settings.preinit, function(func, name) {
self.bind(name, func);
});
}
bindEventListeners.call(this);
// Check for required options
if (!settings.browse_button || !settings.url) {
this.trigger('Error', {
code : plupload.INIT_ERROR,
message : plupload.translate('Init error.')
});
return;
}
initControls.call(this, settings, function(inited) {
if (typeof(settings.init) == "function") {
settings.init(self);
} else {
plupload.each(settings.init, function(func, name) {
self.bind(name, func);
});
}
if (inited) {
self.runtime = o.Runtime.getInfo(getRUID()).type;
self.trigger('Init', { runtime: self.runtime });
self.trigger('PostInit');
} else {
self.trigger('Error', {
code : plupload.INIT_ERROR,
message : plupload.translate('Init error.')
});
}
});
},
/**
* Set the value for the specified option(s).
*
* @method setOption
* @since 2.1
* @param {String|Object} option Name of the option to change or the set of key/value pairs
* @param {Mixed} [value] Value for the option (is ignored, if first argument is object)
*/
setOption: function(option, value) {
setOption.call(this, option, value, !this.runtime); // until runtime not set we do not need to reinitialize
},
/**
* Get the value for the specified option or the whole configuration, if not specified.
*
* @method getOption
* @since 2.1
* @param {String} [option] Name of the option to get
* @return {Mixed} Value for the option or the whole set
*/
getOption: function(option) {
if (!option) {
return settings;
}
return settings[option];
},
/**
* Refreshes the upload instance by dispatching out a refresh event to all runtimes.
* This would for example reposition flash/silverlight shims on the page.
*
* @method refresh
*/
refresh : function() {
if (fileInputs.length) {
plupload.each(fileInputs, function(fileInput) {
fileInput.trigger('Refresh');
});
}
this.trigger('Refresh');
},
/**
* Starts uploading the queued files.
*
* @method start
*/
start : function() {
if (this.state != plupload.STARTED) {
this.state = plupload.STARTED;
this.trigger('StateChanged');
uploadNext.call(this);
}
},
/**
* Stops the upload of the queued files.
*
* @method stop
*/
stop : function() {
if (this.state != plupload.STOPPED) {
this.state = plupload.STOPPED;
this.trigger('StateChanged');
this.trigger('CancelUpload');
}
},
/**
* Disables/enables browse button on request.
*
* @method disableBrowse
* @param {Boolean} disable Whether to disable or enable (default: true)
*/
disableBrowse : function() {
disabled = arguments[0] !== undef ? arguments[0] : true;
if (fileInputs.length) {
plupload.each(fileInputs, function(fileInput) {
fileInput.disable(disabled);
});
}
this.trigger('DisableBrowse', disabled);
},
/**
* Returns the specified file object by id.
*
* @method getFile
* @param {String} id File id to look for.
* @return {plupload.File} File object or undefined if it wasn't found;
*/
getFile : function(id) {
var i;
for (i = files.length - 1; i >= 0; i--) {
if (files[i].id === id) {
return files[i];
}
}
},
/**
* Adds file to the queue programmatically. Can be native file, instance of Plupload.File,
* instance of mOxie.File, input[type="file"] element, or array of these. Fires FilesAdded,
* if any files were added to the queue. Otherwise nothing happens.
*
* @method addFile
* @since 2.0
* @param {plupload.File|mOxie.File|File|Node|Array} file File or files to add to the queue.
* @param {String} [fileName] If specified, will be used as a name for the file
*/
addFile : function(file, fileName) {
var self = this
, queue = []
, filesAdded = []
, ruid
;
function filterFile(file, cb) {
var queue = [];
o.each(self.settings.filters, function(rule, name) {
if (fileFilters[name]) {
queue.push(function(cb) {
fileFilters[name].call(self, rule, file, function(res) {
cb(!res);
});
});
}
});
o.inSeries(queue, cb);
}
/**
* @method resolveFile
* @private
* @param {o.File|o.Blob|plupload.File|File|Blob|input[type="file"]} file
*/
function resolveFile(file) {
var type = o.typeOf(file);
// o.File
if (file instanceof o.File) {
if (!file.ruid && !file.isDetached()) {
if (!ruid) { // weird case
return false;
}
file.ruid = ruid;
file.connectRuntime(ruid);
}
resolveFile(new plupload.File(file));
}
// o.Blob
else if (file instanceof o.Blob) {
resolveFile(file.getSource());
file.destroy();
}
// plupload.File - final step for other branches
else if (file instanceof plupload.File) {
if (fileName) {
file.name = fileName;
}
queue.push(function(cb) {
// run through the internal and user-defined filters, if any
filterFile(file, function(err) {
if (!err) {
// make files available for the filters by updating the main queue directly
files.push(file);
// collect the files that will be passed to FilesAdded event
filesAdded.push(file);
self.trigger("FileFiltered", file);
}
delay(cb, 1); // do not build up recursions or eventually we might hit the limits
});
});
}
// native File or blob
else if (o.inArray(type, ['file', 'blob']) !== -1) {
resolveFile(new o.File(null, file));
}
// input[type="file"]
else if (type === 'node' && o.typeOf(file.files) === 'filelist') {
// if we are dealing with input[type="file"]
o.each(file.files, resolveFile);
}
// mixed array of any supported types (see above)
else if (type === 'array') {
fileName = null; // should never happen, but unset anyway to avoid funny situations
o.each(file, resolveFile);
}
}
ruid = getRUID();
resolveFile(file);
if (queue.length) {
o.inSeries(queue, function() {
// if any files left after filtration, trigger FilesAdded
if (filesAdded.length) {
self.trigger("FilesAdded", filesAdded);
}
});
}
},
/**
* Removes a specific file.
*
* @method removeFile
* @param {plupload.File|String} file File to remove from queue.
*/
removeFile : function(file) {
var id = typeof(file) === 'string' ? file : file.id;
for (var i = files.length - 1; i >= 0; i--) {
if (files[i].id === id) {
return this.splice(i, 1)[0];
}
}
},
/**
* Removes part of the queue and returns the files removed. This will also trigger the FilesRemoved and QueueChanged events.
*
* @method splice
* @param {Number} start (Optional) Start index to remove from.
* @param {Number} length (Optional) Lengh of items to remove.
* @return {Array} Array of files that was removed.
*/
splice : function(start, length) {
// Splice and trigger events
var removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length);
// if upload is in progress we need to stop it and restart after files are removed
var restartRequired = false;
if (this.state == plupload.STARTED) { // upload in progress
plupload.each(removed, function(file) {
if (file.status === plupload.UPLOADING) {
restartRequired = true; // do not restart, unless file that is being removed is uploading
return false;
}
});
if (restartRequired) {
this.stop();
}
}
this.trigger("FilesRemoved", removed);
// Dispose any resources allocated by those files
plupload.each(removed, function(file) {
file.destroy();
});
if (restartRequired) {
this.start();
}
return removed;
},
/**
Dispatches the specified event name and its arguments to all listeners.
@method trigger
@param {String} name Event name to fire.
@param {Object..} Multiple arguments to pass along to the listener functions.
*/
// override the parent method to match Plupload-like event logic
dispatchEvent: function(type) {
var list, args, result;
type = type.toLowerCase();
list = this.hasEventListener(type);
if (list) {
// sort event list by prority
list.sort(function(a, b) { return b.priority - a.priority; });
// first argument should be current plupload.Uploader instance
args = [].slice.call(arguments);
args.shift();
args.unshift(this);
for (var i = 0; i < list.length; i++) {
// Fire event, break chain if false is returned
if (list[i].fn.apply(list[i].scope, args) === false) {
return false;
}
}
}
return true;
},
/**
Check whether uploader has any listeners to the specified event.
@method hasEventListener
@param {String} name Event name to check for.
*/
/**
Adds an event listener by name.
@method bind
@param {String} name Event name to listen for.
@param {function} fn Function to call ones the event gets fired.
@param {Object} [scope] Optional scope to execute the specified function in.
@param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first
*/
bind: function(name, fn, scope, priority) {
// adapt moxie EventTarget style to Plupload-like
plupload.Uploader.prototype.bind.call(this, name, fn, priority, scope);
},
/**
Removes the specified event listener.
@method unbind
@param {String} name Name of event to remove.
@param {function} fn Function to remove from listener.
*/
/**
Removes all event listeners.
@method unbindAll
*/
/**
* Destroys Plupload instance and cleans after itself.
*
* @method destroy
*/
destroy : function() {
this.trigger('Destroy');
settings = total = null; // purge these exclusively
this.unbindAll();
}
});
};
plupload.Uploader.prototype = o.EventTarget.instance;
/**
* Constructs a new file instance.
*
* @class File
* @constructor
*
* @param {Object} file Object containing file properties
* @param {String} file.name Name of the file.
* @param {Number} file.size File size.
*/
plupload.File = (function() {
var filepool = {};
function PluploadFile(file) {
plupload.extend(this, {
/**
* File id this is a globally unique id for the specific file.
*
* @property id
* @type String
*/
id: plupload.guid(),
/**
* File name for example "myfile.gif".
*
* @property name
* @type String
*/
name: file.name || file.fileName,
/**
* File type, `e.g image/jpeg`
*
* @property type
* @type String
*/
type: file.type || '',
/**
* File size in bytes (may change after client-side manupilation).
*
* @property size
* @type Number
*/
size: file.size || file.fileSize,
/**
* Original file size in bytes.
*
* @property origSize
* @type Number
*/
origSize: file.size || file.fileSize,
/**
* Number of bytes uploaded of the files total size.
*
* @property loaded
* @type Number
*/
loaded: 0,
/**
* Number of percentage uploaded of the file.
*
* @property percent
* @type Number
*/
percent: 0,
/**
* Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
*
* @property status
* @type Number
* @see plupload
*/
status: plupload.QUEUED,
/**
* Date of last modification.
*
* @property lastModifiedDate
* @type {String}
*/
lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString(), // Thu Aug 23 2012 19:40:00 GMT+0400 (GET)
/**
* Returns native window.File object, when it's available.
*
* @method getNative
* @return {window.File} or null, if plupload.File is of different origin
*/
getNative: function() {
var file = this.getSource().getSource();
return o.inArray(o.typeOf(file), ['blob', 'file']) !== -1 ? file : null;
},
/**
* Returns mOxie.File - unified wrapper object that can be used across runtimes.
*
* @method getSource
* @return {mOxie.File} or null
*/
getSource: function() {
if (!filepool[this.id]) {
return null;
}
return filepool[this.id];
},
/**
* Destroys plupload.File object.
*
* @method destroy
*/
destroy: function() {
var src = this.getSource();
if (src) {
src.destroy();
delete filepool[this.id];
}
}
});
filepool[this.id] = file;
}
return PluploadFile;
}());
/**
* Constructs a queue progress.
*
* @class QueueProgress
* @constructor
*/
plupload.QueueProgress = function() {
var self = this; // Setup alias for self to reduce code size when it's compressed
/**
* Total queue file size.
*
* @property size
* @type Number
*/
self.size = 0;
/**
* Total bytes uploaded.
*
* @property loaded
* @type Number
*/
self.loaded = 0;
/**
* Number of files uploaded.
*
* @property uploaded
* @type Number
*/
self.uploaded = 0;
/**
* Number of files failed to upload.
*
* @property failed
* @type Number
*/
self.failed = 0;
/**
* Number of files yet to be uploaded.
*
* @property queued
* @type Number
*/
self.queued = 0;
/**
* Total percent of the uploaded bytes.
*
* @property percent
* @type Number
*/
self.percent = 0;
/**
* Bytes uploaded per second.
*
* @property bytesPerSec
* @type Number
*/
self.bytesPerSec = 0;
/**
* Resets the progress to its initial values.
*
* @method reset
*/
self.reset = function() {
self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0;
};
};
window.plupload = plupload;
}(window, mOxie));
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* Plupload - multi-runtime File Uploader
* v2.1.8
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Date: 2015-07-21
*/
;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.8",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.code===o.HTTP_ERROR&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},dispatchEvent:function(e){var t,n,r;e=e.toLowerCase(),t=this.hasEventListener(e);if(t){t.sort(function(e,t){return t.priority-e.priority}),n=[].slice.call(arguments),n.shift(),n.unshift(this);for(var i=0;i<t.length;i++)if(t[i].fn.apply(t[i].scope,n)===!1)return!1}return!0},bind:function(e,t,n,r){o.Uploader.prototype.bind.call(this,e,t,r,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie);
\ No newline at end of file
/*
Plupload
------------------------------------------------------------------- */
.plupload_wrapper * {
box-sizing: content-box;
}
.plupload_button {
display: -moz-inline-box; /* FF < 3*/
display: inline-block;
font: normal 12px sans-serif;
text-decoration: none;
color: #42454a;
border: 1px solid #bababa;
padding: 2px 8px 3px 20px;
margin-right: 4px;
background: #f3f3f3 url('../img/buttons.png') no-repeat 0 center;
outline: 0;
/* Optional rounded corners for browsers that support it */
-moz-border-radius: 3px;
-khtml-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.plupload_button:hover {
color: #000;
text-decoration: none;
}
.plupload_disabled, a.plupload_disabled:hover {
color: #737373;
border-color: #c5c5c5;
background: #ededed url('../img/buttons-disabled.png') no-repeat 0 center;
cursor: default;
}
.plupload_add {
background-position: -181px center;
}
.plupload_wrapper {
font: normal 11px Verdana,sans-serif;
width: 100%;
}
.plupload_container {
padding: 8px;
background: url('../img/transp50.png');
/*-moz-border-radius: 5px;*/
}
.plupload_container input {
border: 1px solid #DDD;
font: normal 11px Verdana,sans-serif;
width: 98%;
}
.plupload_header {background: #2A2C2E url('../img/backgrounds.gif') repeat-x;}
.plupload_header_content {
background: url('../img/backgrounds.gif') no-repeat 0 -317px;
min-height: 56px;
padding-left: 60px;
color: #FFF;
}
.plupload_header_title {
font: normal 18px sans-serif;
padding: 6px 0 3px;
}
.plupload_header_text {
font: normal 12px sans-serif;
}
.plupload_filelist {
margin: 0;
padding: 0;
list-style: none;
}
.plupload_scroll .plupload_filelist {
height: 185px;
background: #F5F5F5;
overflow-y: scroll;
}
.plupload_filelist li {
padding: 10px 8px;
background: #F5F5F5 url('../img/backgrounds.gif') repeat-x 0 -156px;
border-bottom: 1px solid #DDD;
}
.plupload_filelist_header, .plupload_filelist_footer {
background: #DFDFDF;
padding: 8px 8px;
color: #42454A;
}
.plupload_filelist_header {
border-top: 1px solid #EEE;
border-bottom: 1px solid #CDCDCD;
}
.plupload_filelist_footer {border-top: 1px solid #FFF; height: 22px; line-height: 20px; vertical-align: middle;}
.plupload_file_name {float: left; overflow: hidden}
.plupload_file_status {color: #777;}
.plupload_file_status span {color: #42454A;}
.plupload_file_size, .plupload_file_status, .plupload_progress {
float: right;
width: 80px;
}
.plupload_file_size, .plupload_file_status, .plupload_file_action {text-align: right;}
.plupload_filelist .plupload_file_name {
width: 205px;
white-space: nowrap;
text-overflow: ellipsis;
}
.plupload_file_action {
float: right;
width: 16px;
height: 16px;
margin-left: 15px;
}
.plupload_file_action * {
display: none;
width: 16px;
height: 16px;
}
li.plupload_uploading {background: #ECF3DC url('../img/backgrounds.gif') repeat-x 0 -238px;}
li.plupload_done {color:#AAA}
li.plupload_delete a {
background: url('../img/delete.gif');
}
li.plupload_failed a {
background: url('../img/error.gif');
cursor: default;
}
li.plupload_done a {
background: url('../img/done.gif');
cursor: default;
}
.plupload_progress, .plupload_upload_status {
display: none;
}
.plupload_progress_container {
margin-top: 3px;
border: 1px solid #CCC;
background: #FFF;
padding: 1px;
}
.plupload_progress_bar {
width: 0px;
height: 7px;
background: #CDEB8B;
}
.plupload_scroll .plupload_filelist_header .plupload_file_action, .plupload_scroll .plupload_filelist_footer .plupload_file_action {
margin-right: 17px;
}
/* Floats */
.plupload_clear,.plupload_clearer {clear: both;}
.plupload_clearer, .plupload_progress_bar {
display: block;
font-size: 0;
line-height: 0;
}
li.plupload_droptext {
background: transparent;
text-align: center;
vertical-align: middle;
border: 0;
line-height: 165px;
}
/*
Plupload
------------------------------------------------------------------- */
.plupload_wrapper * {
box-sizing: content-box;
}
.plupload_button {
cursor: pointer;
outline: none;
}
.plupload_wrapper {
font: normal 11px Verdana,sans-serif;
width: 100%;
min-width: 520px;
line-height: 12px;
}
.plupload_container {
_height: 300px;
min-height: 300px;
position: relative;
}
.plupload_filelist_footer {border-width: 1px 0 0 0}
.plupload_file {border-width: 0 0 1px 0}
.plupload_container .plupload_header {border-width: 0 0 1px 0; position: relative;}
.plupload_delete .ui-icon,
.plupload_done .ui-icon,
.plupload_failed .ui-icon {
cursor:pointer;
}
.plupload_header_content {
height: 56px;
padding: 0 160px 0 60px;
position: relative;
}
.plupload_logo {
width: 40px;
height: 40px;
background: image-url("plupload/plupload.png") no-repeat 0 0;
position: absolute;
top: 8px;
left: 8px;
}
.plupload_header_content_bw .plupload_logo {
background-position: -40px 0;
}
.plupload_header_title {
font: normal 18px sans-serif;
line-height: 19px;
padding: 6px 0 3px;
}
.plupload_header_text {
font: normal 12px sans-serif;
}
.plupload_view_switch {
position: absolute;
right: 16px;
bottom: 8px;
margin: 0;
display: none;
}
.plupload_view_switch .ui-button {
margin-right: -0.31em;
}
.plupload_content {
position: absolute;
top: 86px;
bottom: 44px;
left: 0;
right: 0;
overflow-y: auto;
width: 100%;
}
.plupload_filelist {
border-collapse: collapse;
border-left: none;
border-right: none;
margin: 0;
padding: 0;
width: 100%;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.plupload_filelist_content {
padding: 0;
margin: 0;
}
.plupload_cell {padding: 8px 6px;}
.plupload_file {
list-style: none;
display: block;
position: relative;
overflow: hidden;
line-height: 12px;
}
.plupload_file_thumb {
position: relative;
background-image: none;
background-color: #eee;
}
.plupload_thumb_loading {
background: #eee image-url("plupload/loading.gif") center no-repeat;
}
.plupload_thumb_loading .plupload_file_dummy,
.plupload_thumb_embedded .plupload_file_dummy {
display: none;
}
.plupload_file_name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.plupload_filelist_header {
border-top: none;
}
.plupload_filelist_footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.plupload_buttons {
position: relative;
}
/* list view */
.plupload_view_list .plupload_file {
border-left: none;
border-right: none;
border-top: none;
height: 29px;
width: 100% !important;
/* fix IE6 vertical white-space bug */
_float: left;
_clear: left;
}
.plupload_view_list div.plupload_file_size,
.plupload_view_list div.plupload_file_status,
.plupload_view_list div.plupload_file_action {
padding: 8px 6px;
position: absolute;
top: 0;
right: 0;
}
.plupload_view_list div.plupload_file_name {
margin-right: 156px;
padding: 8px 6px;
_width: 75%;
}
.plupload_view_list div.plupload_file_size {
right: 28px;
}
.plupload_view_list div.plupload_file_status {
right: 82px;
}
.plupload_view_list .plupload_file_rename {
margin-left: -2px;
}
.plupload_view_list .plupload_file_size,
.plupload_view_list .plupload_file_status,
.plupload_filelist_footer .plupload_file_size,
.plupload_filelist_footer .plupload_file_status {
text-align: right;
width: 52px;
}
.plupload_view_list .plupload_file_thumb {
position: absolute;
top: -999px;
}
.plupload_view_list .plupload_file_progress {
display: none;
}
/* thumbs view */
.plupload_view_thumbs .plupload_content {
top: 57px;
}
.plupload_view_thumbs .plupload_filelist_header {
display: none;
}
.plupload_view_thumbs .plupload_file {
padding: 6px;
margin: 10px;
border: 1px solid #fff;
float: left;
}
.plupload_view_thumbs .plupload_file_thumb,
.plupload_view_thumbs .plupload_file_dummy {
text-align: center;
overflow: hidden;
}
.plupload_view_thumbs .plupload_file_dummy {
font-size: 21px;
font-weight: bold;
text-transform: lowercase;
overflow: hidden;
border: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.plupload_view_thumbs div.plupload_file_action {
position: absolute;
top: 0;
right: 0;
}
.plupload_view_thumbs div.plupload_file_name {
padding: 0;
font-weight: bold;
}
.plupload_view_thumbs .plupload_file_rename {
padding: 1px 0;
width: 100% !important;
}
.plupload_view_thumbs div.plupload_file_size {
font-size: 0.8em;
font-weight: normal;
}
.plupload_view_thumbs div.plupload_file_status {
position: relative;
height: 3px;
overflow: hidden;
text-indent: -999px;
margin-bottom: 3px;
}
.plupload_view_thumbs div.plupload_file_progress {
border: none;
height: 100%;
}
.plupload .ui-sortable-helper,
.plupload .ui-sortable .plupload_file {
cursor:move;
}
.plupload_file_action {width: 16px;}
.plupload_file_name {
overflow: hidden;
padding-left: 10px;
}
.plupload_file_rename {
border: none;
font: normal 11px Verdana, sans-serif;
padding: 1px 2px;
line-height: 11px;
height: 11px;
}
.plupload_progress {width: 60px;}
.plupload_progress_container {padding: 1px;}
/* Floats */
.plupload_right {float: right;}
.plupload_left {float: left;}
.plupload_clear,.plupload_clearer {clear: both;}
.plupload_clearer, .plupload_progress_bar {
display: block;
font-size: 0;
line-height: 0;
}
.plupload_clearer {height: 0;}
/* Misc */
.plupload_hidden {display: none !important;}
.plupload_droptext {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: transparent;
text-align: center;
vertical-align: middle;
border: 0;
line-height: 160px;
display: none;
}
.plupload_dropbox .plupload_droptext {
display: block;
}
.plupload_buttons, .plupload_upload_status {float: left}
.plupload_message {
position: absolute;
top: -1px;
left: -1px;
height: 100%;
width: 100%;
}
.plupload_message p {
padding:0.7em;
margin:0;
}
.plupload_message strong {
font-weight: bold;
}
.plupload_message i {
font-style: italic;
}
.plupload_message p span.ui-icon {
float: left;
margin-right: 0.3em;
}
.plupload_header_content .ui-state-error,
.plupload_header_content .ui-state-highlight {
border:none;
}
.plupload_message_close {
position:absolute;
top:5px;
right:5px;
cursor:pointer;
}
.plupload .ui-sortable-placeholder {
height:35px;
}
require "rails-assets-moxiecode--plupload/version"
module RailsAssetsMoxiecodePlupload
def self.gem_path
Pathname(File.realpath(__FILE__)).join('../..')
end
def self.gem_spec
Gem::Specification::load(
gem_path.join("rails-assets-moxiecode--plupload.gemspec").to_s
)
end
def self.load_paths
gem_path.join('app/assets').each_child.to_a
end
def self.dependencies
[
]
end
if defined?(Rails)
class Engine < ::Rails::Engine
# Rails -> use app/assets directory.
end
end
end
class RailsAssets
@components ||= []
class << self
attr_accessor :components
def load_paths
components.flat_map(&:load_paths)
end
end
end
RailsAssets.components << RailsAssetsMoxiecodePlupload
module RailsAssetsMoxiecodePlupload
VERSION = "2.1.8"
end
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'rails-assets-moxiecode--plupload/version'
Gem::Specification.new do |spec|
spec.name = "rails-assets-moxiecode--plupload"
spec.version = RailsAssetsMoxiecodePlupload::VERSION
spec.authors = ["rails-assets.org"]
spec.description = ""
spec.summary = ""
spec.homepage = "https://github.com/moxiecode/plupload"
spec.files = `find ./* -type f | cut -b 3-`.split($/)
spec.require_paths = ["lib"]
spec.post_install_message = "This component doesn't define main assets in bower.json.\nPlease open new pull request in component's repository:\nhttps://github.com/moxiecode/plupload"
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake"
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment