Commit 59dc09da authored by Salva Camarasa's avatar Salva Camarasa Committed by Nicolas Widart

Feature/chunked uploads (#322)

Update Datatables lang files
Implementation of chunked uploads
parent 615effdc
$( document ).ready(function() { $( document ).ready(function() {
Dropzone.autoDiscover = false; Dropzone.autoDiscover = false;
/* Adaptation to resumable uploads
* src: https://github.com/enyo/dropzone/issues/339#issuecomment-138644461
*/
var originalDropzone = Dropzone.prototype.uploadFiles;
Dropzone.prototype.uploadFiles = function (files) {
var resumable = new Resumable ({
target: Asgard.dropzonePostUrl,
maxFiles: Dropzone.prototype.defaultOptions.maxFiles || 10,
simultaneousUploads: Dropzone.prototype.defaultOptions.parallelUploads,
headers: {
'Authorization': AuthorizationHeaderValue
},
testChunks: false
});
if (resumable.support) {
for (var j = 0; j < files.length; j++) {
var fileLocal = files[j];
resumable.addFile(fileLocal);
}
resumable.on('fileAdded', function (file) {
resumable.upload();
});
resumable.on('fileProgress', function (file) {
var progressValue = Math.floor(resumable.progress() * 100);
Dropzone.prototype.defaultOptions.uploadprogress(file.file, progressValue, null);
});
resumable.on('fileSuccess', (function(_this) {
return function (file) {
return _this._finished([file.file], "success", null);
}
})(this));
resumable.on('error', (function(_this) {
return function (message, file) {
return _this._errorProcessing([file.file], message, null);
}
})(this));
} else {
//Fallback to original implementation
return originalDropzone.apply(this, arguments);
}
};
var myDropzone = new Dropzone(".dropzone", { var myDropzone = new Dropzone(".dropzone", {
url: Asgard.dropzonePostUrl, url: Asgard.dropzonePostUrl,
autoProcessQueue: true, autoProcessQueue: true,
...@@ -24,4 +73,4 @@ $( document ).ready(function() { ...@@ -24,4 +73,4 @@ $( document ).ready(function() {
myDropzone.removeFile(file); myDropzone.removeFile(file);
}, 2000); }, 2000);
}); });
}); });
\ No newline at end of file
/*
* MIT Licensed
* http://www.23developer.com/opensource
* http://github.com/23/resumable.js
* Steffen Tiedemann Christensen, steffen@23company.com
*/
(function(){
"use strict";
var Resumable = function(opts){
if ( !(this instanceof Resumable) ) {
return new Resumable(opts);
}
this.version = 1.0;
// SUPPORTED BY BROWSER?
// Check if these features are support by the browser:
// - File object type
// - Blob object type
// - FileList object type
// - slicing files
this.support = (
(typeof(File)!=='undefined')
&&
(typeof(Blob)!=='undefined')
&&
(typeof(FileList)!=='undefined')
&&
(!!Blob.prototype.webkitSlice||!!Blob.prototype.mozSlice||!!Blob.prototype.slice||false)
);
if(!this.support) return(false);
// PROPERTIES
var $ = this;
$.files = [];
$.defaults = {
chunkSize:1*1024*1024,
forceChunkSize:false,
simultaneousUploads:3,
fileParameterName:'file',
chunkNumberParameterName: 'resumableChunkNumber',
chunkSizeParameterName: 'resumableChunkSize',
currentChunkSizeParameterName: 'resumableCurrentChunkSize',
totalSizeParameterName: 'resumableTotalSize',
typeParameterName: 'resumableType',
identifierParameterName: 'resumableIdentifier',
fileNameParameterName: 'resumableFilename',
relativePathParameterName: 'resumableRelativePath',
totalChunksParameterName: 'resumableTotalChunks',
throttleProgressCallbacks: 0.5,
query:{},
headers:{},
preprocess:null,
method:'multipart',
uploadMethod: 'POST',
testMethod: 'GET',
prioritizeFirstAndLastChunk:false,
target:'/',
testTarget: null,
parameterNamespace:'',
testChunks:true,
generateUniqueIdentifier:null,
getTarget:null,
maxChunkRetries:100,
chunkRetryInterval:undefined,
permanentErrors:[400, 404, 415, 500, 501],
maxFiles:undefined,
withCredentials:false,
xhrTimeout:0,
clearInput:true,
maxFilesErrorCallback:function (files, errorCount) {
var maxFiles = $.getOpt('maxFiles');
alert('Please upload no more than ' + maxFiles + ' file' + (maxFiles === 1 ? '' : 's') + ' at a time.');
},
minFileSize:1,
minFileSizeErrorCallback:function(file, errorCount) {
alert(file.fileName||file.name +' is too small, please upload files larger than ' + $h.formatSize($.getOpt('minFileSize')) + '.');
},
maxFileSize:undefined,
maxFileSizeErrorCallback:function(file, errorCount) {
alert(file.fileName||file.name +' is too large, please upload files less than ' + $h.formatSize($.getOpt('maxFileSize')) + '.');
},
fileType: [],
fileTypeErrorCallback: function(file, errorCount) {
alert(file.fileName||file.name +' has type not allowed, please upload files of type ' + $.getOpt('fileType') + '.');
}
};
$.opts = opts||{};
$.getOpt = function(o) {
var $opt = this;
// Get multiple option if passed an array
if(o instanceof Array) {
var options = {};
$h.each(o, function(option){
options[option] = $opt.getOpt(option);
});
return options;
}
// Otherwise, just return a simple option
if ($opt instanceof ResumableChunk) {
if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
else { $opt = $opt.fileObj; }
}
if ($opt instanceof ResumableFile) {
if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
else { $opt = $opt.resumableObj; }
}
if ($opt instanceof Resumable) {
if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
else { return $opt.defaults[o]; }
}
};
// EVENTS
// catchAll(event, ...)
// fileSuccess(file), fileProgress(file), fileAdded(file, event), filesAdded(files, filesSkipped), fileRetry(file),
// fileError(file, message), complete(), progress(), error(message, file), pause()
$.events = [];
$.on = function(event,callback){
$.events.push(event.toLowerCase(), callback);
};
$.fire = function(){
// `arguments` is an object, not array, in FF, so:
var args = [];
for (var i=0; i<arguments.length; i++) args.push(arguments[i]);
// Find event listeners, and support pseudo-event `catchAll`
var event = args[0].toLowerCase();
for (var i=0; i<=$.events.length; i+=2) {
if($.events[i]==event) $.events[i+1].apply($,args.slice(1));
if($.events[i]=='catchall') $.events[i+1].apply(null,args);
}
if(event=='fileerror') $.fire('error', args[2], args[1]);
if(event=='fileprogress') $.fire('progress');
};
// INTERNAL HELPER METHODS (handy, but ultimately not part of uploading)
var $h = {
stopEvent: function(e){
e.stopPropagation();
e.preventDefault();
},
each: function(o,callback){
if(typeof(o.length)!=='undefined') {
for (var i=0; i<o.length; i++) {
// Array or FileList
if(callback(o[i])===false) return;
}
} else {
for (i in o) {
// Object
if(callback(i,o[i])===false) return;
}
}
},
generateUniqueIdentifier:function(file, event){
var custom = $.getOpt('generateUniqueIdentifier');
if(typeof custom === 'function') {
return custom(file, event);
}
var relativePath = file.webkitRelativePath||file.fileName||file.name; // Some confusion in different versions of Firefox
var size = file.size;
return(size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, ''));
},
contains:function(array,test) {
var result = false;
$h.each(array, function(value) {
if (value == test) {
result = true;
return false;
}
return true;
});
return result;
},
formatSize:function(size){
if(size<1024) {
return size + ' bytes';
} else if(size<1024*1024) {
return (size/1024.0).toFixed(0) + ' KB';
} else if(size<1024*1024*1024) {
return (size/1024.0/1024.0).toFixed(1) + ' MB';
} else {
return (size/1024.0/1024.0/1024.0).toFixed(1) + ' GB';
}
},
getTarget:function(request, params){
var target = $.getOpt('target');
if (request === 'test' && $.getOpt('testTarget')) {
target = $.getOpt('testTarget') === '/' ? $.getOpt('target') : $.getOpt('testTarget');
}
if (typeof target === 'function') {
return target(params);
}
var separator = target.indexOf('?') < 0 ? '?' : '&';
var joinedParams = params.join('&');
return target + separator + joinedParams;
}
};
var onDrop = function(event){
$h.stopEvent(event);
//handle dropped things as items if we can (this lets us deal with folders nicer in some cases)
if (event.dataTransfer && event.dataTransfer.items) {
loadFiles(event.dataTransfer.items, event);
}
//else handle them as files
else if (event.dataTransfer && event.dataTransfer.files) {
loadFiles(event.dataTransfer.files, event);
}
};
var preventDefault = function(e) {
e.preventDefault();
};
/**
* processes a single upload item (file or directory)
* @param {Object} item item to upload, may be file or directory entry
* @param {string} path current file path
* @param {File[]} items list of files to append new items to
* @param {Function} cb callback invoked when item is processed
*/
function processItem(item, path, items, cb) {
var entry;
if(item.isFile){
// file provided
return item.file(function(file){
file.relativePath = path + file.name;
items.push(file);
cb();
});
}else if(item.isDirectory){
// item is already a directory entry, just assign
entry = item;
}else if(item instanceof File) {
items.push(item);
}
if('function' === typeof item.webkitGetAsEntry){
// get entry from file object
entry = item.webkitGetAsEntry();
}
if(entry && entry.isDirectory){
// directory provided, process it
return processDirectory(entry, path + entry.name + '/', items, cb);
}
if('function' === typeof item.getAsFile){
// item represents a File object, convert it
item = item.getAsFile();
item.relativePath = path + item.name;
items.push(item);
}
cb(); // indicate processing is done
}
/**
* cps-style list iteration.
* invokes all functions in list and waits for their callback to be
* triggered.
* @param {Function[]} items list of functions expecting callback parameter
* @param {Function} cb callback to trigger after the last callback has been invoked
*/
function processCallbacks(items, cb){
if(!items || items.length === 0){
// empty or no list, invoke callback
return cb();
}
// invoke current function, pass the next part as continuation
items[0](function(){
processCallbacks(items.slice(1), cb);
});
}
/**
* recursively traverse directory and collect files to upload
* @param {Object} directory directory to process
* @param {string} path current path
* @param {File[]} items target list of items
* @param {Function} cb callback invoked after traversing directory
*/
function processDirectory (directory, path, items, cb) {
var dirReader = directory.createReader();
dirReader.readEntries(function(entries){
if(!entries.length){
// empty directory, skip
return cb();
}
// process all conversion callbacks, finally invoke own one
processCallbacks(
entries.map(function(entry){
// bind all properties except for callback
return processItem.bind(null, entry, path, items);
}),
cb
);
});
}
/**
* process items to extract files to be uploaded
* @param {File[]} items items to process
* @param {Event} event event that led to upload
*/
function loadFiles(items, event) {
if(!items.length){
return; // nothing to do
}
$.fire('beforeAdd');
var files = [];
processCallbacks(
Array.prototype.map.call(items, function(item){
// bind all properties except for callback
return processItem.bind(null, item, "", files);
}),
function(){
if(files.length){
// at least one file found
appendFilesFromFileList(files, event);
}
}
);
};
var appendFilesFromFileList = function(fileList, event){
// check for uploading too many files
var errorCount = 0;
var o = $.getOpt(['maxFiles', 'minFileSize', 'maxFileSize', 'maxFilesErrorCallback', 'minFileSizeErrorCallback', 'maxFileSizeErrorCallback', 'fileType', 'fileTypeErrorCallback']);
if (typeof(o.maxFiles)!=='undefined' && o.maxFiles<(fileList.length+$.files.length)) {
// if single-file upload, file is already added, and trying to add 1 new file, simply replace the already-added file
if (o.maxFiles===1 && $.files.length===1 && fileList.length===1) {
$.removeFile($.files[0]);
} else {
o.maxFilesErrorCallback(fileList, errorCount++);
return false;
}
}
var files = [], filesSkipped = [], remaining = fileList.length;
var decreaseReamining = function(){
if(!--remaining){
// all files processed, trigger event
if(!files.length && !filesSkipped.length){
// no succeeded files, just skip
return;
}
window.setTimeout(function(){
$.fire('filesAdded', files, filesSkipped);
},0);
}
};
$h.each(fileList, function(file){
var fileName = file.name;
if(o.fileType.length > 0){
var fileTypeFound = false;
for(var index in o.fileType){
var extension = '.' + o.fileType[index];
if(fileName.indexOf(extension, fileName.length - extension.length) !== -1){
fileTypeFound = true;
break;
}
}
if (!fileTypeFound) {
o.fileTypeErrorCallback(file, errorCount++);
return false;
}
}
if (typeof(o.minFileSize)!=='undefined' && file.size<o.minFileSize) {
o.minFileSizeErrorCallback(file, errorCount++);
return false;
}
if (typeof(o.maxFileSize)!=='undefined' && file.size>o.maxFileSize) {
o.maxFileSizeErrorCallback(file, errorCount++);
return false;
}
function addFile(uniqueIdentifier){
if (!$.getFromUniqueIdentifier(uniqueIdentifier)) {(function(){
file.uniqueIdentifier = uniqueIdentifier;
var f = new ResumableFile($, file, uniqueIdentifier);
$.files.push(f);
files.push(f);
f.container = (typeof event != 'undefined' ? event.srcElement : null);
window.setTimeout(function(){
$.fire('fileAdded', f, event)
},0);
})()} else {
filesSkipped.push(file);
};
decreaseReamining();
}
// directories have size == 0
var uniqueIdentifier = $h.generateUniqueIdentifier(file, event);
if(uniqueIdentifier && typeof uniqueIdentifier.then === 'function'){
// Promise or Promise-like object provided as unique identifier
uniqueIdentifier
.then(
function(uniqueIdentifier){
// unique identifier generation succeeded
addFile(uniqueIdentifier);
},
function(){
// unique identifier generation failed
// skip further processing, only decrease file count
decreaseReamining();
}
);
}else{
// non-Promise provided as unique identifier, process synchronously
addFile(uniqueIdentifier);
}
});
};
// INTERNAL OBJECT TYPES
function ResumableFile(resumableObj, file, uniqueIdentifier){
var $ = this;
$.opts = {};
$.getOpt = resumableObj.getOpt;
$._prevProgress = 0;
$.resumableObj = resumableObj;
$.file = file;
$.fileName = file.fileName||file.name; // Some confusion in different versions of Firefox
$.size = file.size;
$.relativePath = file.relativePath || file.webkitRelativePath || $.fileName;
$.uniqueIdentifier = uniqueIdentifier;
$._pause = false;
$.container = '';
var _error = uniqueIdentifier !== undefined;
// Callback when something happens within the chunk
var chunkEvent = function(event, message){
// event can be 'progress', 'success', 'error' or 'retry'
switch(event){
case 'progress':
$.resumableObj.fire('fileProgress', $);
break;
case 'error':
$.abort();
_error = true;
$.chunks = [];
$.resumableObj.fire('fileError', $, message);
break;
case 'success':
if(_error) return;
$.resumableObj.fire('fileProgress', $); // it's at least progress
if($.isComplete()) {
$.resumableObj.fire('fileSuccess', $, message);
}
break;
case 'retry':
$.resumableObj.fire('fileRetry', $);
break;
}
};
// Main code to set up a file object with chunks,
// packaged to be able to handle retries if needed.
$.chunks = [];
$.abort = function(){
// Stop current uploads
var abortCount = 0;
$h.each($.chunks, function(c){
if(c.status()=='uploading') {
c.abort();
abortCount++;
}
});
if(abortCount>0) $.resumableObj.fire('fileProgress', $);
};
$.cancel = function(){
// Reset this file to be void
var _chunks = $.chunks;
$.chunks = [];
// Stop current uploads
$h.each(_chunks, function(c){
if(c.status()=='uploading') {
c.abort();
$.resumableObj.uploadNextChunk();
}
});
$.resumableObj.removeFile($);
$.resumableObj.fire('fileProgress', $);
};
$.retry = function(){
$.bootstrap();
var firedRetry = false;
$.resumableObj.on('chunkingComplete', function(){
if(!firedRetry) $.resumableObj.upload();
firedRetry = true;
});
};
$.bootstrap = function(){
$.abort();
_error = false;
// Rebuild stack of chunks from file
$.chunks = [];
$._prevProgress = 0;
var round = $.getOpt('forceChunkSize') ? Math.ceil : Math.floor;
var maxOffset = Math.max(round($.file.size/$.getOpt('chunkSize')),1);
for (var offset=0; offset<maxOffset; offset++) {(function(offset){
window.setTimeout(function(){
$.chunks.push(new ResumableChunk($.resumableObj, $, offset, chunkEvent));
$.resumableObj.fire('chunkingProgress',$,offset/maxOffset);
},0);
})(offset)}
window.setTimeout(function(){
$.resumableObj.fire('chunkingComplete',$);
},0);
};
$.progress = function(){
if(_error) return(1);
// Sum up progress across everything
var ret = 0;
var error = false;
$h.each($.chunks, function(c){
if(c.status()=='error') error = true;
ret += c.progress(true); // get chunk progress relative to entire file
});
ret = (error ? 1 : (ret>0.99999 ? 1 : ret));
ret = Math.max($._prevProgress, ret); // We don't want to lose percentages when an upload is paused
$._prevProgress = ret;
return(ret);
};
$.isUploading = function(){
var uploading = false;
$h.each($.chunks, function(chunk){
if(chunk.status()=='uploading') {
uploading = true;
return(false);
}
});
return(uploading);
};
$.isComplete = function(){
var outstanding = false;
$h.each($.chunks, function(chunk){
var status = chunk.status();
if(status=='pending' || status=='uploading' || chunk.preprocessState === 1) {
outstanding = true;
return(false);
}
});
return(!outstanding);
};
$.pause = function(pause){
if(typeof(pause)==='undefined'){
$._pause = ($._pause ? false : true);
}else{
$._pause = pause;
}
};
$.isPaused = function() {
return $._pause;
};
// Bootstrap and return
$.resumableObj.fire('chunkingStart', $);
$.bootstrap();
return(this);
}
function ResumableChunk(resumableObj, fileObj, offset, callback){
var $ = this;
$.opts = {};
$.getOpt = resumableObj.getOpt;
$.resumableObj = resumableObj;
$.fileObj = fileObj;
$.fileObjSize = fileObj.size;
$.fileObjType = fileObj.file.type;
$.offset = offset;
$.callback = callback;
$.lastProgressCallback = (new Date);
$.tested = false;
$.retries = 0;
$.pendingRetry = false;
$.preprocessState = 0; // 0 = unprocessed, 1 = processing, 2 = finished
// Computed properties
var chunkSize = $.getOpt('chunkSize');
$.loaded = 0;
$.startByte = $.offset*chunkSize;
$.endByte = Math.min($.fileObjSize, ($.offset+1)*chunkSize);
if ($.fileObjSize-$.endByte < chunkSize && !$.getOpt('forceChunkSize')) {
// The last chunk will be bigger than the chunk size, but less than 2*chunkSize
$.endByte = $.fileObjSize;
}
$.xhr = null;
// test() makes a GET request without any data to see if the chunk has already been uploaded in a previous session
$.test = function(){
// Set up request and listen for event
$.xhr = new XMLHttpRequest();
var testHandler = function(e){
$.tested = true;
var status = $.status();
if(status=='success') {
$.callback(status, $.message());
$.resumableObj.uploadNextChunk();
} else {
$.send();
}
};
$.xhr.addEventListener('load', testHandler, false);
$.xhr.addEventListener('error', testHandler, false);
$.xhr.addEventListener('timeout', testHandler, false);
// Add data from the query options
var params = [];
var parameterNamespace = $.getOpt('parameterNamespace');
var customQuery = $.getOpt('query');
if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
$h.each(customQuery, function(k,v){
params.push([encodeURIComponent(parameterNamespace+k), encodeURIComponent(v)].join('='));
});
// Add extra data to identify chunk
params = params.concat(
[
// define key/value pairs for additional parameters
['chunkNumberParameterName', $.offset + 1],
['chunkSizeParameterName', $.getOpt('chunkSize')],
['currentChunkSizeParameterName', $.endByte - $.startByte],
['totalSizeParameterName', $.fileObjSize],
['typeParameterName', $.fileObjType],
['identifierParameterName', $.fileObj.uniqueIdentifier],
['fileNameParameterName', $.fileObj.fileName],
['relativePathParameterName', $.fileObj.relativePath],
['totalChunksParameterName', $.fileObj.chunks.length]
].filter(function(pair){
// include items that resolve to truthy values
// i.e. exclude false, null, undefined and empty strings
return $.getOpt(pair[0]);
})
.map(function(pair){
// map each key/value pair to its final form
return [
parameterNamespace + $.getOpt(pair[0]),
encodeURIComponent(pair[1])
].join('=');
})
);
// Append the relevant chunk and send it
$.xhr.open($.getOpt('testMethod'), $h.getTarget('test', params));
$.xhr.timeout = $.getOpt('xhrTimeout');
$.xhr.withCredentials = $.getOpt('withCredentials');
// Add data from header options
var customHeaders = $.getOpt('headers');
if(typeof customHeaders === 'function') {
customHeaders = customHeaders($.fileObj, $);
}
$h.each(customHeaders, function(k,v) {
$.xhr.setRequestHeader(k, v);
});
$.xhr.send(null);
};
$.preprocessFinished = function(){
$.preprocessState = 2;
$.send();
};
// send() uploads the actual data in a POST call
$.send = function(){
var preprocess = $.getOpt('preprocess');
if(typeof preprocess === 'function') {
switch($.preprocessState) {
case 0: $.preprocessState = 1; preprocess($); return;
case 1: return;
case 2: break;
}
}
if($.getOpt('testChunks') && !$.tested) {
$.test();
return;
}
// Set up request and listen for event
$.xhr = new XMLHttpRequest();
// Progress
$.xhr.upload.addEventListener('progress', function(e){
if( (new Date) - $.lastProgressCallback > $.getOpt('throttleProgressCallbacks') * 1000 ) {
$.callback('progress');
$.lastProgressCallback = (new Date);
}
$.loaded=e.loaded||0;
}, false);
$.loaded = 0;
$.pendingRetry = false;
$.callback('progress');
// Done (either done, failed or retry)
var doneHandler = function(e){
var status = $.status();
if(status=='success'||status=='error') {
$.callback(status, $.message());
$.resumableObj.uploadNextChunk();
} else {
$.callback('retry', $.message());
$.abort();
$.retries++;
var retryInterval = $.getOpt('chunkRetryInterval');
if(retryInterval !== undefined) {
$.pendingRetry = true;
setTimeout($.send, retryInterval);
} else {
$.send();
}
}
};
$.xhr.addEventListener('load', doneHandler, false);
$.xhr.addEventListener('error', doneHandler, false);
$.xhr.addEventListener('timeout', doneHandler, false);
// Set up the basic query data from Resumable
var query = [
['chunkNumberParameterName', $.offset + 1],
['chunkSizeParameterName', $.getOpt('chunkSize')],
['currentChunkSizeParameterName', $.endByte - $.startByte],
['totalSizeParameterName', $.fileObjSize],
['typeParameterName', $.fileObjType],
['identifierParameterName', $.fileObj.uniqueIdentifier],
['fileNameParameterName', $.fileObj.fileName],
['relativePathParameterName', $.fileObj.relativePath],
['totalChunksParameterName', $.fileObj.chunks.length],
].filter(function(pair){
// include items that resolve to truthy values
// i.e. exclude false, null, undefined and empty strings
return $.getOpt(pair[0]);
})
.reduce(function(query, pair){
// assign query key/value
query[$.getOpt(pair[0])] = pair[1];
return query;
}, {});
// Mix in custom data
var customQuery = $.getOpt('query');
if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
$h.each(customQuery, function(k,v){
query[k] = v;
});
var func = ($.fileObj.file.slice ? 'slice' : ($.fileObj.file.mozSlice ? 'mozSlice' : ($.fileObj.file.webkitSlice ? 'webkitSlice' : 'slice')));
var bytes = $.fileObj.file[func]($.startByte, $.endByte);
var data = null;
var params = [];
var parameterNamespace = $.getOpt('parameterNamespace');
if ($.getOpt('method') === 'octet') {
// Add data from the query options
data = bytes;
$h.each(query, function (k, v) {
params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
});
} else {
// Add data from the query options
data = new FormData();
$h.each(query, function (k, v) {
data.append(parameterNamespace + k, v);
params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
});
data.append(parameterNamespace + $.getOpt('fileParameterName'), bytes, $.fileObj.fileName);
}
var target = $h.getTarget('upload', params);
var method = $.getOpt('uploadMethod');
$.xhr.open(method, target);
if ($.getOpt('method') === 'octet') {
$.xhr.setRequestHeader('Content-Type', 'application/octet-stream');
}
$.xhr.timeout = $.getOpt('xhrTimeout');
$.xhr.withCredentials = $.getOpt('withCredentials');
// Add data from header options
var customHeaders = $.getOpt('headers');
if(typeof customHeaders === 'function') {
customHeaders = customHeaders($.fileObj, $);
}
$h.each(customHeaders, function(k,v) {
$.xhr.setRequestHeader(k, v);
});
$.xhr.send(data);
};
$.abort = function(){
// Abort and reset
if($.xhr) $.xhr.abort();
$.xhr = null;
};
$.status = function(){
// Returns: 'pending', 'uploading', 'success', 'error'
if($.pendingRetry) {
// if pending retry then that's effectively the same as actively uploading,
// there might just be a slight delay before the retry starts
return('uploading');
} else if(!$.xhr) {
return('pending');
} else if($.xhr.readyState<4) {
// Status is really 'OPENED', 'HEADERS_RECEIVED' or 'LOADING' - meaning that stuff is happening
return('uploading');
} else {
if($.xhr.status == 200 || $.xhr.status == 201) {
// HTTP 200, 201 (created)
return('success');
} else if($h.contains($.getOpt('permanentErrors'), $.xhr.status) || $.retries >= $.getOpt('maxChunkRetries')) {
// HTTP 415/500/501, permanent error
return('error');
} else {
// this should never happen, but we'll reset and queue a retry
// a likely case for this would be 503 service unavailable
$.abort();
return('pending');
}
}
};
$.message = function(){
return($.xhr ? $.xhr.responseText : '');
};
$.progress = function(relative){
if(typeof(relative)==='undefined') relative = false;
var factor = (relative ? ($.endByte-$.startByte)/$.fileObjSize : 1);
if($.pendingRetry) return(0);
if(!$.xhr || !$.xhr.status) factor*=.95;
var s = $.status();
switch(s){
case 'success':
case 'error':
return(1*factor);
case 'pending':
return(0*factor);
default:
return($.loaded/($.endByte-$.startByte)*factor);
}
};
return(this);
}
// QUEUE
$.uploadNextChunk = function(){
var found = false;
// In some cases (such as videos) it's really handy to upload the first
// and last chunk of a file quickly; this let's the server check the file's
// metadata and determine if there's even a point in continuing.
if ($.getOpt('prioritizeFirstAndLastChunk')) {
$h.each($.files, function(file){
if(file.chunks.length && file.chunks[0].status()=='pending' && file.chunks[0].preprocessState === 0) {
file.chunks[0].send();
found = true;
return(false);
}
if(file.chunks.length>1 && file.chunks[file.chunks.length-1].status()=='pending' && file.chunks[file.chunks.length-1].preprocessState === 0) {
file.chunks[file.chunks.length-1].send();
found = true;
return(false);
}
});
if(found) return(true);
}
// Now, simply look for the next, best thing to upload
$h.each($.files, function(file){
if(file.isPaused()===false){
$h.each(file.chunks, function(chunk){
if(chunk.status()=='pending' && chunk.preprocessState === 0) {
chunk.send();
found = true;
return(false);
}
});
}
if(found) return(false);
});
if(found) return(true);
// The are no more outstanding chunks to upload, check is everything is done
var outstanding = false;
$h.each($.files, function(file){
if(!file.isComplete()) {
outstanding = true;
return(false);
}
});
if(!outstanding) {
// All chunks have been uploaded, complete
$.fire('complete');
}
return(false);
};
// PUBLIC METHODS FOR RESUMABLE.JS
$.assignBrowse = function(domNodes, isDirectory){
if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
$h.each(domNodes, function(domNode) {
var input;
if(domNode.tagName==='INPUT' && domNode.type==='file'){
input = domNode;
} else {
input = document.createElement('input');
input.setAttribute('type', 'file');
input.style.display = 'none';
domNode.addEventListener('click', function(){
input.style.opacity = 0;
input.style.display='block';
input.focus();
input.click();
input.style.display='none';
}, false);
domNode.appendChild(input);
}
var maxFiles = $.getOpt('maxFiles');
if (typeof(maxFiles)==='undefined'||maxFiles!=1){
input.setAttribute('multiple', 'multiple');
} else {
input.removeAttribute('multiple');
}
if(isDirectory){
input.setAttribute('webkitdirectory', 'webkitdirectory');
} else {
input.removeAttribute('webkitdirectory');
}
// When new files are added, simply append them to the overall list
input.addEventListener('change', function(e){
appendFilesFromFileList(e.target.files,e);
var clearInput = $.getOpt('clearInput');
if (clearInput) {
e.target.value = '';
}
}, false);
});
};
$.assignDrop = function(domNodes){
if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
$h.each(domNodes, function(domNode) {
domNode.addEventListener('dragover', preventDefault, false);
domNode.addEventListener('dragenter', preventDefault, false);
domNode.addEventListener('drop', onDrop, false);
});
};
$.unAssignDrop = function(domNodes) {
if (typeof(domNodes.length) == 'undefined') domNodes = [domNodes];
$h.each(domNodes, function(domNode) {
domNode.removeEventListener('dragover', preventDefault);
domNode.removeEventListener('dragenter', preventDefault);
domNode.removeEventListener('drop', onDrop);
});
};
$.isUploading = function(){
var uploading = false;
$h.each($.files, function(file){
if (file.isUploading()) {
uploading = true;
return(false);
}
});
return(uploading);
};
$.upload = function(){
// Make sure we don't start too many uploads at once
if($.isUploading()) return;
// Kick off the queue
$.fire('uploadStart');
for (var num=1; num<=$.getOpt('simultaneousUploads'); num++) {
$.uploadNextChunk();
}
};
$.pause = function(){
// Resume all chunks currently being uploaded
$h.each($.files, function(file){
file.abort();
});
$.fire('pause');
};
$.cancel = function(){
$.fire('beforeCancel');
for(var i = $.files.length - 1; i >= 0; i--) {
$.files[i].cancel();
}
$.fire('cancel');
};
$.progress = function(){
var totalDone = 0;
var totalSize = 0;
// Resume all chunks currently being uploaded
$h.each($.files, function(file){
totalDone += file.progress()*file.size;
totalSize += file.size;
});
return(totalSize>0 ? totalDone/totalSize : 0);
};
$.addFile = function(file, event){
appendFilesFromFileList([file], event);
};
$.removeFile = function(file){
for(var i = $.files.length - 1; i >= 0; i--) {
if($.files[i] === file) {
$.files.splice(i, 1);
}
}
};
$.getFromUniqueIdentifier = function(uniqueIdentifier){
var ret = false;
$h.each($.files, function(f){
if(f.uniqueIdentifier==uniqueIdentifier) ret = f;
});
return(ret);
};
$.getSize = function(){
var totalSize = 0;
$h.each($.files, function(file){
totalSize += file.size;
});
return(totalSize);
};
$.handleDropEvent = function (e) {
onDrop(e);
};
$.handleChangeEvent = function (e) {
appendFilesFromFileList(e.target.files, e);
e.target.value = '';
};
$.updateQuery = function(query){
$.opts.query = query;
};
return(this);
};
// Node.js-style export for Node and Component
if (typeof module != 'undefined') {
module.exports = Resumable;
} else if (typeof define === "function" && define.amd) {
// AMD/requirejs: Define the module
define(function(){
return Resumable;
});
} else {
// Browser: Expose to window
window.Resumable = Resumable;
}
})();
\ No newline at end of file
...@@ -15,6 +15,10 @@ use Modules\Media\Http\Requests\UploadMediaRequest; ...@@ -15,6 +15,10 @@ use Modules\Media\Http\Requests\UploadMediaRequest;
use Modules\Media\Image\Imagy; use Modules\Media\Image\Imagy;
use Modules\Media\Repositories\FileRepository; use Modules\Media\Repositories\FileRepository;
use Modules\Media\Services\FileService; use Modules\Media\Services\FileService;
use Pion\Laravel\ChunkUpload\Exceptions\UploadMissingFileException;
use Pion\Laravel\ChunkUpload\Handler\AbstractHandler;
use Pion\Laravel\ChunkUpload\Handler\ResumableJSUploadHandler;
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
class MediaController extends Controller class MediaController extends Controller
{ {
...@@ -56,19 +60,37 @@ class MediaController extends Controller ...@@ -56,19 +60,37 @@ class MediaController extends Controller
* @param UploadMediaRequest $request * @param UploadMediaRequest $request
* @return Response * @return Response
*/ */
public function store(UploadMediaRequest $request) public function store(Request $request)
{ {
$savedFile = $this->fileService->store($request->file('file')); $receiver = new FileReceiver("file", $request, ResumableJSUploadHandler::class);
if (is_string($savedFile)) { if ($receiver->isUploaded()) {
return Response::json([ $save = $receiver->receive();
'error' => $savedFile,
], 409); if ($save->isFinished()) {
} $savedFile = $this->fileService->store($save->getFile());
if (is_string($savedFile)) {
return Response::json([
'error' => $savedFile,
], 409);
}
event(new FileWasUploaded($savedFile)); event(new FileWasUploaded($savedFile));
return Response::json($savedFile->toArray()); return Response::json($savedFile->toArray());
}
else {
$handler = $save->handler();
return response()->json([
"done" => $handler->getPercentageDone()
]);
}
}
else {
throw new UploadMissingFileException();
}
} }
/** /**
...@@ -91,9 +113,9 @@ class MediaController extends Controller ...@@ -91,9 +113,9 @@ class MediaController extends Controller
'order' => $order, 'order' => $order,
]); ]);
$imageable = DB::table('media__imageables')->whereFileId($mediaId) $imageable = DB::table('media__imageables')->whereFileId($mediaId)
->whereZone($zone) ->whereZone($zone)
->whereImageableType($entityClass) ->whereImageableType($entityClass)
->first(); ->first();
$file = $this->file->find($imageable->file_id); $file = $this->file->find($imageable->file_id);
$mediaType = FileHelper::getTypeByMimetype($file->mimetype); $mediaType = FileHelper::getTypeByMimetype($file->mimetype);
......
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
{!! Theme::script('vendor/bootstrap/dist/js/bootstrap.min.js') !!} {!! Theme::script('vendor/bootstrap/dist/js/bootstrap.min.js') !!}
{!! Theme::script('vendor/datatables.net/js/jquery.dataTables.min.js') !!} {!! Theme::script('vendor/datatables.net/js/jquery.dataTables.min.js') !!}
{!! Theme::script('vendor/datatables.net-bs/js/dataTables.bootstrap.min.js') !!} {!! Theme::script('vendor/datatables.net-bs/js/dataTables.bootstrap.min.js') !!}
<script src="{!! Module::asset('media:js/resumable.js') !!}"></script>
<script src="{!! Module::asset('media:js/dropzone.js') !!}"></script> <script src="{!! Module::asset('media:js/dropzone.js') !!}"></script>
<?php $config = config('asgard.media.config'); ?> <?php $config = config('asgard.media.config'); ?>
<script> <script>
......
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
@stop @stop
@section('scripts') @section('scripts')
<script src="{!! Module::asset('media:js/resumable.js') !!}"></script>
<script src="{!! Module::asset('media:js/dropzone.js') !!}"></script> <script src="{!! Module::asset('media:js/dropzone.js') !!}"></script>
<?php $config = config('asgard.media.config'); ?> <?php $config = config('asgard.media.config'); ?>
<script> <script>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
{{ trans('core::core.error 500') }} {{ trans('core::core.error 500') }}
</h1> </h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><a href="{{ route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li> <li><a href="{{ route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class="current">{{ trans('core::core.error 500') }}</li> <li class="current">{{ trans('core::core.error 500') }}</li>
</ol> </ol>
@stop @stop
......
...@@ -188,6 +188,8 @@ return [ ...@@ -188,6 +188,8 @@ return [
Modules\Core\Providers\AsgardServiceProvider::class, Modules\Core\Providers\AsgardServiceProvider::class,
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
Pion\Laravel\ChunkUpload\Providers\ChunkUploadServiceProvider::class
], ],
/* /*
......
<?php
return [
/**
* The storage config
*/
"storage" => [
/**
* Returns the folder name of the chunks. The location is in storage/app/{folder_name}
*/
"chunks" => "storage/app/chunks",
"disk" => "local"
],
"clear" => [
/**
* How old chunks we should delete
*/
"timestamp" => "-3 HOURS",
"schedule" => [
"enabled" => true,
"cron" => "0 */1 * * * *" // run every hour
]
],
"chunk" => [
// setup for the chunk naming setup to ensure same name upload at same time
"name" => [
"use" => [
"session" => false, // should the chunk name use the session id? The uploader must send cookie!,
"browser" => true // instead of session we can use the ip and browser?
]
]
]
];
\ No newline at end of file
{
"sEmptyTable": "Geen data beskikbaar in tabel",
"sInfo": "uitstalling _START_ to _END_ of _TOTAL_ inskrywings",
"sInfoEmpty": "uitstalling 0 to 0 of 0 inskrywings",
"sInfoFiltered": "(gefiltreer uit _MAX_ totaal inskrywings)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "uitstal _MENU_ inskrywings",
"sLoadingRecords": "laai...",
"sProcessing": "verwerking...",
"sSearch": "soektog:",
"sZeroRecords": "Geen treffers gevind",
"oPaginate": {
"sFirst": "eerste",
"sLast": "laaste",
"sNext": "volgende",
"sPrevious": "vorige"
},
"oAria": {
"sSortAscending": ": aktiveer kolom stygende te sorteer",
"sSortDescending": ": aktiveer kolom orde te sorteer"
}
}
\ No newline at end of file
{
"sProcessing": "جارٍ التحميل...",
"sLengthMenu": "أظهر _MENU_ مدخلات",
"sZeroRecords": "لم يعثر على أية سجلات",
"sInfo": "إظهار _START_ إلى _END_ من أصل _TOTAL_ مدخل",
"sInfoEmpty": "يعرض 0 إلى 0 من أصل 0 سجل",
"sInfoFiltered": "(منتقاة من مجموع _MAX_ مُدخل)",
"sInfoPostFix": "",
"sSearch": "ابحث:",
"sUrl": "",
"oPaginate": {
"sFirst": "الأول",
"sPrevious": "السابق",
"sNext": "التالي",
"sLast": "الأخير"
}
}
\ No newline at end of file
{
"sEmptyTable": "Cədvəldə heç bir məlumat yoxdur",
"sInfo": " _TOTAL_ Nəticədən _START_ - _END_ Arası Nəticələr",
"sInfoEmpty": "Nəticə Yoxdur",
"sInfoFiltered": "( _MAX_ Nəticə İçindən Tapılanlar)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Səhifədə _MENU_ Nəticə Göstər",
"sLoadingRecords": "Yüklənir...",
"sProcessing": "Gözləyin...",
"sSearch": "Axtarış:",
"sZeroRecords": "Nəticə Tapılmadı.",
"oPaginate": {
"sFirst": "İlk",
"sLast": "Axırıncı",
"sNext": "Sonraki",
"sPrevious": "Öncəki"
},
"oAria": {
"sSortAscending": ": sütunu artma sırası üzərə aktiv etmək",
"sSortDescending": ": sütunu azalma sırası üzərə aktiv etmək"
}
}
\ No newline at end of file
{
"sProcessing": "Пачакайце...",
"sLengthMenu": "Паказваць _MENU_ запісаў",
"sZeroRecords": "Запісы адсутнічаюць.",
"sInfo": "Запісы з _START_ па _END_ з _TOTAL_ запісаў",
"sInfoEmpty": "Запісы з 0 па 0 з 0 запісаў",
"sInfoFiltered": "(адфільтравана з _MAX_ запісаў)",
"sInfoPostFix": "",
"sSearch": "Пошук:",
"sUrl": "",
"oPaginate": {
"sFirst": "Першая",
"sPrevious": "Папярэдняя",
"sNext": "Наступная",
"sLast": "Апошняя"
},
"oAria": {
"sSortAscending": ": актываваць для сартавання слупка па ўзрастанні",
"sSortDescending": ": актываваць для сартавання слупка па змяншэнні"
}
}
\ No newline at end of file
{
"sProcessing": "Обработка на резултатите...",
"sLengthMenu": "Показване на _MENU_ резултата",
"sZeroRecords": "Няма намерени резултати",
"sInfo": "Показване на резултати от _START_ до _END_ от общо _TOTAL_",
"sInfoEmpty": "Показване на резултати от 0 до 0 от общо 0",
"sInfoFiltered": "(филтрирани от общо _MAX_ резултата)",
"sInfoPostFix": "",
"sSearch": "Търсене във всички колони:",
"sUrl": "",
"oPaginate": {
"sFirst": "Първа",
"sPrevious": "Предишна",
"sNext": "Следваща",
"sLast": "Последна"
}
}
\ No newline at end of file
{
"sProcessing": "প্রসেসিং হচ্ছে...",
"sLengthMenu": "_MENU_ টা এন্ট্রি দেখাও",
"sZeroRecords": "আপনি যা অনুসন্ধান করেছেন তার সাথে মিলে যাওয়া কোন রেকর্ড খুঁজে পাওয়া যায় নাই",
"sInfo": "_TOTAL_ টা এন্ট্রির মধ্যে _START_ থেকে _END_ পর্যন্ত দেখানো হচ্ছে",
"sInfoEmpty": "কোন এন্ট্রি খুঁজে পাওয়া যায় নাই",
"sInfoFiltered": "(মোট _MAX_ টা এন্ট্রির মধ্যে থেকে বাছাইকৃত)",
"sInfoPostFix": "",
"sSearch": "অনুসন্ধান:",
"sUrl": "",
"oPaginate": {
"sFirst": "প্রথমটা",
"sPrevious": "আগেরটা",
"sNext": "পরবর্তীটা",
"sLast": "শেষেরটা"
}
}
\ No newline at end of file
{
"sProcessing": "Processant...",
"sLengthMenu": "Mostra _MENU_ registres",
"sZeroRecords": "No s'han trobat registres.",
"sInfo": "Mostrant de _START_ a _END_ de _TOTAL_ registres",
"sInfoEmpty": "Mostrant de 0 a 0 de 0 registres",
"sInfoFiltered": "(filtrat de _MAX_ total registres)",
"sInfoPostFix": "",
"sSearch": "Filtrar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primer",
"sPrevious": "Anterior",
"sNext": "Següent",
"sLast": "Últim"
}
}
\ No newline at end of file
{
"sEmptyTable": "Tabulka neobsahuje žádná data",
"sInfo": "Zobrazuji _START_ až _END_ z celkem _TOTAL_ záznamů",
"sInfoEmpty": "Zobrazuji 0 až 0 z 0 záznamů",
"sInfoFiltered": "(filtrováno z celkem _MAX_ záznamů)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "Zobraz záznamů _MENU_",
"sLoadingRecords": "Načítám...",
"sProcessing": "Provádím...",
"sSearch": "Hledat:",
"sZeroRecords": "Žádné záznamy nebyly nalezeny",
"oPaginate": {
"sFirst": "První",
"sLast": "Poslední",
"sNext": "Další",
"sPrevious": "Předchozí"
},
"oAria": {
"sSortAscending": ": aktivujte pro řazení sloupce vzestupně",
"sSortDescending": ": aktivujte pro řazení sloupce sestupně"
}
}
\ No newline at end of file
{
"sEmptyTable": "Dim data ar gael yn y tabl",
"sInfo": "Dangos _START_ i _END_ o _TOTAL_ cofnod",
"sInfoEmpty": "Dangos 0 i 0 o 0 cofnod",
"sInfoFiltered": "(wedi hidlo o gyfanswm o _MAX_ cofnod)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Dangos _MENU_ cofnod",
"sLoadingRecords": "Wrthi'n llwytho...",
"sProcessing": "Wrthi'n prosesu...",
"sSearch": "Chwilio:",
"sZeroRecords": "Heb ddod o hyd i gofnodion sy'n cyfateb",
"oPaginate": {
"sFirst": "Cyntaf",
"sLast": "Olaf",
"sNext": "Nesaf",
"sPrevious": "Blaenorol"
},
"oAria": {
"sSortAscending": ": rhoi ar waith i drefnu colofnau o'r lleiaf i'r mwyaf",
"sSortDescending": ": rhoi ar waith i drefnu colofnau o'r mwyaf i'r lleiaf"
}
}
\ No newline at end of file
{
"sProcessing": "Henter...",
"sLengthMenu": "Vis _MENU_ linjer",
"sZeroRecords": "Ingen linjer matcher s&oslash;gningen",
"sInfo": "Viser _START_ til _END_ af _TOTAL_ linjer",
"sInfoEmpty": "Viser 0 til 0 af 0 linjer",
"sInfoFiltered": "(filtreret fra _MAX_ linjer)",
"sInfoPostFix": "",
"sSearch": "S&oslash;g:",
"sUrl": "",
"oPaginate": {
"sFirst": "F&oslash;rste",
"sPrevious": "Forrige",
"sNext": "N&aelig;ste",
"sLast": "Sidste"
}
}
\ No newline at end of file
{ {
"sEmptyTable": "Keine Daten in der Tabelle vorhanden", "sEmptyTable": "Keine Daten in der Tabelle vorhanden",
"sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen", "sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoEmpty": "0 bis 0 von 0 Einträgen", "sInfoEmpty": "0 bis 0 von 0 Einträgen",
"sInfoFiltered": "(gefiltert von _MAX_ Einträgen)", "sInfoFiltered": "(gefiltert von _MAX_ Einträgen)",
"sInfoPostFix": "", "sInfoPostFix": "",
"sInfoThousands": ".", "sInfoThousands": ".",
"sLengthMenu": "_MENU_ Einträge anzeigen", "sLengthMenu": "_MENU_ Einträge anzeigen",
"sLoadingRecords": "Wird geladen...", "sLoadingRecords": "Wird geladen...",
"sProcessing": "Bitte warten...", "sProcessing": "Bitte warten...",
"sSearch": "Suchen", "sSearch": "Suchen",
"sZeroRecords": "Keine Einträge vorhanden.", "sZeroRecords": "Keine Einträge vorhanden.",
"oPaginate": { "oPaginate": {
"sFirst": "Erste", "sFirst": "Erste",
"sPrevious": "Zurück", "sPrevious": "Zurück",
"sNext": "Nächste", "sNext": "Nächste",
"sLast": "Letzte" "sLast": "Letzte"
}, },
"oAria": { "oAria": {
"sSortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren", "sSortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren",
"sSortDescending": ": aktivieren, um Spalte absteigend zu sortieren" "sSortDescending": ": aktivieren, um Spalte absteigend zu sortieren"
} }
} }
\ No newline at end of file
{
"sDecimal": ",",
"sEmptyTable": "Δεν υπάρχουν δεδομένα στον πίνακα",
"sInfo": "Εμφανίζονται _START_ έως _END_ από _TOTAL_ εγγραφές",
"sInfoEmpty": "Εμφανίζονται 0 έως 0 από 0 εγγραφές",
"sInfoFiltered": "(φιλτραρισμένες από _MAX_ συνολικά εγγραφές)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Δείξε _MENU_ εγγραφές",
"sLoadingRecords": "Φόρτωση...",
"sProcessing": "Επεξεργασία...",
"sSearch": "Αναζήτηση:",
"sSearchPlaceholder": "Αναζήτηση",
"sThousands": ".",
"sUrl": "",
"sZeroRecords": "Δεν βρέθηκαν εγγραφές που να ταιριάζουν",
"oPaginate": {
"sFirst": "Πρώτη",
"sPrevious": "Προηγούμενη",
"sNext": "Επόμενη",
"sLast": "Τελευταία"
},
"oAria": {
"sSortAscending": ": ενεργοποιήστε για αύξουσα ταξινόμηση της στήλης",
"sSortDescending": ": ενεργοποιήστε για φθίνουσα ταξινόμηση της στήλης"
}
}
\ No newline at end of file
{ {
"sEmptyTable": "No data available in table", "sEmptyTable": "No data available in table",
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
"sInfoEmpty": "Showing 0 to 0 of 0 entries", "sInfoEmpty": "Showing 0 to 0 of 0 entries",
"sInfoFiltered": "(filtered from _MAX_ total entries)", "sInfoFiltered": "(filtered from _MAX_ total entries)",
"sInfoPostFix": "", "sInfoPostFix": "",
"sInfoThousands": ",", "sInfoThousands": ",",
"sLengthMenu": "Show _MENU_ entries", "sLengthMenu": "Show _MENU_ entries",
"sLoadingRecords": "Loading...", "sLoadingRecords": "Loading...",
"sProcessing": "Processing...", "sProcessing": "Processing...",
"sSearch": "Search:", "sSearch": "Search:",
"sZeroRecords": "No matching records found", "sZeroRecords": "No matching records found",
"oPaginate": { "oPaginate": {
"sFirst": "First", "sFirst": "First",
"sLast": "Last", "sLast": "Last",
"sNext": "Next", "sNext": "Next",
"sPrevious": "Previous" "sPrevious": "Previous"
}, },
"oAria": { "oAria": {
"sSortAscending": ": activate to sort column ascending", "sSortAscending": ": activate to sort column ascending",
"sSortDescending": ": activate to sort column descending" "sSortDescending": ": activate to sort column descending"
} }
} }
\ No newline at end of file
{ {
"sEmptyTable": "No hay datos disponibles en la tabla", "sProcessing": "Procesando...",
"sInfo": "Mostrando _START_ de _END_ a _TOTAL_ registros", "sLengthMenu": "Mostrar _MENU_ registros",
"sInfoEmpty": "Mostrando 0 de 0 a 0 registros", "sZeroRecords": "No se encontraron resultados",
"sInfoFiltered": "(filtrado de _MAX_ registros)", "sEmptyTable": "Ningún dato disponible en esta tabla",
"sInfoPostFix": "", "sInfo": "Mostrando registros del _START_ al _END_ de un total de _TOTAL_ registros",
"sInfoThousands": ",", "sInfoEmpty": "Mostrando registros del 0 al 0 de un total de 0 registros",
"sLengthMenu": "Mostrar _MENU_ registros", "sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
"sLoadingRecords": "Cargando...", "sInfoPostFix": "",
"sProcessing": "Procesando...", "sSearch": "Buscar:",
"sSearch": "Buscar:", "sUrl": "",
"sZeroRecords": "No se encontró ningún registro.", "sInfoThousands": ",",
"oPaginate": { "sLoadingRecords": "Cargando...",
"sFirst": "Primero", "oPaginate": {
"sLast": "Último", "sFirst": "Primero",
"sNext": "Siguiente", "sLast": "Último",
"sPrevious": "Anterior" "sNext": "Siguiente",
}, "sPrevious": "Anterior"
"oAria": { },
"sSortAscending": ": activar el orden ascendente", "oAria": {
"sSortDescending": ": activar el orden descendente" "sSortAscending": ": Activar para ordenar la columna de manera ascendente",
} "sSortDescending": ": Activar para ordenar la columna de manera descendente"
}
} }
\ No newline at end of file
{
"sProcessing": "Palun oodake, koostan kuvamiseks nimekirja!",
"sLengthMenu": "N&auml;ita kirjeid _MENU_ kaupa",
"sZeroRecords": "Otsitavat vastet ei leitud.",
"sInfo": "Kuvatud: _TOTAL_ kirjet (_START_-_END_)",
"sInfoEmpty": "Otsinguvasteid ei leitud",
"sInfoFiltered": " - filteeritud _MAX_ kirje seast.",
"sInfoPostFix": "K&otilde;ik kuvatud kirjed p&otilde;hinevad reaalsetel tulemustel.",
"sSearch": "Otsi k&otilde;ikide tulemuste seast:",
"oPaginate": {
"sFirst": "Algus",
"sPrevious": "Eelmine",
"sNext": "J&auml;rgmine",
"sLast": "Viimane"
}
}
\ No newline at end of file
{
"sProcessing": "Prozesatzen...",
"sLengthMenu": "Erakutsi _MENU_ erregistro",
"sZeroRecords": "Ez da emaitzarik aurkitu",
"sEmptyTable": "Taula hontan ez dago inongo datu erabilgarririk",
"sInfo": "_START_ -etik _END_ -erako erregistroak erakusten, guztira _TOTAL_ erregistro",
"sInfoEmpty": "0tik 0rako erregistroak erakusten, guztira 0 erregistro",
"sInfoFiltered": "(guztira _MAX_ erregistro iragazten)",
"sInfoPostFix": "",
"sSearch": "Aurkitu:",
"sUrl": "",
"sInfoThousands": ",",
"sLoadingRecords": "Abiarazten...",
"oPaginate": {
"sFirst": "Lehena",
"sLast": "Azkena",
"sNext": "Hurrengoa",
"sPrevious": "Aurrekoa"
},
"oAria": {
"sSortAscending": ": Zutabea goranzko eran ordenatzeko aktibatu ",
"sSortDescending": ": Zutabea beheranzko eran ordenatzeko aktibatu"
}
}
\ No newline at end of file
{
"sProcessing": "درحال پردازش...",
"sLengthMenu": "نمایش محتویات _MENU_",
"sZeroRecords": "موردی یافت نشد",
"sInfo": "نمایش _START_ تا _END_ از مجموع _TOTAL_ مورد",
"sInfoEmpty": "تهی",
"sInfoFiltered": "(فیلتر شده از مجموع _MAX_ مورد)",
"sInfoPostFix": "",
"sSearch": "جستجو:",
"sUrl": "",
"oPaginate": {
"sFirst": "ابتدا",
"sPrevious": "قبلی",
"sNext": "بعدی",
"sLast": "انتها"
}
}
\ No newline at end of file
{
"sProcessing": "Hetkinen...",
"sLengthMenu": "Näytä kerralla _MENU_ riviä",
"sZeroRecords": "Tietoja ei löytynyt",
"sInfo": "Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )",
"sInfoEmpty": "Näytetään 0 - 0 (yhteensä 0)",
"sInfoFiltered": "(suodatettu _MAX_ tuloksen joukosta)",
"sInfoPostFix": "",
"sSearch": "Etsi:",
"sUrl": "",
"oPaginate": {
"sFirst": "Ensimmäinen",
"sPrevious": "Edellinen",
"sNext": "Seuraava",
"sLast": "Viimeinen"
}
}
\ No newline at end of file
{
"sProcessing": "Pagproseso...",
"sLengthMenu": "Ipakita _MENU_ entries",
"sZeroRecords": "Walang katugmang mga talaan na natagpuan",
"sInfo": "Ipinapakita ang _START_ sa _END_ ng _TOTAL_ entries",
"sInfoEmpty": "Ipinapakita ang 0-0 ng 0 entries",
"sInfoFiltered": "(na-filter mula _MAX_ kabuuang entries)",
"sInfoPostFix": "",
"sSearch": "Paghahanap:",
"sUrl": "",
"oPaginate": {
"sFirst": "Unang",
"sPrevious": "Nakaraan",
"sNext": "Susunod",
"sLast": "Huli"
}
}
\ No newline at end of file
{ {
"sProcessing": "Traitement en cours...", "sProcessing": "Traitement en cours...",
"sSearch": "Rechercher&nbsp;:", "sSearch": "Rechercher&nbsp;:",
"sLengthMenu": "Afficher _MENU_ &eacute;l&eacute;ments", "sLengthMenu": "Afficher _MENU_ &eacute;l&eacute;ments",
"sInfo": "Affichage de l'&eacute;lement _START_ &agrave; _END_ sur _TOTAL_ &eacute;l&eacute;ments", "sInfo": "Affichage de l'&eacute;l&eacute;ment _START_ &agrave; _END_ sur _TOTAL_ &eacute;l&eacute;ments",
"sInfoEmpty": "Affichage de l'&eacute;lement 0 &agrave; 0 sur 0 &eacute;l&eacute;ments", "sInfoEmpty": "Affichage de l'&eacute;l&eacute;ment 0 &agrave; 0 sur 0 &eacute;l&eacute;ment",
"sInfoFiltered": "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)", "sInfoFiltered": "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)",
"sInfoPostFix": "", "sInfoPostFix": "",
"sLoadingRecords": "Chargement en cours...", "sLoadingRecords": "Chargement en cours...",
"sZeroRecords": "Aucun &eacute;l&eacute;ment &agrave; afficher", "sZeroRecords": "Aucun &eacute;l&eacute;ment &agrave; afficher",
"sEmptyTable": "Aucune donn&eacute;e disponible dans le tableau", "sEmptyTable": "Aucune donn&eacute;e disponible dans le tableau",
"oPaginate": { "oPaginate": {
"sFirst": "Premier", "sFirst": "Premier",
"sPrevious": "Pr&eacute;c&eacute;dent", "sPrevious": "Pr&eacute;c&eacute;dent",
"sNext": "Suivant", "sNext": "Suivant",
"sLast": "Dernier" "sLast": "Dernier"
}, },
"oAria": { "oAria": {
"sSortAscending": ": activer pour trier la colonne par ordre croissant", "sSortAscending": ": activer pour trier la colonne par ordre croissant",
"sSortDescending": ": activer pour trier la colonne par ordre d&eacute;croissant" "sSortDescending": ": activer pour trier la colonne par ordre d&eacute;croissant"
} }
} }
\ No newline at end of file
{
"sProcessing": "Próiseáil...",
"sLengthMenu": "Taispeáin iontrálacha _MENU_",
"sZeroRecords": "Gan aon taifead meaitseáil aimsithe",
"sInfo": "_START_ Showing a _END_ na n-iontrálacha _TOTAL_",
"sInfoEmpty": "Showing 0-0 na n-iontrálacha 0",
"sInfoFiltered": "(scagtha ó _MAX_ iontrálacha iomlán)",
"sInfoPostFix": "",
"sSearch": "Cuardaigh:",
"sUrl": "",
"oPaginate": {
"sFirst": "An Chéad",
"sPrevious": "Roimhe Seo",
"sNext": "Ar Aghaidh",
"sLast": "Last"
}
}
\ No newline at end of file
{
"sProcessing": "Procesando...",
"sLengthMenu": "Mostrar _MENU_ rexistros",
"sZeroRecords": "Non se atoparon resultados",
"sEmptyTable": "Ningún dato dispoñible nesta táboa",
"sInfo": "Mostrando rexistros do _START_ ó _END_ dun total de _TOTAL_ rexistros",
"sInfoEmpty": "Mostrando rexistros do 0 ó 0 dun total de 0 rexistros",
"sInfoFiltered": "(filtrado dun total de _MAX_ rexistros)",
"sInfoPostFix": "",
"sSearch": "Buscar:",
"sUrl": "",
"sInfoThousands": ",",
"sLoadingRecords": "Cargando...",
"oPaginate": {
"sFirst": "Primeiro",
"sLast": "Último",
"sNext": "Seguinte",
"sPrevious": "Anterior"
},
"oAria": {
"sSortAscending": ": Activar para ordear a columna de maneira ascendente",
"sSortDescending": ": Activar para ordear a columna de maneira descendente"
}
}
\ No newline at end of file
{
"sEmptyTable": "કોષ્ટકમાં કોઈ ડેટા ઉપલબ્ધ નથી",
"sInfo": "કુલ_પ્રવેશો_અંત_પ્રારંભ_દર્શાવે_છે",
"sInfoEmpty": "0 પ્રવેશો 0 0 બતાવી રહ્યું છે",
"sInfoFiltered": "(_MAX_ કુલ પ્રવેશો માંથી ફિલ્ટર)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "બતાવો _MENU_ પ્રવેશો",
"sLoadingRecords": "લોડ કરી રહ્યું છે ...",
"sProcessing": "પ્રક્રિયા ...",
"sSearch": "શોધો:",
"sZeroRecords": "કોઈ મેળ ખાતા રેકોર્ડ મળી",
"oPaginate": {
"sFirst": "પ્રથમ",
"sLast": "અંતિમ",
"sNext": "આગામી",
"sPrevious": "ગત"
},
"oAria": {
"sSortAscending": ": સ્તંભ ચડતા ક્રમમાં ગોઠવવા માટે સક્રિય",
"sSortDescending": ": કૉલમ ઉતરતા ક્રમમાં ગોઠવવા માટે સક્રિય"
}
}
\ No newline at end of file
{
"processing": "מעבד...",
"lengthMenu": "הצג _MENU_ פריטים",
"zeroRecords": "לא נמצאו רשומות מתאימות",
"emptyTable": "לא נמצאו רשומות מתאימות",
"info": "_START_ עד _END_ מתוך _TOTAL_ רשומות" ,
"infoEmpty": "0 עד 0 מתוך 0 רשומות",
"infoFiltered": "(מסונן מסך _MAX_ רשומות)",
"infoPostFix": "",
"search": "חפש:",
"url": "",
"paginate": {
"first": "ראשון",
"previous": "קודם",
"next": "הבא",
"last": "אחרון"
}
}
\ No newline at end of file
{
"sProcessing": "प्रगति पे हैं ...",
"sLengthMenu": " _MENU_ प्रविष्टियां दिखाएं ",
"sZeroRecords": "रिकॉर्ड्स का मेल नहीं मिला",
"sInfo": "_START_ to _END_ of _TOTAL_ प्रविष्टियां दिखा रहे हैं",
"sInfoEmpty": "0 में से 0 से 0 प्रविष्टियां दिखा रहे हैं",
"sInfoFiltered": "(_MAX_ कुल प्रविष्टियों में से छठा हुआ)",
"sInfoPostFix": "",
"sSearch": "खोजें:",
"sUrl": "",
"oPaginate": {
"sFirst": "प्रथम",
"sPrevious": "पिछला",
"sNext": "अगला",
"sLast": "अंतिम"
}
}
\ No newline at end of file
{
"sEmptyTable": "Nema podataka u tablici",
"sInfo": "Prikazano _START_ do _END_ od _TOTAL_ rezultata",
"sInfoEmpty": "Prikazano 0 do 0 od 0 rezultata",
"sInfoFiltered": "(filtrirano iz _MAX_ ukupnih rezultata)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Prikaži _MENU_ rezultata po stranici",
"sLoadingRecords": "Dohvaćam...",
"sProcessing": "Obrađujem...",
"sSearch": "Pretraži:",
"sZeroRecords": "Ništa nije pronađeno",
"oPaginate": {
"sFirst": "Prva",
"sPrevious": "Nazad",
"sNext": "Naprijed",
"sLast": "Zadnja"
},
"oAria": {
"sSortAscending": ": aktiviraj za rastući poredak",
"sSortDescending": ": aktiviraj za padajući poredak"
}
}
\ No newline at end of file
{
"sEmptyTable": "Nincs rendelkezésre álló adat",
"sInfo": "Találatok: _START_ - _END_ Összesen: _TOTAL_",
"sInfoEmpty": "Nulla találat",
"sInfoFiltered": "(_MAX_ összes rekord közül szűrve)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "_MENU_ találat oldalanként",
"sLoadingRecords": "Betöltés...",
"sProcessing": "Feldolgozás...",
"sSearch": "Keresés:",
"sZeroRecords": "Nincs a keresésnek megfelelő találat",
"oPaginate": {
"sFirst": "Első",
"sPrevious": "Előző",
"sNext": "Következő",
"sLast": "Utolsó"
},
"oAria": {
"sSortAscending": ": aktiválja a növekvő rendezéshez",
"sSortDescending": ": aktiválja a csökkenő rendezéshez"
}
}
\ No newline at end of file
{
"sEmptyTable": "Տվյալները բացակայում են",
"sProcessing": "Կատարվում է...",
"sInfoThousands": ",",
"sLengthMenu": "Ցուցադրել _MENU_ արդյունքներ մեկ էջում",
"sLoadingRecords": "Բեռնվում է ...",
"sZeroRecords": "Հարցմանը համապատասխանող արդյունքներ չկան",
"sInfo": "Ցուցադրված են _START_-ից _END_ արդյունքները ընդհանուր _TOTAL_-ից",
"sInfoEmpty": "Արդյունքներ գտնված չեն",
"sInfoFiltered": "(ֆիլտրվել է ընդհանուր _MAX_ արդյունքներից)",
"sInfoPostFix": "",
"sSearch": "Փնտրել",
"oPaginate": {
"sFirst": "Առաջին էջ",
"sPrevious": "Նախորդ էջ",
"sNext": "Հաջորդ էջ",
"sLast": "Վերջին էջ"
},
"oAria": {
"sSortAscending": ": ակտիվացրեք աճման կարգով դասավորելու համար",
"sSortDescending": ": ակտիվացրեք նվազման կարգով դասավորելու համար"
}
}
\ No newline at end of file
{
"sProcessing": "Sedang memproses...",
"sLengthMenu": "Tampilkan _MENU_ entri",
"sZeroRecords": "Tidak ditemukan data yang sesuai",
"sInfo": "Menampilkan _START_ sampai _END_ dari _TOTAL_ entri",
"sInfoEmpty": "Menampilkan 0 sampai 0 dari 0 entri",
"sInfoFiltered": "(disaring dari _MAX_ entri keseluruhan)",
"sInfoPostFix": "",
"sSearch": "Cari:",
"sUrl": "",
"oPaginate": {
"sFirst": "Pertama",
"sPrevious": "Sebelumnya",
"sNext": "Selanjutnya",
"sLast": "Terakhir"
}
}
\ No newline at end of file
{
"sEmptyTable": "Engin gögn eru í þessari töflu",
"sInfo": "Sýni _START_ til _END_ af _TOTAL_ færslum",
"sInfoEmpty": "Sýni 0 til 0 af 0 færslum",
"sInfoFiltered": "(síað út frá _MAX_ færslum)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Sýna _MENU_ færslur",
"sLoadingRecords": "Hleð...",
"sProcessing": "Úrvinnsla...",
"sSearch": "Leita:",
"sZeroRecords": "Engar færslur fundust",
"oPaginate": {
"sFirst": "Fyrsta",
"sLast": "Síðasta",
"sNext": "Næsta",
"sPrevious": "Fyrri"
},
"oAria": {
"sSortAscending": ": virkja til að raða dálki í hækkandi röð",
"sSortDescending": ": virkja til að raða dálki lækkandi í röð"
}
}
\ No newline at end of file
{
"sEmptyTable": "Nessun dato presente nella tabella",
"sInfo": "Vista da _START_ a _END_ di _TOTAL_ elementi",
"sInfoEmpty": "Vista da 0 a 0 di 0 elementi",
"sInfoFiltered": "(filtrati da _MAX_ elementi totali)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Visualizza _MENU_ elementi",
"sLoadingRecords": "Caricamento...",
"sProcessing": "Elaborazione...",
"sSearch": "Cerca:",
"sZeroRecords": "La ricerca non ha portato alcun risultato.",
"oPaginate": {
"sFirst": "Inizio",
"sPrevious": "Precedente",
"sNext": "Successivo",
"sLast": "Fine"
},
"oAria": {
"sSortAscending": ": attiva per ordinare la colonna in ordine crescente",
"sSortDescending": ": attiva per ordinare la colonna in ordine decrescente"
}
}
\ No newline at end of file
{
"sEmptyTable": "テーブルにデータがありません",
"sInfo": " _TOTAL_ 件中 _START_ から _END_ まで表示",
"sInfoEmpty": " 0 件中 0 から 0 まで表示",
"sInfoFiltered": "(全 _MAX_ 件より抽出)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ 件表示",
"sLoadingRecords": "読み込み中...",
"sProcessing": "処理中...",
"sSearch": "検索:",
"sZeroRecords": "一致するレコードがありません",
"oPaginate": {
"sFirst": "先頭",
"sLast": "最終",
"sNext": "次",
"sPrevious": "前"
},
"oAria": {
"sSortAscending": ": 列を昇順に並べ替えるにはアクティブにする",
"sSortDescending": ": 列を降順に並べ替えるにはアクティブにする"
}
}
\ No newline at end of file
{
"sEmptyTable": "ცხრილში არ არის მონაცემები",
"sInfo": "ნაჩვენებია ჩანაწერები _START_–დან _END_–მდე, _TOTAL_ ჩანაწერიდან",
"sInfoEmpty": "ნაჩვენებია ჩანაწერები 0–დან 0–მდე, 0 ჩანაწერიდან",
"sInfoFiltered": "(გაფილტრული შედეგი _MAX_ ჩანაწერიდან)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "აჩვენე _MENU_ ჩანაწერი",
"sLoadingRecords": "იტვირთება...",
"sProcessing": "მუშავდება...",
"sSearch": "ძიება:",
"sZeroRecords": "არაფერი მოიძებნა",
"oPaginate": {
"sFirst": "პირველი",
"sLast": "ბოლო",
"sNext": "შემდეგი",
"sPrevious": "წინა"
},
"oAria": {
"sSortAscending": ": სვეტის დალაგება ზრდის მიხედვით",
"sSortDescending": ": სვეტის დალაგება კლების მიხედვით"
}
}
\ No newline at end of file
{
"sEmptyTable": "데이터가 없습니다",
"sInfo": "_START_ - _END_ / _TOTAL_",
"sInfoEmpty": "0 - 0 / 0",
"sInfoFiltered": "(총 _MAX_ 개)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "페이지당 줄수 _MENU_",
"sLoadingRecords": "읽는중...",
"sProcessing": "처리중...",
"sSearch": "검색:",
"sZeroRecords": "검색 결과가 없습니다",
"oPaginate": {
"sFirst": "처음",
"sLast": "마지막",
"sNext": "다음",
"sPrevious": "이전"
},
"oAria": {
"sSortAscending": ": 오름차순 정렬",
"sSortDescending": ": 내림차순 정렬"
}
}
\ No newline at end of file
{
"sEmptyTable": "Таблицада эч кандай берилиш жок",
"sInfo": "Жалпы _TOTAL_ саптын ичинен _START_-саптан _END_-сапка чейинкилер",
"sInfoEmpty": "Жалпы 0 саптын ичинен 0-саптан 0-сапка чейинкилер",
"sInfoFiltered": "(жалпы _MAX_ саптан фильтрленди)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "_MENU_ саптан көрсөт",
"sLoadingRecords": "Жүктөлүүдө...",
"sProcessing": "Иштеп жатат...",
"sSearch": "Издөө:",
"sZeroRecords": "Туура келген бир да сап жок",
"oPaginate": {
"sFirst": "Биринчи",
"sLast": "Акыркы",
"sNext": "Кийинки",
"sPrevious": "Мурунку"
},
"oAria": {
"sSortAscending": ": иретте",
"sSortDescending": ": тескери иретте"
}
}
\ No newline at end of file
{
"sEmptyTable": "Lentelėje nėra duomenų",
"sInfo": "Rodomi įrašai nuo _START_ iki _END_ iš _TOTAL_ įrašų",
"sInfoEmpty": "Rodomi įrašai nuo 0 iki 0 iš 0",
"sInfoFiltered": "(atrinkta iš _MAX_ įrašų)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "Rodyti _MENU_ įrašus",
"sLoadingRecords": "Įkeliama...",
"sProcessing": "Apdorojama...",
"sSearch": "Ieškoti:",
"sThousands": " ",
"sUrl": "",
"sZeroRecords": "Įrašų nerasta",
"oPaginate": {
"sFirst": "Pirmas",
"sPrevious": "Ankstesnis",
"sNext": "Tolimesnis",
"sLast": "Paskutinis"
}
}
\ No newline at end of file
{
"processing": "Uzgaidiet...",
"search": "Meklēt:",
"lengthMenu": "Rādīt _MENU_ ierakstus",
"info": "Parādīti _START_. līdz _END_. no _TOTAL_ ierakstiem",
"infoEmpty": "Nav ierakstu",
"infoFiltered": "(atlasīts no pavisam _MAX_ ierakstiem)",
"infoPostFix": "",
"loadingRecords": "Iekraušanas ieraksti ...",
"zeroRecords": "Nav atrasti vaicājumam atbilstoši ieraksti",
"emptyTable:": "Tabula nav datu",
"paginate": {
"first": "Pirmā",
"previous": "Iepriekšējā",
"next": "Nākošā",
"last": "Pēdējā"
},
"aria": {
"sortAscending": ": aktivizēt kolonnu, lai kārtotu augošā",
"sortDescending": ": aktivizēt kolonnu, lai kārtotu dilstošā"
}
}
\ No newline at end of file
{
"sProcessing": "Процесирање...",
"sLengthMenu": "Прикажи _MENU_ записи",
"sZeroRecords": "Не се пронајдени записи",
"sEmptyTable": "Нема податоци во табелата",
"sLoadingRecords": "Вчитување...",
"sInfo": "Прикажани _START_ до _END_ од _TOTAL_ записи",
"sInfoEmpty": "Прикажани 0 до 0 од 0 записи",
"sInfoFiltered": "(филтрирано од вкупно _MAX_ записи)",
"sInfoPostFix": "",
"sSearch": "Барај",
"sUrl": "",
"oPaginate": {
"sFirst": "Почетна",
"sPrevious": "Претходна",
"sNext": "Следна",
"sLast": "Последна"
}
}
\ No newline at end of file
{
"sEmptyTable": "Хүснэгт хоосон байна",
"sInfo": "Нийт _TOTAL_ бичлэгээс _START_ - _END_ харуулж байна",
"sInfoEmpty": "Тохирох үр дүн алга",
"sInfoFiltered": "(нийт _MAX_ бичлэгээс шүүв)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Дэлгэцэд _MENU_ бичлэг харуулна",
"sLoadingRecords": "Ачааллаж байна...",
"sProcessing": "Боловсруулж байна...",
"sSearch": "Хайлт:",
"sZeroRecords": "Тохирох бичлэг олдсонгүй",
"oPaginate": {
"sFirst": "Эхнийх",
"sLast": "Сүүлийнх",
"sNext": "Өмнөх",
"sPrevious": "Дараах"
},
"oAria": {
"sSortAscending": ": цагаан толгойн дарааллаар эрэмбэлэх",
"sSortDescending": ": цагаан толгойн эсрэг дарааллаар эрэмбэлэх"
}
}
\ No newline at end of file
{
"sEmptyTable": "Tiada data",
"sInfo": "Paparan dari _START_ hingga _END_ dari _TOTAL_ rekod",
"sInfoEmpty": "Paparan 0 hingga 0 dari 0 rekod",
"sInfoFiltered": "(Ditapis dari jumlah _MAX_ rekod)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Papar _MENU_ rekod",
"sLoadingRecords": "Diproses...",
"sProcessing": "Sedang diproses...",
"sSearch": "Carian:",
"sZeroRecords": "Tiada padanan rekod yang dijumpai.",
"oPaginate": {
"sFirst": "Pertama",
"sPrevious": "Sebelum",
"sNext": "Kemudian",
"sLast": "Akhir"
},
"oAria": {
"sSortAscending": ": diaktifkan kepada susunan lajur menaik",
"sSortDescending": ": diaktifkan kepada susunan lajur menurun"
}
}
\ No newline at end of file
{
"sEmptyTable": "Ingen data tilgjengelig i tabellen",
"sInfo": "Viser _START_ til _END_ av _TOTAL_ linjer",
"sInfoEmpty": "Viser 0 til 0 av 0 linjer",
"sInfoFiltered": "(filtrert fra _MAX_ totalt antall linjer)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLoadingRecords": "Laster...",
"sLengthMenu": "Vis _MENU_ linjer",
"sProcessing": "Laster...",
"sSearch": "S&oslash;k:",
"sUrl": "",
"sZeroRecords": "Ingen linjer matcher s&oslash;ket",
"oPaginate": {
"sFirst": "F&oslash;rste",
"sPrevious": "Forrige",
"sNext": "Neste",
"sLast": "Siste"
},
"oAria": {
"sSortAscending": ": aktiver for å sortere kolonnen stigende",
"sSortDescending": ": aktiver for å sortere kolonnen synkende"
}
}
\ No newline at end of file
{
"sEmptyTable": "टेबलमा डाटा उपलब्ध भएन",
"sInfo": "_TOTAL_ रेकर्ड मध्य _START_ देखि _END_ रेकर्ड देखाउंदै",
"sInfoEmpty": "0 मध्य 0 देखि 0 रेकर्ड देखाउंदै",
"sInfoFiltered": "(_MAX_ कुल रेकर्डबाट छनौट गरिएको)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": " _MENU_ रेकर्ड देखाउने ",
"sLoadingRecords": "लोड हुँदैछ...",
"sProcessing": "प्रगति हुदैंछ ...",
"sSearch": "खोजी:",
"sUrl": "",
"sZeroRecords": "कुनै मिल्ने रेकर्ड फेला परेन",
"oPaginate": {
"sFirst": "प्रथम",
"sPrevious": "पछिल्लो",
"sNext": "अघिल्लो",
"sLast": "अन्तिम"
},
"oAria": {
"sSortAscending": ": अगाडिबाट अक्षरात्मक रूपमा क्रमबद्ध गराउने",
"sSortDescending": ": पछाडिबाट अक्षरात्मक रूपमा क्रमबद्ध गराउने"
}
}
\ No newline at end of file
{ {
"sProcessing": "Bezig...", "sProcessing": "Bezig...",
"sLengthMenu": "_MENU_ resultaten weergeven", "sLengthMenu": "_MENU_ resultaten weergeven",
"sZeroRecords": "Geen resultaten gevonden", "sZeroRecords": "Geen resultaten gevonden",
"sInfo": "_START_ tot _END_ van _TOTAL_ resultaten", "sInfo": "_START_ tot _END_ van _TOTAL_ resultaten",
"sInfoEmpty": "Geen resultaten om weer te geven", "sInfoEmpty": "Geen resultaten om weer te geven",
"sInfoFiltered": " (gefilterd uit _MAX_ resultaten)", "sInfoFiltered": " (gefilterd uit _MAX_ resultaten)",
"sInfoPostFix": "", "sInfoPostFix": "",
"sSearch": "Zoeken:", "sSearch": "Zoeken:",
"sEmptyTable": "Geen resultaten aanwezig in de tabel", "sEmptyTable": "Geen resultaten aanwezig in de tabel",
"sInfoThousands": ".", "sInfoThousands": ".",
"sLoadingRecords": "Een moment geduld aub - bezig met laden...", "sLoadingRecords": "Een moment geduld aub - bezig met laden...",
"oPaginate": { "oPaginate": {
"sFirst": "Eerste", "sFirst": "Eerste",
"sLast": "Laatste", "sLast": "Laatste",
"sNext": "Volgende", "sNext": "Volgende",
"sPrevious": "Vorige" "sPrevious": "Vorige"
} },
} "oAria": {
"sSortAscending": ": activeer om kolom oplopend te sorteren",
"sSortDescending": ": activeer om kolom aflopend te sorteren"
}
}
\ No newline at end of file
{
"sEmptyTable": "Inga data tilgjengeleg i tabellen",
"sInfo": "Syner _START_ til _END_ av _TOTAL_ linjer",
"sInfoEmpty": "Syner 0 til 0 av 0 linjer",
"sInfoFiltered": "(filtrert frå _MAX_ totalt antal linjer)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLoadingRecords": "Lastar...",
"sLengthMenu": "Syn _MENU_ linjer",
"sProcessing": "Lastar...",
"sSearch": "S&oslash;k:",
"sUrl": "",
"sZeroRecords": "Inga linjer treff p&aring; s&oslash;ket",
"oPaginate": {
"sFirst": "Fyrste",
"sPrevious": "Forrige",
"sNext": "Neste",
"sLast": "Siste"
},
"oAria": {
"sSortAscending": ": aktiver for å sortere kolonna stigande",
"sSortDescending": ": aktiver for å sortere kolonna synkande"
}
}
\ No newline at end of file
{
"processing": "Przetwarzanie...",
"search": "Szukaj:",
"lengthMenu": "Pokaż _MENU_ pozycji",
"info": "Pozycje od _START_ do _END_ z _TOTAL_ łącznie",
"infoEmpty": "Pozycji 0 z 0 dostępnych",
"infoFiltered": "(filtrowanie spośród _MAX_ dostępnych pozycji)",
"infoPostFix": "",
"loadingRecords": "Wczytywanie...",
"zeroRecords": "Nie znaleziono pasujących pozycji",
"emptyTable": "Brak danych",
"paginate": {
"first": "Pierwsza",
"previous": "Poprzednia",
"next": "Następna",
"last": "Ostatnia"
},
"aria": {
"sortAscending": ": aktywuj, by posortować kolumnę rosnąco",
"sortDescending": ": aktywuj, by posortować kolumnę malejąco"
}
}
\ No newline at end of file
{
"sEmptyTable": "جدول خالي دی",
"sInfo": "د _START_ څخه تر _END_ پوري، له ټولو _TOTAL_ څخه",
"sInfoEmpty": "د 0 څخه تر 0 پوري، له ټولو 0 څخه",
"sInfoFiltered": "(لټول سوي له ټولو _MAX_ څخه)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ کتاره وښايه",
"sLoadingRecords": "منتظر اوسئ...",
"sProcessing": "منتظر اوسئ...",
"sSearch": "لټون:",
"sZeroRecords": "د لټون مطابق معلومات و نه موندل سول",
"oPaginate": {
"sFirst": "لومړۍ",
"sLast": "وروستۍ",
"sNext": "بله",
"sPrevious": "شاته"
},
"oAria": {
"sSortAscending": ": په صعودي ډول مرتبول",
"sSortDescending": ": په نزولي ډول مرتبول"
}
}
\ No newline at end of file
{ {
"sEmptyTable": "Nenhum registro cadastrado", "sEmptyTable": "Nenhum registro encontrado",
"sInfo": "Visualizando _START_ a _END_ de _TOTAL_ registros", "sInfo": "Mostrando de _START_ até _END_ de _TOTAL_ registros",
"sInfoEmpty": "Visualizando 0 a 0 de 0 registros", "sInfoEmpty": "Mostrando 0 até 0 de 0 registros",
"sInfoFiltered": "(filtrado de _MAX_ registros)", "sInfoFiltered": "(Filtrados de _MAX_ registros)",
"sInfoPostFix": "", "sInfoPostFix": "",
"sInfoThousands": ",", "sInfoThousands": ".",
"sLengthMenu": "Exibir _MENU_ registros por página", "sLengthMenu": "_MENU_ resultados por página",
"sLoadingRecords": "Carregando...", "sLoadingRecords": "Carregando...",
"sProcessing": "Processando...", "sProcessing": "Processando...",
"sSearch": "Busca:", "sZeroRecords": "Nenhum registro encontrado",
"sZeroRecords": "Nenhum registro encontrado", "sSearch": "Pesquisar",
"oPaginate": { "oPaginate": {
"sFirst": "Primeira", "sNext": "Próximo",
"sLast": "Última", "sPrevious": "Anterior",
"sNext": "Próxima", "sFirst": "Primeiro",
"sPrevious": "Anterior" "sLast": "Último"
}, },
"oAria": { "oAria": {
"sSortAscending": ": ativar ordenação crescente", "sSortAscending": ": Ordenar colunas de forma ascendente",
"sSortDescending": ": ativar ordenação decrescente" "sSortDescending": ": Ordenar colunas de forma descendente"
} }
} }
\ No newline at end of file
{
"sProcessing": "A processar...",
"sLengthMenu": "Mostrar _MENU_ registos",
"sZeroRecords": "Não foram encontrados resultados",
"sInfo": "Mostrando de _START_ até _END_ de _TOTAL_ registos",
"sInfoEmpty": "Mostrando de 0 até 0 de 0 registos",
"sInfoFiltered": "(filtrado de _MAX_ registos no total)",
"sInfoPostFix": "",
"sSearch": "Procurar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primeiro",
"sPrevious": "Anterior",
"sNext": "Seguinte",
"sLast": "Último"
}
}
\ No newline at end of file
{
"sProcessing": "Proceseaza...",
"sLengthMenu": "Afiseaza _MENU_ inregistrari pe pagina",
"sZeroRecords": "Nu am gasit nimic - ne pare rau",
"sInfo": "Afisate de la _START_ la _END_ din _TOTAL_ inregistrari",
"sInfoEmpty": "Afisate de la 0 la 0 din 0 inregistrari",
"sInfoFiltered": "(filtrate dintr-un total de _MAX_ inregistrari)",
"sInfoPostFix": "",
"sSearch": "Cauta:",
"sUrl": "",
"oPaginate": {
"sFirst": "Prima",
"sPrevious": "Precedenta",
"sNext": "Urmatoarea",
"sLast": "Ultima"
}
}
\ No newline at end of file
{
"processing": "Подождите...",
"search": "Поиск:",
"lengthMenu": "Показать _MENU_ записей",
"info": "Записи с _START_ до _END_ из _TOTAL_ записей",
"infoEmpty": "Записи с 0 до 0 из 0 записей",
"infoFiltered": "(отфильтровано из _MAX_ записей)",
"infoPostFix": "",
"loadingRecords": "Загрузка записей...",
"zeroRecords": "Записи отсутствуют.",
"emptyTable": "В таблице отсутствуют данные",
"paginate": {
"first": "Первая",
"previous": "Предыдущая",
"next": "Следующая",
"last": "Последняя"
},
"aria": {
"sortAscending": ": активировать для сортировки столбца по возрастанию",
"sortDescending": ": активировать для сортировки столбца по убыванию"
}
}
\ No newline at end of file
{
"sEmptyTable": "වගුවේ දත්ත කිසිවක් නොමැත",
"sInfo": "_TOTAL_ න් _START_ සිට _END_ දක්වා",
"sInfoEmpty": "0 න් 0 සිට 0 දක්වා",
"sInfoFiltered": "(_MAX_ න් තෝරාගත් )",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ ක් පෙන්වන්න",
"sLoadingRecords": "පූරණය වෙමින් පවතී...",
"sProcessing": "සැකසෙමින් පවතී...",
"sSearch": "සොයන්න :",
"sZeroRecords": "ගැලපෙන වාර්තා නොමැත.",
"oPaginate": {
"sFirst": "පළමු",
"sLast": "අන්තිම",
"sNext": "ඊළග",
"sPrevious": "පසුගිය"
},
"oAria": {
"sSortAscending": ": තීරුව ආරෝහනව තෝරන්න",
"sSortDescending": ": තීරුව අවරෝහනව තෝරන්න"
}
}
\ No newline at end of file
{
"sEmptyTable": "Nie sú k dispozícii žiadne dáta",
"sInfo": "Záznamy _START_ až _END_ z celkom _TOTAL_",
"sInfoEmpty": "Záznamy 0 až 0 z celkom 0 ",
"sInfoFiltered": "(vyfiltrované spomedzi _MAX_ záznamov)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Zobraz _MENU_ záznamov",
"sLoadingRecords": "Načítavam...",
"sProcessing": "Spracúvam...",
"sSearch": "Hľadať:",
"sZeroRecords": "Nenašli sa žiadne vyhovujúce záznamy",
"oPaginate": {
"sFirst": "Prvá",
"sLast": "Posledná",
"sNext": "Nasledujúca",
"sPrevious": "Predchádzajúca"
},
"oAria": {
"sSortAscending": ": aktivujte na zoradenie stĺpca vzostupne",
"sSortDescending": ": aktivujte na zoradenie stĺpca zostupne"
}
}
\ No newline at end of file
{
"sEmptyTable": "Nobenih podatkov ni na voljo",
"sInfo": "Prikazujem _START_ do _END_ od _TOTAL_ zapisov",
"sInfoEmpty": "Prikazujem 0 do 0 od 0 zapisov",
"sInfoFiltered": "(filtrirano od _MAX_ vseh zapisov)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Prikaži _MENU_ zapisov",
"sLoadingRecords": "Nalagam...",
"sProcessing": "Obdelujem...",
"sSearch": "Išči:",
"sZeroRecords": "Nobeden zapis ne ustreza",
"oPaginate": {
"sFirst": "Prvi",
"sLast": "Zadnji",
"sNext": "Nasl.",
"sPrevious": "Pred."
},
"oAria": {
"sSortAscending": ": vključite za naraščujoči sort",
"sSortDescending": ": vključite za padajoči sort"
}
}
\ No newline at end of file
{
"sEmptyTable": "Nuk ka asnjë të dhënë në tabele",
"sInfo": "Duke treguar _START_ deri _END_ prej _TOTAL_ reshtave",
"sInfoEmpty": "Duke treguar 0 deri 0 prej 0 reshtave",
"sInfoFiltered": "(të filtruara nga gjithësej _MAX_ reshtave)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Shiko _MENU_ reshta",
"sLoadingRecords": "Duke punuar...",
"sProcessing": "Duke procesuar...",
"sSearch": "Kërkoni:",
"sZeroRecords": "Asnjë e dhënë nuk u gjet",
"oPaginate": {
"sFirst": "E para",
"sLast": "E Fundit",
"sNext": "Tjetra",
"sPrevious": "E Kaluara"
},
"oAria": {
"sSortAscending": ": aktivizo për të sortuar kolumnin me vlera në ngritje",
"sSortDescending": ": aktivizo për të sortuar kolumnin me vlera në zbritje"
}
}
\ No newline at end of file
{
"sProcessing": "Procesiranje u toku...",
"sLengthMenu": "Prikaži _MENU_ elemenata",
"sZeroRecords": "Nije pronađen nijedan rezultat",
"sInfo": "Prikaz _START_ do _END_ od ukupno _TOTAL_ elemenata",
"sInfoEmpty": "Prikaz 0 do 0 od ukupno 0 elemenata",
"sInfoFiltered": "(filtrirano od ukupno _MAX_ elemenata)",
"sInfoPostFix": "",
"sSearch": "Pretraga:",
"sUrl": "",
"oPaginate": {
"sFirst": "Početna",
"sPrevious": "Prethodna",
"sNext": "Sledeća",
"sLast": "Poslednja"
}
}
\ No newline at end of file
{
"sEmptyTable": "Tabellen innehåller ingen data",
"sInfo": "Visar _START_ till _END_ av totalt _TOTAL_ rader",
"sInfoEmpty": "Visar 0 till 0 av totalt 0 rader",
"sInfoFiltered": "(filtrerade från totalt _MAX_ rader)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "Visa _MENU_ rader",
"sLoadingRecords": "Laddar...",
"sProcessing": "Bearbetar...",
"sSearch": "Sök:",
"sZeroRecords": "Hittade inga matchande resultat",
"oPaginate": {
"sFirst": "Första",
"sLast": "Sista",
"sNext": "Nästa",
"sPrevious": "Föregående"
},
"oAria": {
"sSortAscending": ": aktivera för att sortera kolumnen i stigande ordning",
"sSortDescending": ": aktivera för att sortera kolumnen i fallande ordning"
}
}
\ No newline at end of file
{
"sEmptyTable": "Hakuna data iliyo patikana",
"sInfo": "Inaonyesha _START_ mpaka _END_ ya matokeo _TOTAL_",
"sInfoEmpty": "Inaonyesha 0 hadi 0 ya matokeo 0",
"sInfoFiltered": "(uschujo kutoka matokeo idadi _MAX_)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Onyesha _MENU_ matokeo",
"sLoadingRecords": "Inapakia...",
"sProcessing": "Processing...",
"sSearch": "Tafuta:",
"sZeroRecords": "Rekodi vinavyolingana haziku patikana",
"oPaginate": {
"sFirst": "Mwanzo",
"sLast": "Mwisho",
"sNext": "Ijayo",
"sPrevious": "Kabla"
},
"oAria": {
"sSortAscending": ": seti kulainisha sanjari kwa mtindo wa upandaji",
"sSortDescending": ": seti kulainisha sanjari kwa mtindo wa mteremko"
}
}
\ No newline at end of file
{
"sEmptyTable": "அட்டவணையில் தரவு கிடைக்கவில்லை",
"sInfo": "உள்ளீடுகளை் _START_ முதல _END_ உள்ள _TOTAL_ காட்டும்",
"sInfoEmpty": "0 உள்ளீடுகளை 0 0 காட்டும்",
"sInfoFiltered": "(_MAX_ மொத்த உள்ளீடுகளை இருந்து வடிகட்டி)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ காண்பி",
"sLoadingRecords": "ஏற்றுகிறது ...",
"sProcessing": "செயலாக்க ...",
"sSearch": "தேடல்:",
"sZeroRecords": "பொருத்தமான பதிவுகள் இல்லை",
"oPaginate": {
"sFirst": "முதல்",
"sLast": "இறுதி",
"sNext": "அடுத்து",
"sPrevious": "முந்தைய"
},
"oAria": {
"sSortAscending": ": நிரலை ஏறுவரிசையில் வரிசைப்படுத்த செயல்படுத்த",
"sSortDescending": ": நிரலை இறங்கு வரிசைப்படுத்த செயல்படுத்த"
}
}
\ No newline at end of file
{
"sEmptyTable": "పట్టికలో డేటా లేదు.",
"sInfo": "మొత్తం _TOTAL_ ఎంట్రీలులో _START_ నుండి _END_ వరకు చూపిస్తున్నాం",
"sInfoEmpty": "చూపిస్తున్నాం 0 నుండి 0 వరకు 0 ఎంట్రీలు లో",
"sInfoFiltered": "( _MAX_ ఎంట్రీలులో నుండి వడపోయాబడినవి)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": " _MENU_ ఎంట్రీలు చూపించు",
"sLoadingRecords": "లోడ్ అవుతుంది ...",
"sProcessing": "ప్రాసెస్ చేయబడుతుంది...",
"sSearch": "వెతుకు:",
"sZeroRecords": "మ్యాచింగ్ రికార్డులు లేవు",
"oPaginate": {
"sFirst": "మొదటి",
"sLast": "చివరి",
"sNext": "తర్వాత",
"sPrevious": "మునుపటి"
},
"oAria": {
"sSortAscending": ": నిలువరుసను ఆరోహణ క్రమం అమర్చండి",
"sSortDescending": ": నిలువరుసను అవరోహణ క్రమం అమర్చండి"
}
}
\ No newline at end of file
{
"sProcessing": "กำลังดำเนินการ...",
"sLengthMenu": "แสดง _MENU_ แถว",
"sZeroRecords": "ไม่พบข้อมูล",
"sInfo": "แสดง _START_ ถึง _END_ จาก _TOTAL_ แถว",
"sInfoEmpty": "แสดง 0 ถึง 0 จาก 0 แถว",
"sInfoFiltered": "(กรองข้อมูล _MAX_ ทุกแถว)",
"sInfoPostFix": "",
"sSearch": "ค้นหา: ",
"sUrl": "",
"oPaginate": {
"sFirst": "หน้าแรก",
"sPrevious": "ก่อนหน้า",
"sNext": "ถัดไป",
"sLast": "หน้าสุดท้าย"
}
}
\ No newline at end of file
{
"sDecimal": ",",
"sEmptyTable": "Tabloda herhangi bir veri mevcut değil",
"sInfo": "_TOTAL_ kayıttan _START_ - _END_ arasındaki kayıtlar gösteriliyor",
"sInfoEmpty": "Kayıt yok",
"sInfoFiltered": "(_MAX_ kayıt içerisinden bulunan)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Sayfada _MENU_ kayıt göster",
"sLoadingRecords": "Yükleniyor...",
"sProcessing": "İşleniyor...",
"sSearch": "Ara:",
"sZeroRecords": "Eşleşen kayıt bulunamadı",
"oPaginate": {
"sFirst": "İlk",
"sLast": "Son",
"sNext": "Sonraki",
"sPrevious": "Önceki"
},
"oAria": {
"sSortAscending": ": artan sütun sıralamasını aktifleştir",
"sSortDescending": ": azalan sütun soralamasını aktifleştir"
}
}
\ No newline at end of file
{
"sProcessing": "Зачекайте...",
"sLengthMenu": "Показати _MENU_ записів",
"sZeroRecords": "Записи відсутні.",
"sInfo": "Записи з _START_ по _END_ із _TOTAL_ записів",
"sInfoEmpty": "Записи з 0 по 0 із 0 записів",
"sInfoFiltered": "(відфільтровано з _MAX_ записів)",
"sInfoPostFix": "",
"sSearch": "Пошук:",
"sUrl": "",
"oPaginate": {
"sFirst": "Перша",
"sPrevious": "Попередня",
"sNext": "Наступна",
"sLast": "Остання"
},
"oAria": {
"sSortAscending": ": активувати для сортування стовпців за зростанням",
"sSortDescending": ": активувати для сортування стовпців за спаданням"
}
}
\ No newline at end of file
{
"sProcessing": "ہے جاري عملدرامد...",
"sLengthMenu": "دکہائين شقيں کي (_MENU_) فہرست",
"sZeroRecords": "ملے نہيں مفروضات جلتے ملتے کوئ",
"sInfo": "فہرست کي تک _END_ سے _START_ سے ميں _TOTAL_ فہرست پوري ہے نظر پيش",
"sInfoEmpty": "فہرست کي تک 0 سے 0 سے ميں 0 قل ہے نظر پيشّ",
"sInfoFiltered": "(فہرست ہوئ چھني سے ميں _MAX_ قل)",
"sInfoPostFix": "",
"sSearch": "کرو تلاش:",
"sUrl": "",
"oPaginate": {
"sFirst": "پہلا",
"sPrevious": "پچہلا",
"sNext": "اگلا",
"sLast": "آخري"
}
}
\ No newline at end of file
{
"sEmptyTable": "Ma'lumot yo'q",
"sInfo": "Umumiy _TOTAL_ yozuvlarlardan _START_ dan _END_ gachasi ko'rsatilmoqda",
"sInfoEmpty": "Umumiy 0 yozuvlardan 0 dan 0 gachasi ko'rsatilmoqda",
"sInfoFiltered": "(_MAX_ yozuvlardan filtrlandi)",
"sInfoPostFix": "",
"sLengthMenu": "_MENU_ ta yozuvlarni ko'rsat",
"sLoadingRecords": "Yozuvlar yuklanmoqda...",
"sProcessing": "Ishlayapman...",
"sSearch": "Izlash:",
"sZeroRecords": "Ma'lumot yo'q.",
"oPaginate": {
"sFirst": "Birinchi",
"sPrevious": "Avvalgi",
"sNext": "Keyingi",
"sLast": "Son'ggi"
},
"oAria": {
"sSortAscending": ": to'g'ri tartiblash",
"sSortDescending": ": teskari tartiblash"
}
}
\ No newline at end of file
{
"sProcessing": "Đang xử lý...",
"sLengthMenu": "Xem _MENU_ mục",
"sZeroRecords": "Không tìm thấy dòng nào phù hợp",
"sInfo": "Đang xem _START_ đến _END_ trong tổng số _TOTAL_ mục",
"sInfoEmpty": "Đang xem 0 đến 0 trong tổng số 0 mục",
"sInfoFiltered": "(được lọc từ _MAX_ mục)",
"sInfoPostFix": "",
"sSearch": "Tìm:",
"sUrl": "",
"oPaginate": {
"sFirst": "Đầu",
"sPrevious": "Trước",
"sNext": "Tiếp",
"sLast": "Cuối"
}
}
\ No newline at end of file
{
"processing":   "處理中...",
"loadingRecords": "載入中...",
"lengthMenu":   "顯示 _MENU_ 項結果",
"zeroRecords":  "沒有符合的結果",
"info":         "顯示第 _START_ 至 _END_ 項結果,共 _TOTAL_ 項",
"infoEmpty":    "顯示第 0 至 0 項結果,共 0 項",
"infoFiltered": "(從 _MAX_ 項結果中過濾)",
"infoPostFix":  "",
"search":       "搜尋:",
"paginate": {
"first":    "第一頁",
"previous": "上一頁",
"next":     "下一頁",
"last":     "最後一頁"
},
"aria": {
"sortAscending": ": 升冪排列",
"sortDescending": ": 降冪排列"
}
}
\ No newline at end of file
{ {
"sEmptyTable": "无数据", "sProcessing": "处理中...",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项", "sLengthMenu": "显示 _MENU_ 项结果",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项", "sZeroRecords": "没有匹配结果",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)", "sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoPostFix": "", "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoThousands": ",", "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sLengthMenu": "显示 _MENU_ 项结果", "sInfoPostFix": "",
"sLoadingRecords": "载入中...", "sSearch": "搜索:",
"sProcessing": "处理中...", "sUrl": "",
"sSearch": "搜索:", "sEmptyTable": "表中数据为空",
"sZeroRecords": "没有匹配结果", "sLoadingRecords": "载入中...",
"oPaginate": { "sInfoThousands": ",",
"sFirst": "首页", "oPaginate": {
"sLast": "末页", "sFirst": "首页",
"sNext": "下页", "sPrevious": "上页",
"sPrevious": "上页" "sNext": "下页",
}, "sLast": "末页"
"oAria": { },
"sSortAscending": ": 以升序排列此列", "oAria": {
"sSortDescending": ": 以降序排列此列" "sSortAscending": ": 以升序排列此列",
} "sSortDescending": ": 以降序排列此列"
}
} }
\ No newline at end of file
$( document ).ready(function() { $( document ).ready(function() {
Dropzone.autoDiscover = false; Dropzone.autoDiscover = false;
/* Adaptation to resumable uploads
* src: https://github.com/enyo/dropzone/issues/339#issuecomment-138644461
*/
var originalDropzone = Dropzone.prototype.uploadFiles;
Dropzone.prototype.uploadFiles = function (files) {
var resumable = new Resumable ({
target: Asgard.dropzonePostUrl,
maxFiles: Dropzone.prototype.defaultOptions.maxFiles || 10,
simultaneousUploads: Dropzone.prototype.defaultOptions.parallelUploads,
headers: {
'Authorization': AuthorizationHeaderValue
},
testChunks: false
});
if (resumable.support) {
for (var j = 0; j < files.length; j++) {
var fileLocal = files[j];
resumable.addFile(fileLocal);
}
resumable.on('fileAdded', function (file) {
resumable.upload();
});
resumable.on('fileProgress', function (file) {
var progressValue = Math.floor(resumable.progress() * 100);
Dropzone.prototype.defaultOptions.uploadprogress(file.file, progressValue, null);
});
resumable.on('fileSuccess', (function(_this) {
return function (file) {
return _this._finished([file.file], "success", null);
}
})(this));
resumable.on('error', (function(_this) {
return function (message, file) {
return _this._errorProcessing([file.file], message, null);
}
})(this));
} else {
//Fallback to original implementation
return originalDropzone.apply(this, arguments);
}
};
var myDropzone = new Dropzone(".dropzone", { var myDropzone = new Dropzone(".dropzone", {
url: Asgard.dropzonePostUrl, url: Asgard.dropzonePostUrl,
autoProcessQueue: true, autoProcessQueue: true,
......
/*
* MIT Licensed
* http://www.23developer.com/opensource
* http://github.com/23/resumable.js
* Steffen Tiedemann Christensen, steffen@23company.com
*/
(function(){
"use strict";
var Resumable = function(opts){
if ( !(this instanceof Resumable) ) {
return new Resumable(opts);
}
this.version = 1.0;
// SUPPORTED BY BROWSER?
// Check if these features are support by the browser:
// - File object type
// - Blob object type
// - FileList object type
// - slicing files
this.support = (
(typeof(File)!=='undefined')
&&
(typeof(Blob)!=='undefined')
&&
(typeof(FileList)!=='undefined')
&&
(!!Blob.prototype.webkitSlice||!!Blob.prototype.mozSlice||!!Blob.prototype.slice||false)
);
if(!this.support) return(false);
// PROPERTIES
var $ = this;
$.files = [];
$.defaults = {
chunkSize:1*1024*1024,
forceChunkSize:false,
simultaneousUploads:3,
fileParameterName:'file',
chunkNumberParameterName: 'resumableChunkNumber',
chunkSizeParameterName: 'resumableChunkSize',
currentChunkSizeParameterName: 'resumableCurrentChunkSize',
totalSizeParameterName: 'resumableTotalSize',
typeParameterName: 'resumableType',
identifierParameterName: 'resumableIdentifier',
fileNameParameterName: 'resumableFilename',
relativePathParameterName: 'resumableRelativePath',
totalChunksParameterName: 'resumableTotalChunks',
throttleProgressCallbacks: 0.5,
query:{},
headers:{},
preprocess:null,
method:'multipart',
uploadMethod: 'POST',
testMethod: 'GET',
prioritizeFirstAndLastChunk:false,
target:'/',
testTarget: null,
parameterNamespace:'',
testChunks:true,
generateUniqueIdentifier:null,
getTarget:null,
maxChunkRetries:100,
chunkRetryInterval:undefined,
permanentErrors:[400, 404, 415, 500, 501],
maxFiles:undefined,
withCredentials:false,
xhrTimeout:0,
clearInput:true,
maxFilesErrorCallback:function (files, errorCount) {
var maxFiles = $.getOpt('maxFiles');
alert('Please upload no more than ' + maxFiles + ' file' + (maxFiles === 1 ? '' : 's') + ' at a time.');
},
minFileSize:1,
minFileSizeErrorCallback:function(file, errorCount) {
alert(file.fileName||file.name +' is too small, please upload files larger than ' + $h.formatSize($.getOpt('minFileSize')) + '.');
},
maxFileSize:undefined,
maxFileSizeErrorCallback:function(file, errorCount) {
alert(file.fileName||file.name +' is too large, please upload files less than ' + $h.formatSize($.getOpt('maxFileSize')) + '.');
},
fileType: [],
fileTypeErrorCallback: function(file, errorCount) {
alert(file.fileName||file.name +' has type not allowed, please upload files of type ' + $.getOpt('fileType') + '.');
}
};
$.opts = opts||{};
$.getOpt = function(o) {
var $opt = this;
// Get multiple option if passed an array
if(o instanceof Array) {
var options = {};
$h.each(o, function(option){
options[option] = $opt.getOpt(option);
});
return options;
}
// Otherwise, just return a simple option
if ($opt instanceof ResumableChunk) {
if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
else { $opt = $opt.fileObj; }
}
if ($opt instanceof ResumableFile) {
if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
else { $opt = $opt.resumableObj; }
}
if ($opt instanceof Resumable) {
if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
else { return $opt.defaults[o]; }
}
};
// EVENTS
// catchAll(event, ...)
// fileSuccess(file), fileProgress(file), fileAdded(file, event), filesAdded(files, filesSkipped), fileRetry(file),
// fileError(file, message), complete(), progress(), error(message, file), pause()
$.events = [];
$.on = function(event,callback){
$.events.push(event.toLowerCase(), callback);
};
$.fire = function(){
// `arguments` is an object, not array, in FF, so:
var args = [];
for (var i=0; i<arguments.length; i++) args.push(arguments[i]);
// Find event listeners, and support pseudo-event `catchAll`
var event = args[0].toLowerCase();
for (var i=0; i<=$.events.length; i+=2) {
if($.events[i]==event) $.events[i+1].apply($,args.slice(1));
if($.events[i]=='catchall') $.events[i+1].apply(null,args);
}
if(event=='fileerror') $.fire('error', args[2], args[1]);
if(event=='fileprogress') $.fire('progress');
};
// INTERNAL HELPER METHODS (handy, but ultimately not part of uploading)
var $h = {
stopEvent: function(e){
e.stopPropagation();
e.preventDefault();
},
each: function(o,callback){
if(typeof(o.length)!=='undefined') {
for (var i=0; i<o.length; i++) {
// Array or FileList
if(callback(o[i])===false) return;
}
} else {
for (i in o) {
// Object
if(callback(i,o[i])===false) return;
}
}
},
generateUniqueIdentifier:function(file, event){
var custom = $.getOpt('generateUniqueIdentifier');
if(typeof custom === 'function') {
return custom(file, event);
}
var relativePath = file.webkitRelativePath||file.fileName||file.name; // Some confusion in different versions of Firefox
var size = file.size;
return(size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, ''));
},
contains:function(array,test) {
var result = false;
$h.each(array, function(value) {
if (value == test) {
result = true;
return false;
}
return true;
});
return result;
},
formatSize:function(size){
if(size<1024) {
return size + ' bytes';
} else if(size<1024*1024) {
return (size/1024.0).toFixed(0) + ' KB';
} else if(size<1024*1024*1024) {
return (size/1024.0/1024.0).toFixed(1) + ' MB';
} else {
return (size/1024.0/1024.0/1024.0).toFixed(1) + ' GB';
}
},
getTarget:function(request, params){
var target = $.getOpt('target');
if (request === 'test' && $.getOpt('testTarget')) {
target = $.getOpt('testTarget') === '/' ? $.getOpt('target') : $.getOpt('testTarget');
}
if (typeof target === 'function') {
return target(params);
}
var separator = target.indexOf('?') < 0 ? '?' : '&';
var joinedParams = params.join('&');
return target + separator + joinedParams;
}
};
var onDrop = function(event){
$h.stopEvent(event);
//handle dropped things as items if we can (this lets us deal with folders nicer in some cases)
if (event.dataTransfer && event.dataTransfer.items) {
loadFiles(event.dataTransfer.items, event);
}
//else handle them as files
else if (event.dataTransfer && event.dataTransfer.files) {
loadFiles(event.dataTransfer.files, event);
}
};
var preventDefault = function(e) {
e.preventDefault();
};
/**
* processes a single upload item (file or directory)
* @param {Object} item item to upload, may be file or directory entry
* @param {string} path current file path
* @param {File[]} items list of files to append new items to
* @param {Function} cb callback invoked when item is processed
*/
function processItem(item, path, items, cb) {
var entry;
if(item.isFile){
// file provided
return item.file(function(file){
file.relativePath = path + file.name;
items.push(file);
cb();
});
}else if(item.isDirectory){
// item is already a directory entry, just assign
entry = item;
}else if(item instanceof File) {
items.push(item);
}
if('function' === typeof item.webkitGetAsEntry){
// get entry from file object
entry = item.webkitGetAsEntry();
}
if(entry && entry.isDirectory){
// directory provided, process it
return processDirectory(entry, path + entry.name + '/', items, cb);
}
if('function' === typeof item.getAsFile){
// item represents a File object, convert it
item = item.getAsFile();
item.relativePath = path + item.name;
items.push(item);
}
cb(); // indicate processing is done
}
/**
* cps-style list iteration.
* invokes all functions in list and waits for their callback to be
* triggered.
* @param {Function[]} items list of functions expecting callback parameter
* @param {Function} cb callback to trigger after the last callback has been invoked
*/
function processCallbacks(items, cb){
if(!items || items.length === 0){
// empty or no list, invoke callback
return cb();
}
// invoke current function, pass the next part as continuation
items[0](function(){
processCallbacks(items.slice(1), cb);
});
}
/**
* recursively traverse directory and collect files to upload
* @param {Object} directory directory to process
* @param {string} path current path
* @param {File[]} items target list of items
* @param {Function} cb callback invoked after traversing directory
*/
function processDirectory (directory, path, items, cb) {
var dirReader = directory.createReader();
dirReader.readEntries(function(entries){
if(!entries.length){
// empty directory, skip
return cb();
}
// process all conversion callbacks, finally invoke own one
processCallbacks(
entries.map(function(entry){
// bind all properties except for callback
return processItem.bind(null, entry, path, items);
}),
cb
);
});
}
/**
* process items to extract files to be uploaded
* @param {File[]} items items to process
* @param {Event} event event that led to upload
*/
function loadFiles(items, event) {
if(!items.length){
return; // nothing to do
}
$.fire('beforeAdd');
var files = [];
processCallbacks(
Array.prototype.map.call(items, function(item){
// bind all properties except for callback
return processItem.bind(null, item, "", files);
}),
function(){
if(files.length){
// at least one file found
appendFilesFromFileList(files, event);
}
}
);
};
var appendFilesFromFileList = function(fileList, event){
// check for uploading too many files
var errorCount = 0;
var o = $.getOpt(['maxFiles', 'minFileSize', 'maxFileSize', 'maxFilesErrorCallback', 'minFileSizeErrorCallback', 'maxFileSizeErrorCallback', 'fileType', 'fileTypeErrorCallback']);
if (typeof(o.maxFiles)!=='undefined' && o.maxFiles<(fileList.length+$.files.length)) {
// if single-file upload, file is already added, and trying to add 1 new file, simply replace the already-added file
if (o.maxFiles===1 && $.files.length===1 && fileList.length===1) {
$.removeFile($.files[0]);
} else {
o.maxFilesErrorCallback(fileList, errorCount++);
return false;
}
}
var files = [], filesSkipped = [], remaining = fileList.length;
var decreaseReamining = function(){
if(!--remaining){
// all files processed, trigger event
if(!files.length && !filesSkipped.length){
// no succeeded files, just skip
return;
}
window.setTimeout(function(){
$.fire('filesAdded', files, filesSkipped);
},0);
}
};
$h.each(fileList, function(file){
var fileName = file.name;
if(o.fileType.length > 0){
var fileTypeFound = false;
for(var index in o.fileType){
var extension = '.' + o.fileType[index];
if(fileName.indexOf(extension, fileName.length - extension.length) !== -1){
fileTypeFound = true;
break;
}
}
if (!fileTypeFound) {
o.fileTypeErrorCallback(file, errorCount++);
return false;
}
}
if (typeof(o.minFileSize)!=='undefined' && file.size<o.minFileSize) {
o.minFileSizeErrorCallback(file, errorCount++);
return false;
}
if (typeof(o.maxFileSize)!=='undefined' && file.size>o.maxFileSize) {
o.maxFileSizeErrorCallback(file, errorCount++);
return false;
}
function addFile(uniqueIdentifier){
if (!$.getFromUniqueIdentifier(uniqueIdentifier)) {(function(){
file.uniqueIdentifier = uniqueIdentifier;
var f = new ResumableFile($, file, uniqueIdentifier);
$.files.push(f);
files.push(f);
f.container = (typeof event != 'undefined' ? event.srcElement : null);
window.setTimeout(function(){
$.fire('fileAdded', f, event)
},0);
})()} else {
filesSkipped.push(file);
};
decreaseReamining();
}
// directories have size == 0
var uniqueIdentifier = $h.generateUniqueIdentifier(file, event);
if(uniqueIdentifier && typeof uniqueIdentifier.then === 'function'){
// Promise or Promise-like object provided as unique identifier
uniqueIdentifier
.then(
function(uniqueIdentifier){
// unique identifier generation succeeded
addFile(uniqueIdentifier);
},
function(){
// unique identifier generation failed
// skip further processing, only decrease file count
decreaseReamining();
}
);
}else{
// non-Promise provided as unique identifier, process synchronously
addFile(uniqueIdentifier);
}
});
};
// INTERNAL OBJECT TYPES
function ResumableFile(resumableObj, file, uniqueIdentifier){
var $ = this;
$.opts = {};
$.getOpt = resumableObj.getOpt;
$._prevProgress = 0;
$.resumableObj = resumableObj;
$.file = file;
$.fileName = file.fileName||file.name; // Some confusion in different versions of Firefox
$.size = file.size;
$.relativePath = file.relativePath || file.webkitRelativePath || $.fileName;
$.uniqueIdentifier = uniqueIdentifier;
$._pause = false;
$.container = '';
var _error = uniqueIdentifier !== undefined;
// Callback when something happens within the chunk
var chunkEvent = function(event, message){
// event can be 'progress', 'success', 'error' or 'retry'
switch(event){
case 'progress':
$.resumableObj.fire('fileProgress', $);
break;
case 'error':
$.abort();
_error = true;
$.chunks = [];
$.resumableObj.fire('fileError', $, message);
break;
case 'success':
if(_error) return;
$.resumableObj.fire('fileProgress', $); // it's at least progress
if($.isComplete()) {
$.resumableObj.fire('fileSuccess', $, message);
}
break;
case 'retry':
$.resumableObj.fire('fileRetry', $);
break;
}
};
// Main code to set up a file object with chunks,
// packaged to be able to handle retries if needed.
$.chunks = [];
$.abort = function(){
// Stop current uploads
var abortCount = 0;
$h.each($.chunks, function(c){
if(c.status()=='uploading') {
c.abort();
abortCount++;
}
});
if(abortCount>0) $.resumableObj.fire('fileProgress', $);
};
$.cancel = function(){
// Reset this file to be void
var _chunks = $.chunks;
$.chunks = [];
// Stop current uploads
$h.each(_chunks, function(c){
if(c.status()=='uploading') {
c.abort();
$.resumableObj.uploadNextChunk();
}
});
$.resumableObj.removeFile($);
$.resumableObj.fire('fileProgress', $);
};
$.retry = function(){
$.bootstrap();
var firedRetry = false;
$.resumableObj.on('chunkingComplete', function(){
if(!firedRetry) $.resumableObj.upload();
firedRetry = true;
});
};
$.bootstrap = function(){
$.abort();
_error = false;
// Rebuild stack of chunks from file
$.chunks = [];
$._prevProgress = 0;
var round = $.getOpt('forceChunkSize') ? Math.ceil : Math.floor;
var maxOffset = Math.max(round($.file.size/$.getOpt('chunkSize')),1);
for (var offset=0; offset<maxOffset; offset++) {(function(offset){
window.setTimeout(function(){
$.chunks.push(new ResumableChunk($.resumableObj, $, offset, chunkEvent));
$.resumableObj.fire('chunkingProgress',$,offset/maxOffset);
},0);
})(offset)}
window.setTimeout(function(){
$.resumableObj.fire('chunkingComplete',$);
},0);
};
$.progress = function(){
if(_error) return(1);
// Sum up progress across everything
var ret = 0;
var error = false;
$h.each($.chunks, function(c){
if(c.status()=='error') error = true;
ret += c.progress(true); // get chunk progress relative to entire file
});
ret = (error ? 1 : (ret>0.99999 ? 1 : ret));
ret = Math.max($._prevProgress, ret); // We don't want to lose percentages when an upload is paused
$._prevProgress = ret;
return(ret);
};
$.isUploading = function(){
var uploading = false;
$h.each($.chunks, function(chunk){
if(chunk.status()=='uploading') {
uploading = true;
return(false);
}
});
return(uploading);
};
$.isComplete = function(){
var outstanding = false;
$h.each($.chunks, function(chunk){
var status = chunk.status();
if(status=='pending' || status=='uploading' || chunk.preprocessState === 1) {
outstanding = true;
return(false);
}
});
return(!outstanding);
};
$.pause = function(pause){
if(typeof(pause)==='undefined'){
$._pause = ($._pause ? false : true);
}else{
$._pause = pause;
}
};
$.isPaused = function() {
return $._pause;
};
// Bootstrap and return
$.resumableObj.fire('chunkingStart', $);
$.bootstrap();
return(this);
}
function ResumableChunk(resumableObj, fileObj, offset, callback){
var $ = this;
$.opts = {};
$.getOpt = resumableObj.getOpt;
$.resumableObj = resumableObj;
$.fileObj = fileObj;
$.fileObjSize = fileObj.size;
$.fileObjType = fileObj.file.type;
$.offset = offset;
$.callback = callback;
$.lastProgressCallback = (new Date);
$.tested = false;
$.retries = 0;
$.pendingRetry = false;
$.preprocessState = 0; // 0 = unprocessed, 1 = processing, 2 = finished
// Computed properties
var chunkSize = $.getOpt('chunkSize');
$.loaded = 0;
$.startByte = $.offset*chunkSize;
$.endByte = Math.min($.fileObjSize, ($.offset+1)*chunkSize);
if ($.fileObjSize-$.endByte < chunkSize && !$.getOpt('forceChunkSize')) {
// The last chunk will be bigger than the chunk size, but less than 2*chunkSize
$.endByte = $.fileObjSize;
}
$.xhr = null;
// test() makes a GET request without any data to see if the chunk has already been uploaded in a previous session
$.test = function(){
// Set up request and listen for event
$.xhr = new XMLHttpRequest();
var testHandler = function(e){
$.tested = true;
var status = $.status();
if(status=='success') {
$.callback(status, $.message());
$.resumableObj.uploadNextChunk();
} else {
$.send();
}
};
$.xhr.addEventListener('load', testHandler, false);
$.xhr.addEventListener('error', testHandler, false);
$.xhr.addEventListener('timeout', testHandler, false);
// Add data from the query options
var params = [];
var parameterNamespace = $.getOpt('parameterNamespace');
var customQuery = $.getOpt('query');
if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
$h.each(customQuery, function(k,v){
params.push([encodeURIComponent(parameterNamespace+k), encodeURIComponent(v)].join('='));
});
// Add extra data to identify chunk
params = params.concat(
[
// define key/value pairs for additional parameters
['chunkNumberParameterName', $.offset + 1],
['chunkSizeParameterName', $.getOpt('chunkSize')],
['currentChunkSizeParameterName', $.endByte - $.startByte],
['totalSizeParameterName', $.fileObjSize],
['typeParameterName', $.fileObjType],
['identifierParameterName', $.fileObj.uniqueIdentifier],
['fileNameParameterName', $.fileObj.fileName],
['relativePathParameterName', $.fileObj.relativePath],
['totalChunksParameterName', $.fileObj.chunks.length]
].filter(function(pair){
// include items that resolve to truthy values
// i.e. exclude false, null, undefined and empty strings
return $.getOpt(pair[0]);
})
.map(function(pair){
// map each key/value pair to its final form
return [
parameterNamespace + $.getOpt(pair[0]),
encodeURIComponent(pair[1])
].join('=');
})
);
// Append the relevant chunk and send it
$.xhr.open($.getOpt('testMethod'), $h.getTarget('test', params));
$.xhr.timeout = $.getOpt('xhrTimeout');
$.xhr.withCredentials = $.getOpt('withCredentials');
// Add data from header options
var customHeaders = $.getOpt('headers');
if(typeof customHeaders === 'function') {
customHeaders = customHeaders($.fileObj, $);
}
$h.each(customHeaders, function(k,v) {
$.xhr.setRequestHeader(k, v);
});
$.xhr.send(null);
};
$.preprocessFinished = function(){
$.preprocessState = 2;
$.send();
};
// send() uploads the actual data in a POST call
$.send = function(){
var preprocess = $.getOpt('preprocess');
if(typeof preprocess === 'function') {
switch($.preprocessState) {
case 0: $.preprocessState = 1; preprocess($); return;
case 1: return;
case 2: break;
}
}
if($.getOpt('testChunks') && !$.tested) {
$.test();
return;
}
// Set up request and listen for event
$.xhr = new XMLHttpRequest();
// Progress
$.xhr.upload.addEventListener('progress', function(e){
if( (new Date) - $.lastProgressCallback > $.getOpt('throttleProgressCallbacks') * 1000 ) {
$.callback('progress');
$.lastProgressCallback = (new Date);
}
$.loaded=e.loaded||0;
}, false);
$.loaded = 0;
$.pendingRetry = false;
$.callback('progress');
// Done (either done, failed or retry)
var doneHandler = function(e){
var status = $.status();
if(status=='success'||status=='error') {
$.callback(status, $.message());
$.resumableObj.uploadNextChunk();
} else {
$.callback('retry', $.message());
$.abort();
$.retries++;
var retryInterval = $.getOpt('chunkRetryInterval');
if(retryInterval !== undefined) {
$.pendingRetry = true;
setTimeout($.send, retryInterval);
} else {
$.send();
}
}
};
$.xhr.addEventListener('load', doneHandler, false);
$.xhr.addEventListener('error', doneHandler, false);
$.xhr.addEventListener('timeout', doneHandler, false);
// Set up the basic query data from Resumable
var query = [
['chunkNumberParameterName', $.offset + 1],
['chunkSizeParameterName', $.getOpt('chunkSize')],
['currentChunkSizeParameterName', $.endByte - $.startByte],
['totalSizeParameterName', $.fileObjSize],
['typeParameterName', $.fileObjType],
['identifierParameterName', $.fileObj.uniqueIdentifier],
['fileNameParameterName', $.fileObj.fileName],
['relativePathParameterName', $.fileObj.relativePath],
['totalChunksParameterName', $.fileObj.chunks.length],
].filter(function(pair){
// include items that resolve to truthy values
// i.e. exclude false, null, undefined and empty strings
return $.getOpt(pair[0]);
})
.reduce(function(query, pair){
// assign query key/value
query[$.getOpt(pair[0])] = pair[1];
return query;
}, {});
// Mix in custom data
var customQuery = $.getOpt('query');
if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
$h.each(customQuery, function(k,v){
query[k] = v;
});
var func = ($.fileObj.file.slice ? 'slice' : ($.fileObj.file.mozSlice ? 'mozSlice' : ($.fileObj.file.webkitSlice ? 'webkitSlice' : 'slice')));
var bytes = $.fileObj.file[func]($.startByte, $.endByte);
var data = null;
var params = [];
var parameterNamespace = $.getOpt('parameterNamespace');
if ($.getOpt('method') === 'octet') {
// Add data from the query options
data = bytes;
$h.each(query, function (k, v) {
params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
});
} else {
// Add data from the query options
data = new FormData();
$h.each(query, function (k, v) {
data.append(parameterNamespace + k, v);
params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
});
data.append(parameterNamespace + $.getOpt('fileParameterName'), bytes, $.fileObj.fileName);
}
var target = $h.getTarget('upload', params);
var method = $.getOpt('uploadMethod');
$.xhr.open(method, target);
if ($.getOpt('method') === 'octet') {
$.xhr.setRequestHeader('Content-Type', 'application/octet-stream');
}
$.xhr.timeout = $.getOpt('xhrTimeout');
$.xhr.withCredentials = $.getOpt('withCredentials');
// Add data from header options
var customHeaders = $.getOpt('headers');
if(typeof customHeaders === 'function') {
customHeaders = customHeaders($.fileObj, $);
}
$h.each(customHeaders, function(k,v) {
$.xhr.setRequestHeader(k, v);
});
$.xhr.send(data);
};
$.abort = function(){
// Abort and reset
if($.xhr) $.xhr.abort();
$.xhr = null;
};
$.status = function(){
// Returns: 'pending', 'uploading', 'success', 'error'
if($.pendingRetry) {
// if pending retry then that's effectively the same as actively uploading,
// there might just be a slight delay before the retry starts
return('uploading');
} else if(!$.xhr) {
return('pending');
} else if($.xhr.readyState<4) {
// Status is really 'OPENED', 'HEADERS_RECEIVED' or 'LOADING' - meaning that stuff is happening
return('uploading');
} else {
if($.xhr.status == 200 || $.xhr.status == 201) {
// HTTP 200, 201 (created)
return('success');
} else if($h.contains($.getOpt('permanentErrors'), $.xhr.status) || $.retries >= $.getOpt('maxChunkRetries')) {
// HTTP 415/500/501, permanent error
return('error');
} else {
// this should never happen, but we'll reset and queue a retry
// a likely case for this would be 503 service unavailable
$.abort();
return('pending');
}
}
};
$.message = function(){
return($.xhr ? $.xhr.responseText : '');
};
$.progress = function(relative){
if(typeof(relative)==='undefined') relative = false;
var factor = (relative ? ($.endByte-$.startByte)/$.fileObjSize : 1);
if($.pendingRetry) return(0);
if(!$.xhr || !$.xhr.status) factor*=.95;
var s = $.status();
switch(s){
case 'success':
case 'error':
return(1*factor);
case 'pending':
return(0*factor);
default:
return($.loaded/($.endByte-$.startByte)*factor);
}
};
return(this);
}
// QUEUE
$.uploadNextChunk = function(){
var found = false;
// In some cases (such as videos) it's really handy to upload the first
// and last chunk of a file quickly; this let's the server check the file's
// metadata and determine if there's even a point in continuing.
if ($.getOpt('prioritizeFirstAndLastChunk')) {
$h.each($.files, function(file){
if(file.chunks.length && file.chunks[0].status()=='pending' && file.chunks[0].preprocessState === 0) {
file.chunks[0].send();
found = true;
return(false);
}
if(file.chunks.length>1 && file.chunks[file.chunks.length-1].status()=='pending' && file.chunks[file.chunks.length-1].preprocessState === 0) {
file.chunks[file.chunks.length-1].send();
found = true;
return(false);
}
});
if(found) return(true);
}
// Now, simply look for the next, best thing to upload
$h.each($.files, function(file){
if(file.isPaused()===false){
$h.each(file.chunks, function(chunk){
if(chunk.status()=='pending' && chunk.preprocessState === 0) {
chunk.send();
found = true;
return(false);
}
});
}
if(found) return(false);
});
if(found) return(true);
// The are no more outstanding chunks to upload, check is everything is done
var outstanding = false;
$h.each($.files, function(file){
if(!file.isComplete()) {
outstanding = true;
return(false);
}
});
if(!outstanding) {
// All chunks have been uploaded, complete
$.fire('complete');
}
return(false);
};
// PUBLIC METHODS FOR RESUMABLE.JS
$.assignBrowse = function(domNodes, isDirectory){
if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
$h.each(domNodes, function(domNode) {
var input;
if(domNode.tagName==='INPUT' && domNode.type==='file'){
input = domNode;
} else {
input = document.createElement('input');
input.setAttribute('type', 'file');
input.style.display = 'none';
domNode.addEventListener('click', function(){
input.style.opacity = 0;
input.style.display='block';
input.focus();
input.click();
input.style.display='none';
}, false);
domNode.appendChild(input);
}
var maxFiles = $.getOpt('maxFiles');
if (typeof(maxFiles)==='undefined'||maxFiles!=1){
input.setAttribute('multiple', 'multiple');
} else {
input.removeAttribute('multiple');
}
if(isDirectory){
input.setAttribute('webkitdirectory', 'webkitdirectory');
} else {
input.removeAttribute('webkitdirectory');
}
// When new files are added, simply append them to the overall list
input.addEventListener('change', function(e){
appendFilesFromFileList(e.target.files,e);
var clearInput = $.getOpt('clearInput');
if (clearInput) {
e.target.value = '';
}
}, false);
});
};
$.assignDrop = function(domNodes){
if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
$h.each(domNodes, function(domNode) {
domNode.addEventListener('dragover', preventDefault, false);
domNode.addEventListener('dragenter', preventDefault, false);
domNode.addEventListener('drop', onDrop, false);
});
};
$.unAssignDrop = function(domNodes) {
if (typeof(domNodes.length) == 'undefined') domNodes = [domNodes];
$h.each(domNodes, function(domNode) {
domNode.removeEventListener('dragover', preventDefault);
domNode.removeEventListener('dragenter', preventDefault);
domNode.removeEventListener('drop', onDrop);
});
};
$.isUploading = function(){
var uploading = false;
$h.each($.files, function(file){
if (file.isUploading()) {
uploading = true;
return(false);
}
});
return(uploading);
};
$.upload = function(){
// Make sure we don't start too many uploads at once
if($.isUploading()) return;
// Kick off the queue
$.fire('uploadStart');
for (var num=1; num<=$.getOpt('simultaneousUploads'); num++) {
$.uploadNextChunk();
}
};
$.pause = function(){
// Resume all chunks currently being uploaded
$h.each($.files, function(file){
file.abort();
});
$.fire('pause');
};
$.cancel = function(){
$.fire('beforeCancel');
for(var i = $.files.length - 1; i >= 0; i--) {
$.files[i].cancel();
}
$.fire('cancel');
};
$.progress = function(){
var totalDone = 0;
var totalSize = 0;
// Resume all chunks currently being uploaded
$h.each($.files, function(file){
totalDone += file.progress()*file.size;
totalSize += file.size;
});
return(totalSize>0 ? totalDone/totalSize : 0);
};
$.addFile = function(file, event){
appendFilesFromFileList([file], event);
};
$.removeFile = function(file){
for(var i = $.files.length - 1; i >= 0; i--) {
if($.files[i] === file) {
$.files.splice(i, 1);
}
}
};
$.getFromUniqueIdentifier = function(uniqueIdentifier){
var ret = false;
$h.each($.files, function(f){
if(f.uniqueIdentifier==uniqueIdentifier) ret = f;
});
return(ret);
};
$.getSize = function(){
var totalSize = 0;
$h.each($.files, function(file){
totalSize += file.size;
});
return(totalSize);
};
$.handleDropEvent = function (e) {
onDrop(e);
};
$.handleChangeEvent = function (e) {
appendFilesFromFileList(e.target.files, e);
e.target.value = '';
};
$.updateQuery = function(query){
$.opts.query = query;
};
return(this);
};
// Node.js-style export for Node and Component
if (typeof module != 'undefined') {
module.exports = Resumable;
} else if (typeof define === "function" && define.amd) {
// AMD/requirejs: Define the module
define(function(){
return Resumable;
});
} else {
// Browser: Expose to window
window.Resumable = Resumable;
}
})();
\ No newline at end of file
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