PageSourceSearch

https://stats.gov.ck/wp-content/plugins/wp-file-download/app/admin/assets/js/resumable.js?ver=6.2.5

js stats.gov.ck collected 2026-09-24 23:56:09 UTC 43,718 bytes, 1,219 lines download raw bytes

vendor: 9,155 bytes, lines 1-262
1/*
2* MIT Licensed
3* https://www.twentythree.com
4* https://github.com/23/resumable.js
5* Steffen Fagerström Christensen, [email protected]
6*/
7
8(function(){
9  "use strict";
10
11  var Resumable = function(opts){
12    if ( !(this instanceof Resumable) ) {
13      return new Resumable(opts);
14    }
15    this.version = 1.0;
16    // SUPPORTED BY BROWSER?
17    // Check if these features are support by the browser:
18    // - File object type
19    // - Blob object type
20    // - FileList object type
21    // - slicing files
22    this.support = (
23      (typeof(File)!=='undefined')
24      &&
25      (typeof(Blob)!=='undefined')
26      &&
27      (typeof(FileList)!=='undefined')
28      &&
29      (!!Blob.prototype.webkitSlice||!!Blob.prototype.mozSlice||!!Blob.prototype.slice||false)
30    );
31    if(!this.support) return(false);
32
33
34    // PROPERTIES
35    var $ = this;
36    $.files = [];
37    $.defaults = {
38      chunkSize:1*1024*1024,
39      forceChunkSize:false,
40      simultaneousUploads:3,
41      fileParameterName:'file',
42      chunkNumberParameterName: 'resumableChunkNumber',
43      chunkSizeParameterName: 'resumableChunkSize',
44      currentChunkSizeParameterName: 'resumableCurrentChunkSize',
45      totalSizeParameterName: 'resumableTotalSize',
46      typeParameterName: 'resumableType',
47      identifierParameterName: 'resumableIdentifier',
48      fileNameParameterName: 'resumableFilename',
49      relativePathParameterName: 'resumableRelativePath',
50      totalChunksParameterName: 'resumableTotalChunks',
51      dragOverClass: 'dragover',
52      throttleProgressCallbacks: 0.5,
53      query:{},
54      headers:{},
55      preprocess:null,
56      preprocessFile:null,
57      method:'multipart',
58      uploadMethod: 'POST',
59      testMethod: 'GET',
60      prioritizeFirstAndLastChunk:false,
61      target:'/',
62      testTarget: null,
63      parameterNamespace:'',
64      testChunks:true,
65      generateUniqueIdentifier:null,
66      getTarget:null,
67      maxChunkRetries:100,
68      chunkRetryInterval:undefined,
69      permanentErrors:[400, 401, 403, 404, 409, 415, 500, 501],
70      maxFiles:undefined,
71      withCredentials:false,
72      xhrTimeout:0,
73      clearInput:true,
74      chunkFormat:'blob',
75      setChunkTypeFromFile:false,
76      maxFilesErrorCallback:function (files, errorCount) {
77        var maxFiles = $.getOpt('maxFiles');
78        alert('Please upload no more than ' + maxFiles + ' file' + (maxFiles === 1 ? '' : 's') + ' at a time.');
79      },
80      minFileSize:1,
81      minFileSizeErrorCallback:function(file, errorCount) {
82        alert(file.fileName||file.name +' is too small, please upload files larger than ' + $h.formatSize($.getOpt('minFileSize')) + '.');
83      },
84      maxFileSize:undefined,
85      maxFileSizeErrorCallback:function(file, errorCount) {
86        alert(file.fileName||file.name +' is too large, please upload files less than ' + $h.formatSize($.getOpt('maxFileSize')) + '.');
87      },
88      fileType: [],
89      fileTypeErrorCallback: function(file, errorCount) {
90        alert(file.fileName||file.name +' has type not allowed, please upload files of type ' + $.getOpt('fileType') + '.');
91      }
92    };
93    $.opts = opts||{};
94    $.getOpt = function(o) {
95      var $opt = this;
96      // Get multiple option if passed an array
97      if(o instanceof Array) {
98        var options = {};
99        $h.each(o, function(option){
100          options[option] = $opt.getOpt(option);
101        });
102        return options;
103      }
104      // Otherwise, just return a simple option
105      if ($opt instanceof ResumableChunk) {
106        if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
107        else { $opt = $opt.fileObj; }
108      }
109      if ($opt instanceof ResumableFile) {
110        if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
111        else { $opt = $opt.resumableObj; }
112      }
113      if ($opt instanceof Resumable) {
114        if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
115        else { return $opt.defaults[o]; }
116      }
117    };
118    $.indexOf = function(array, obj) {
119      if (array.indexOf) { return array.indexOf(obj); }
120      for (var i = 0; i < array.length; i++) {
121        if (array[i] === obj) { return i; }
122      }
123      return -1;
124    }
125
126    // EVENTS
127    // catchAll(event, ...)
128    // fileSuccess(file), fileProgress(file), fileAdded(file, event), filesAdded(files, filesSkipped), fileRetry(file),
129    // fileError(file, message), complete(), progress(), error(message, file), pause()
130    $.events = [];
131    $.on = function(event,callback){
132      $.events.push(event.toLowerCase(), callback);
133    };
134    $.fire = function(){
135      // `arguments` is an object, not array, in FF, so:
136      var args = [];
137      for (var i=0; i<arguments.length; i++) args.push(arguments[i]);
138      // Find event listeners, and support pseudo-event `catchAll`
139      var event = args[0].toLowerCase();
140      for (var i=0; i<=$.events.length; i+=2) {
141        if($.events[i]==event) $.events[i+1].apply($,args.slice(1));
142        if($.events[i]=='catchall') $.events[i+1].apply(null,args);
143      }
144      if(event=='fileerror') $.fire('error', args[2], args[1]);
145      if(event=='fileprogress') $.fire('progress');
146    };
147
148
149    // INTERNAL HELPER METHODS (handy, but ultimately not part of uploading)
150    var $h = {
151      stopEvent: function(e){
152        e.stopPropagation();
153        e.preventDefault();
154      },
155      each: function(o,callback){
156        if(typeof(o.length)!=='undefined') {
157          for (var i=0; i<o.length; i++) {
158            // Array or FileList
159            if(callback(o[i])===false) return;
160          }
161        } else {
162          for (i in o) {
163            // Object
164            if(callback(i,o[i])===false) return;
165          }
166        }
167      },
168      generateUniqueIdentifier:function(file, event){
169        var custom = $.getOpt('generateUniqueIdentifier');
170        if(typeof custom === 'function') {
171          return custom(file, event);
172        }
173        var relativePath = file.webkitRelativePath||file.relativePath||file.fileName||file.name; // Some confusion in different versions of Firefox
174        var size = file.size;
175        return(size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, ''));
176      },
177      contains:function(array,test) {
178        var result = false;
179
180        $h.each(array, function(value) {
181          if (value == test) {
182            result = true;
183            return false;
184          }
185          return true;
186        });
187
188        return result;
189      },
190      formatSize:function(size){
191        if(size<1024) {
192          return size + ' bytes';
193        } else if(size<1024*1024) {
194          return (size/1024.0).toFixed(0) + ' KB';
195        } else if(size<1024*1024*1024) {
196          return (size/1024.0/1024.0).toFixed(1) + ' MB';
197        } else {
198          return (size/1024.0/1024.0/1024.0).toFixed(1) + ' GB';
199        }
200      },
201      getTarget:function(request, params){
202        var target = $.getOpt('target');
203
204        if (request === 'test' && $.getOpt('testTarget')) {
205          target = $.getOpt('testTarget') === '/' ? $.getOpt('target') : $.getOpt('testTarget');
206        }
207
208        if (typeof target === 'function') {
209          return target(params);
210        }
211
212        var separator = target.indexOf('?') < 0 ? '?' : '&';
213        var joinedParams = params.join('&');
214
215        if (joinedParams) target = target + separator + joinedParams;
216
217        return target;
218      }
219    };
220
221    var onDrop = function(e){
222      e.currentTarget.classList.remove($.getOpt('dragOverClass'));
223      $h.stopEvent(e);
224
225      //handle dropped things as items if we can (this lets us deal with folders nicer in some cases)
226      if (e.dataTransfer && e.dataTransfer.items) {
227        loadFiles(e.dataTransfer.items, e);
228      }
229      //else handle them as files
230      else if (e.dataTransfer && e.dataTransfer.files) {
231        loadFiles(e.dataTransfer.files, e);
232      }
233    };
234    var onDragLeave = function(e){
235      e.currentTarget.classList.remove($.getOpt('dragOverClass'));
236    };
237    var onDragOverEnter = function(e) {
238      e.preventDefault();
239      var dt = e.dataTransfer;
240      if ($.indexOf(dt.types, "Files") >= 0) { // only for file drop
241        e.stopPropagation();
242        dt.dropEffect = "copy";
243        dt.effectAllowed = "copy";
244        e.currentTarget.classList.add($.getOpt('dragOverClass'));
245      } else { // not work on IE/Edge....
246        dt.dropEffect = "none";
247        dt.effectAllowed = "none";
248      }
249    };
250
251    /**
252     * processes a single upload item (file or directory)
253     * @param {Object} item item to upload, may be file or directory entry
254     * @param {string} path current file path
255     * @param {File[]} items list of files to append new items to
256     * @param {Function} cb callback invoked when item is processed
257     */
258    function processItem(item, path, items, cb) {
259      var entry;
260      if(item.isFile){
261        // file provided
262        return item.file(function(file){
263          file.relativePath = path + file.name;
264          items.push(file);
265          cb();
266        });
267      }else if(item.isDirectory){
268        // item is already a directory entry, just assign
269        entry = item;
270      }else if(item instanceof File) {
271        items.push(item);
272      }
273      if('function' === typeof item.webkitGetAsEntry){
274        // get entry from file object
275        entry = item.webkitGetAsEntry();
276      }
277      if(entry && entry.isDirectory){
278        // directory provided, process it
279        return processDirectory(entry, path + entry.name + '/', items, cb);
280      }
281      if('function' === typeof item.getAsFile){
282        // item represents a File object, convert it
283        item = item.getAsFile();
284        if(item instanceof File) {
285          item.relativePath = path + item.name;
286          items.push(item);
287        }
288      }
289      cb(); // indicate processing is done
290    }
291
292
293    /**
294     * cps-style list iteration.
295     * invokes all functions in list and waits for their callback to be
296     * triggered.
297     * @param  {Function[]}   items list of functions expecting callback parameter
298     * @param  {Function} cb    callback to trigger after the last callback has been invoked
299     */
300    function processCallbacks(items, cb){
301      if(!items || items.length === 0){
302        // empty or no list, invoke callback
303        return cb();
304      }
305      // invoke current function, pass the next part as continuation
306      items[0](function(){
307        processCallbacks(items.slice(1), cb);
308      });
309    }
310
311    /**
312     * recursively traverse directory and collect files to upload
313     * @param  {Object}   directory directory to process
314     * @param  {string}   path      current path
315     * @param  {File[]}   items     target list of items
316     * @param  {Function} cb        callback invoked after traversing directory
317     */
318    function processDirectory (directory, path, items, cb) {
319      var dirReader = directory.createReader();
320      var allEntries = [];
321
322      function readEntries () {
323        dirReader.readEntries(function(entries){
324          if (entries.length) {
325            allEntries = allEntries.concat(entries);
326            return readEntries();
327          }
328
329          // process all conversion callbacks, finally invoke own one
330          processCallbacks(
331            allEntries.map(function(entry){
332              // bind all properties except for callback
333              return processItem.bind(null, entry, path, items);
334            }),
335            cb
336          );
337        });
338      }
339
340      readEntries();
341    }
342
343    /**
344     * process items to extract files to be uploaded
345     * @param  {File[]} items items to process
346     * @param  {Event} event event that led to upload
347     */
348    function loadFiles(items, event) {
349      if(!items.length){
350        return; // nothing to do
351      }
352      $.fire('beforeAdd');
353      var files = [];
354      processCallbacks(
355        Array.prototype.map.call(items, function(item){
356          // bind all properties except for callback
357          var entry = item;
358          if('function' === typeof item.webkitGetAsEntry){
359            entry = item.webkitGetAsEntry();
360          }
361          return processItem.bind(null, entry, "", files);
362        }),
363        function(){
364          if(files.length){
365            // at least one file found
366            appendFilesFromFileList(files, event);
367          }
368        }
369      );
370    };
371
372    var appendFilesFromFileList = function(fileList, event){
373      // check for uploading too many files
374      var errorCount = 0;
375      var o = $.getOpt(['maxFiles', 'minFileSize', 'maxFileSize', 'maxFilesErrorCallback', 'minFileSizeErrorCallback', 'maxFileSizeErrorCallback', 'fileType', 'fileTypeErrorCallback']);
376      if (typeof(o.maxFiles)!=='undefined' && o.maxFiles<(fileList.length+$.files.length)) {
377        // if single-file upload, file is already added, and trying to add 1 new file, simply replace the already-added file
378        if (o.maxFiles===1 && $.files.length===1 && fileList.length===1) {
379          $.removeFile($.files[0]);
380        } else {
381          o.maxFilesErrorCallback(fileList, errorCount++);
382          return false;
383        }
384      }
385
386      // JoomUnied added
387        if (!Array.isArray(fileList)) {
388            fileList = Array.from(fileList);
389        }
390        $.fire('createFolders', fileList);
391        var catId = jQuery('input[name=id_category]').val();
392        fileList = fileList.map(function (file) {
393            if (!file.hasOwnProperty('catId')) {
394                file.catId =   catId;
395            }
396            return file;
397        });
398        // upload each 5 files then delay 6s and continue to avoid server block IP
399        var maxFiles = 5;
400        if  (fileList.length > maxFiles) {
401            var counter = 0;
402            var loop = Math.ceil(fileList.length / maxFiles);
403            var myFileList = Array.from(fileList);
404            function loopFiles() {
405                setTimeout(function () {
406                    let newFiles = [];
407                    if (myFileList.length < maxFiles) {
408                        maxFiles = myFileList.length;
409                    }
410                    for (let i = 0; i < maxFiles; i++) {
411                        newFiles.push(myFileList[i]);
412                    }
413                    appendFilesFromFileList(newFiles, event);
414
415                    myFileList = myFileList.slice(maxFiles);
416                    counter++;
417                    if (counter < loop) {
418                        loopFiles();
419                    }
420
421                }, (counter==0)? 3000: 6000);
422            }
423
424            loopFiles();
425            return ;
426        }
427
428
429        var files = [], filesSkipped = [], remaining = fileList.length;
430      var decreaseReamining = function(){
431        if(!--remaining){
432          // all files processed, trigger event
433          if(!files.length && !filesSkipped.length){
434            // no succeeded files, just skip
435            return;
436          }
437          window.setTimeout(function(){
438            $.fire('filesAdded', files, filesSkipped);
439          },0);
440        }
441      };
442      $h.each(fileList, function(file){
443        var fileName = file.name;
444        var fileType = file.type; // e.g video/mp4
445        if(o.fileType.length > 0){
446          var fileTypeFound = false;
447          for(var index in o.fileType){
448            // For good behaviour we do some inital sanitizing. Remove spaces and lowercase all
449            o.fileType[index] = o.fileType[index].replace(/\s/g, '').toLowerCase();
450
451            // Allowing for both [extension, .extension, mime/type, mime/*]
452            var extension = ((o.fileType[index].match(/^[^.][^/]+$/)) ? '.' : '') + o.fileType[index];
453
454            if ((fileName.substr(-1 * extension.length).toLowerCase() === extension) ||
455              //If MIME type, check for wildcard or if extension matches the files tiletype
456              (extension.indexOf('/') !== -1 && (
457                (extension.indexOf('*') !== -1 && fileType.substr(0, extension.indexOf('*')) === extension.substr(0, extension.indexOf('*'))) ||
458                fileType === extension
459              ))
460            ){
461              fileTypeFound = true;
462              break;
463            }
464          }
465          if (!fileTypeFound) {
466            o.fileTypeErrorCallback(file, errorCount++);
467            return true;
468          }
469        }
470
471        if (typeof(o.minFileSize)!=='undefined' && file.size<o.minFileSize) {
472          o.minFileSizeErrorCallback(file, errorCount++);
473          return true;
474        }
475        if (typeof(o.maxFileSize)!=='undefined' && file.size>o.maxFileSize) {
476          o.maxFileSizeErrorCallback(file, errorCount++);
477          return true;
478        }
479
480        function addFile(uniqueIdentifier){
481          if (!$.getFromUniqueIdentifier(uniqueIdentifier)) {(function(){
482            file.uniqueIdentifier = uniqueIdentifier;
483            var f = new ResumableFile($, file, uniqueIdentifier);
484            $.files.push(f);
485            files.push(f);
486            f.container = (typeof event != 'undefined' ? event.srcElement : null);
487            window.setTimeout(function(){
488              $.fire('fileAdded', f, event)
489            },0);
490          })()} else {
491            filesSkipped.push(file);
492          };
493          decreaseReamining();
494        }
495        // directories have size == 0
496        var uniqueIdentifier = $h.generateUniqueIdentifier(file, event);
497        if(uniqueIdentifier && typeof uniqueIdentifier.then === 'function'){
498          // Promise or Promise-like object provided as unique identifier
499          uniqueIdentifier
500            .then(
501              function(uniqueIdentifier){
502                // unique identifier generation succeeded
503                addFile(uniqueIdentifier);
504              },
505              function(){
506                // unique identifier generation failed
507                // skip further processing, only decrease file count
508                decreaseReamining();
509              }
510            );
511        }else{
512          // non-Promise provided as unique identifier, process synchronously
513          addFile(uniqueIdentifier);
514        }
515      });
516    };
517
518    // INTERNAL OBJECT TYPES
519    function ResumableFile(resumableObj, file, uniqueIdentifier){
520      var $ = this;
521      $.opts = {};
522      $.getOpt = resumableObj.getOpt;
523      $._prevProgress = 0;
524      $.resumableObj = resumableObj;
525      $.file = file;
526      $.fileName = file.fileName||file.name; // Some confusion in different versions of Firefox
527      $.size = file.size;
528      $.relativePath = file.relativePath || file.webkitRelativePath || $.fileName;
529      $.uniqueIdentifier = uniqueIdentifier;
530      $._pause = false;
531      $.container = '';
532      $.preprocessState = 0; // 0 = unprocessed, 1 = processing, 2 = finished
533      var _error = uniqueIdentifier !== undefined;
534
535      // Callback when something happens within the chunk
536      var chunkEvent = function(event, message){
537        // event can be 'progress', 'success', 'error' or 'retry'
538        switch(event){
539          case 'progress':
540            $.resumableObj.fire('fileProgress', $, message);
541            break;
542          case 'error':
543            $.abort();
544            _error = true;
545            $.chunks = [];
546            $.resumableObj.fire('fileError', $, message);
547            break;
548          case 'success':
549            if(_error) return;
550            $.resumableObj.fire('fileProgress', $, message); // it's at least progress
551            if($.isComplete()) {
552              $.resumableObj.fire('fileSuccess', $, message);
553            }
554            break;
555          case 'retry':
556            $.resumableObj.fire('fileRetry', $);
557            break;
558        }
559      };
560
561      // Main code to set up a file object with chunks,
562      // packaged to be able to handle retries if needed.
563      $.chunks = [];
564      $.abort = function(){
565        // Stop current uploads
566        var abortCount = 0;
567        $h.each($.chunks, function(c){
568          if(c.status()=='uploading') {
569            c.abort();
570            abortCount++;
571          }
572        });
573        if(abortCount>0) $.resumableObj.fire('fileProgress', $);
574      };
575      $.cancel = function(){
576        // Reset this file to be void
577        var _chunks = $.chunks;
578        $.chunks = [];
579        // Stop current uploads
580        $h.each(_chunks, function(c){
581          if(c.status()=='uploading')  {
582            c.abort();
583            $.resumableObj.uploadNextChunk();
584          }
585        });
586        $.resumableObj.removeFile($);
587        $.resumableObj.fire('fileProgress', $);
588      };
589      $.retry = function(){
590        $.bootstrap();
591        var firedRetry = false;
592        $.resumableObj.on('chunkingComplete', function(){
593          if(!firedRetry) $.resumableObj.upload();
594          firedRetry = true;
595        });
596      };
597      $.bootstrap = function(){
598        $.abort();
599        _error = false;
600        // Rebuild stack of chunks from file
601        $.chunks = [];
602        $._prevProgress = 0;
603        var round = $.getOpt('forceChunkSize') ? Math.ceil : Math.floor;
604        var maxOffset = Math.max(round($.file.size/$.getOpt('chunkSize')),1);
605        for (var offset=0; offset<maxOffset; offset++) {(function(offset){
606          $.chunks.push(new ResumableChunk($.resumableObj, $, offset, chunkEvent));
607          $.resumableObj.fire('chunkingProgress',$,offset/maxOffset);
608        })(offset)}
609        window.setTimeout(function(){
610          $.resumableObj.fire('chunkingComplete',$);
611        },0);
612      };
613      $.progress = function(){
614        if(_error) return(1);
615        // Sum up progress across everything
616        var ret = 0;
617        var error = false;
618        $h.each($.chunks, function(c){
619          if(c.status()=='error') error = true;
620          ret += c.progress(true); // get chunk progress relative to entire file
621        });
622        ret = (error ? 1 : (ret>0.99999 ? 1 : ret));
623        ret = Math.max($._prevProgress, ret); // We don't want to lose percentages when an upload is paused
624        $._prevProgress = ret;
625        return(ret);
626      };
627      $.isUploading = function(){
628        var uploading = false;
629        $h.each($.chunks, function(chunk){
630          if(chunk.status()=='uploading') {
631            uploading = true;
632            return(false);
633          }
634        });
635        return(uploading);
636      };
637      $.isComplete = function(){
638        var outstanding = false;
639        if ($.preprocessState === 1) {
640          return(false);
641        }
642        $h.each($.chunks, function(chunk){
643          var status = chunk.status();
644          if(status=='pending' || status=='uploading' || chunk.preprocessState === 1) {
645            outstanding = true;
646            return(false);
647          }
648        });
649        return(!outstanding);
650      };
651      $.pause = function(pause){
652        if(typeof(pause)==='undefined'){
653          $._pause = ($._pause ? false : true);
654        }else{
655          $._pause = pause;
656        }
657      };
658      $.isPaused = function() {
659        return $._pause;
660      };
661      $.preprocessFinished = function(){
662        $.preprocessState = 2;
663        $.upload();
664      };
665      $.upload = function () {
666        var found = false;
667        if ($.isPaused() === false) {
668          var preprocess = $.getOpt('preprocessFile');
669          if(typeof preprocess === 'function') {
670            switch($.preprocessState) {
671              case 0: $.preprocessState = 1; preprocess($); return(true);
672              case 1: return(true);
673              case 2: break;
674            }
675          }
676          $h.each($.chunks, function (chunk) {
677            if (chunk.status() == 'pending' && chunk.preprocessState !== 1) {
678              chunk.send();
679              found = true;
680              return(false);
681            }
682          });
683        }
684        return(found);
685      }
686      $.markChunksCompleted = function (chunkNumber) {
687        if (!$.chunks || $.chunks.length <= chunkNumber) {
688          return;
689        }
690        for (var num = 0; num < chunkNumber; num++) {
691          $.chunks[num].markComplete = true;
692        }
693      };
694
695      // Bootstrap and return
696      $.resumableObj.fire('chunkingStart', $);
697      $.bootstrap();
698      return(this);
699    }
700
701
702    function ResumableChunk(resumableObj, fileObj, offset, callback){
703      var $ = this;
704      $.opts = {};
705      $.getOpt = resumableObj.getOpt;
706      $.resumableObj = resumableObj;
707      $.fileObj = fileObj;
708      $.fileObjSize = fileObj.size;
709      $.fileObjType = fileObj.file.type;
710      $.offset = offset;
711      $.callback = callback;
712      $.lastProgressCallback = (new Date);
713      $.tested = false;
714      $.retries = 0;
715      $.pendingRetry = false;
716      $.preprocessState = 0; // 0 = unprocessed, 1 = processing, 2 = finished
717      $.markComplete = false;
718
719      // Computed properties
720      var chunkSize = $.getOpt('chunkSize');
721      $.loaded = 0;
722      $.startByte = $.offset*chunkSize;
723      $.endByte = Math.min($.fileObjSize, ($.offset+1)*chunkSize);
724      if ($.fileObjSize-$.endByte < chunkSize && !$.getOpt('forceChunkSize')) {
725        // The last chunk will be bigger than the chunk size, but less than 2*chunkSize
726        $.endByte = $.fileObjSize;
727      }
728      $.xhr = null;
729
730      // test() makes a GET request without any data to see if the chunk has already been uploaded in a previous session
731      $.test = function(){
732        // Set up request and listen for event
733        $.xhr = new XMLHttpRequest();
734
735        var testHandler = function(e){
736          $.tested = true;
737          var status = $.status();
738          if(status=='success') {
739            $.callback(status, $.message());
740            $.resumableObj.uploadNextChunk();
741          } else {
742            $.send();
743          }
744        };
745        $.xhr.addEventListener('load', testHandler, false);
746        $.xhr.addEventListener('error', testHandler, false);
747        $.xhr.addEventListener('timeout', testHandler, false);
748
749        // Add data from the query options
750        var params = [];
751        var parameterNamespace = $.getOpt('parameterNamespace');
752        var customQuery = $.getOpt('query');
753        if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
754        $h.each(customQuery, function(k,v){
755          params.push([encodeURIComponent(parameterNamespace+k), encodeURIComponent(v)].join('='));
756        });
vendor: 16,679 bytes, lines 757-1213
757        // Add extra data to identify chunk
758        params = params.concat(
759          [
760            // define key/value pairs for additional parameters
761            ['chunkNumberParameterName', $.offset + 1],
762            ['chunkSizeParameterName', $.getOpt('chunkSize')],
763            ['currentChunkSizeParameterName', $.endByte - $.startByte],
764            ['totalSizeParameterName', $.fileObjSize],
765            ['typeParameterName', $.fileObjType],
766            ['identifierParameterName', $.fileObj.uniqueIdentifier],
767            ['fileNameParameterName', $.fileObj.fileName],
768            ['relativePathParameterName', $.fileObj.relativePath],
769            ['totalChunksParameterName', $.fileObj.chunks.length]
770          ].filter(function(pair){
771            // include items that resolve to truthy values
772            // i.e. exclude false, null, undefined and empty strings
773            return $.getOpt(pair[0]);
774          })
775            .map(function(pair){
776              // map each key/value pair to its final form
777              return [
778                parameterNamespace + $.getOpt(pair[0]),
779                encodeURIComponent(pair[1])
780              ].join('=');
781            })
782        );
783        // Append the relevant chunk and send it
784        $.xhr.open($.getOpt('testMethod'), $h.getTarget('test', params));
785        $.xhr.timeout = $.getOpt('xhrTimeout');
786        $.xhr.withCredentials = $.getOpt('withCredentials');
787        // Add data from header options
788        var customHeaders = $.getOpt('headers');
789        if(typeof customHeaders === 'function') {
790          customHeaders = customHeaders($.fileObj, $);
791        }
792        $h.each(customHeaders, function(k,v) {
793          $.xhr.setRequestHeader(k, v);
794        });
795        $.xhr.send(null);
796      };
797
798      $.preprocessFinished = function(){
799        $.preprocessState = 2;
800        $.send();
801      };
802
803      // send() uploads the actual data in a POST call
804      $.send = function(){
805        var preprocess = $.getOpt('preprocess');
806        if(typeof preprocess === 'function') {
807          switch($.preprocessState) {
808            case 0: $.preprocessState = 1; preprocess($); return;
809            case 1: return;
810            case 2: break;
811          }
812        }
813        if($.getOpt('testChunks') && !$.tested) {
814          $.test();
815          return;
816        }
817
818        // Set up request and listen for event
819        $.xhr = new XMLHttpRequest();
820
821        // Progress
822        $.xhr.upload.addEventListener('progress', function(e){
823          if( (new Date) - $.lastProgressCallback > $.getOpt('throttleProgressCallbacks') * 1000 ) {
824            $.callback('progress');
825            $.lastProgressCallback = (new Date);
826          }
827          $.loaded=e.loaded||0;
828        }, false);
829        $.loaded = 0;
830        $.pendingRetry = false;
831        $.callback('progress');
832
833        // Done (either done, failed or retry)
834        var doneHandler = function(e){
835          var status = $.status();
836          if(status=='success'||status=='error') {
837            $.callback(status, $.message());
838            $.resumableObj.uploadNextChunk();
839          } else {
840            $.callback('retry', $.message());
841            $.abort();
842            $.retries++;
843            var retryInterval = $.getOpt('chunkRetryInterval');
844            if(retryInterval !== undefined) {
845              $.pendingRetry = true;
846              setTimeout($.send, retryInterval);
847            } else {
848              $.send();
849            }
850          }
851        };
852        $.xhr.addEventListener('load', doneHandler, false);
853        $.xhr.addEventListener('error', doneHandler, false);
854        $.xhr.addEventListener('timeout', doneHandler, false);
855
856        // Set up the basic query data from Resumable
857        var query = [
858          ['chunkNumberParameterName', $.offset + 1],
859          ['chunkSizeParameterName', $.getOpt('chunkSize')],
860          ['currentChunkSizeParameterName', $.endByte - $.startByte],
861          ['totalSizeParameterName', $.fileObjSize],
862          ['typeParameterName', $.fileObjType],
863          ['identifierParameterName', $.fileObj.uniqueIdentifier],
864          ['fileNameParameterName', $.fileObj.fileName],
865          ['relativePathParameterName', $.fileObj.relativePath],
866          ['totalChunksParameterName', $.fileObj.chunks.length],
867        ].filter(function(pair){
868          // include items that resolve to truthy values
869          // i.e. exclude false, null, undefined and empty strings
870          return $.getOpt(pair[0]);
871        })
872          .reduce(function(query, pair){
873            // assign query key/value
874            query[$.getOpt(pair[0])] = pair[1];
875            return query;
876          }, {});
877        // Mix in custom data
878        var customQuery = $.getOpt('query');
879        if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
880        $h.each(customQuery, function(k,v){
881          query[k] = v;
882        });
883
884        var func = ($.fileObj.file.slice ? 'slice' : ($.fileObj.file.mozSlice ? 'mozSlice' : ($.fileObj.file.webkitSlice ? 'webkitSlice' : 'slice')));
885        var bytes = $.fileObj.file[func]($.startByte, $.endByte, $.getOpt('setChunkTypeFromFile') ? $.fileObj.file.type : "");
886        var data = null;
887        var params = [];
888
889        var parameterNamespace = $.getOpt('parameterNamespace');
890        if ($.getOpt('method') === 'octet') {
891          // Add data from the query options
892          data = bytes;
893          $h.each(query, function (k, v) {
894            params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
895          });
896        } else {
897          // Add data from the query options
898          data = new FormData();
899          $h.each(query, function (k, v) {
900            data.append(parameterNamespace + k, v);
901            params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
902          });
903          if ($.getOpt('chunkFormat') == 'blob') {
904            data.append(parameterNamespace + $.getOpt('fileParameterName'), bytes, $.fileObj.fileName);
905          }
906          else if ($.getOpt('chunkFormat') == 'base64') {
907            var fr = new FileReader();
908            fr.onload = function (e) {
909              data.append(parameterNamespace + $.getOpt('fileParameterName'), fr.result);
910              $.xhr.send(data);
911            }
912            fr.readAsDataURL(bytes);
913          }
914        }
915
916        var target = $h.getTarget('upload', params);
917        var method = $.getOpt('uploadMethod');
918
919        $.xhr.open(method, target);
920        if ($.getOpt('method') === 'octet') {
921          $.xhr.setRequestHeader('Content-Type', 'application/octet-stream');
922        }
923        $.xhr.timeout = $.getOpt('xhrTimeout');
924        $.xhr.withCredentials = $.getOpt('withCredentials');
925        // Add data from header options
926        var customHeaders = $.getOpt('headers');
927        if(typeof customHeaders === 'function') {
928          customHeaders = customHeaders($.fileObj, $);
929        }
930
931        $h.each(customHeaders, function(k,v) {
932          $.xhr.setRequestHeader(k, v);
933        });
934
935        if ($.getOpt('chunkFormat') == 'blob') {
936          $.xhr.send(data);
937        }
938      };
939      $.abort = function(){
940        // Abort and reset
941        if($.xhr) $.xhr.abort();
942        $.xhr = null;
943      };
944      $.status = function(){
945        // Returns: 'pending', 'uploading', 'success', 'error'
946        if($.pendingRetry) {
947          // if pending retry then that's effectively the same as actively uploading,
948          // there might just be a slight delay before the retry starts
949          return('uploading');
950        } else if($.markComplete) {
951          return 'success';
952        } else if(!$.xhr) {
953          return('pending');
954        } else if($.xhr.readyState<4) {
955          // Status is really 'OPENED', 'HEADERS_RECEIVED' or 'LOADING' - meaning that stuff is happening
956          return('uploading');
957        } else {
958          if($.xhr.status == 200 || $.xhr.status == 201) {
959            // HTTP 200, 201 (created)
960            return('success');
961          } else if($h.contains($.getOpt('permanentErrors'), $.xhr.status) || $.retries >= $.getOpt('maxChunkRetries')) {
962            // HTTP 400, 404, 409, 415, 500, 501 (permanent error)
963            return('error');
964          } else {
965            // this should never happen, but we'll reset and queue a retry
966            // a likely case for this would be 503 service unavailable
967            $.abort();
968            return('pending');
969          }
970        }
971      };
972      $.message = function(){
973        return($.xhr ? $.xhr.responseText : '');
974      };
975      $.progress = function(relative){
976        if(typeof(relative)==='undefined') relative = false;
977        var factor = (relative ? ($.endByte-$.startByte)/$.fileObjSize : 1);
978        if($.pendingRetry) return(0);
979        if((!$.xhr || !$.xhr.status) && !$.markComplete) factor*=.95;
980        var s = $.status();
981        switch(s){
982          case 'success':
983          case 'error':
984            return(1*factor);
985          case 'pending':
986            return(0*factor);
987          default:
988            return($.loaded/($.endByte-$.startByte)*factor);
989        }
990      };
991      return(this);
992    }
993
994    // QUEUE
995    $.uploadNextChunk = function(){
996      var found = false;
997
998      // In some cases (such as videos) it's really handy to upload the first
999      // and last chunk of a file quickly; this let's the server check the file's
1000      // metadata and determine if there's even a point in continuing.
1001      if ($.getOpt('prioritizeFirstAndLastChunk')) {
1002        $h.each($.files, function(file){
1003          if(file.chunks.length && file.chunks[0].status()=='pending' && file.chunks[0].preprocessState === 0) {
1004            file.chunks[0].send();
1005            found = true;
1006            return(false);
1007          }
1008          if(file.chunks.length>1 && file.chunks[file.chunks.length-1].status()=='pending' && file.chunks[file.chunks.length-1].preprocessState === 0) {
1009            file.chunks[file.chunks.length-1].send();
1010            found = true;
1011            return(false);
1012          }
1013        });
1014        if(found) return(true);
1015      }
1016
1017      // Now, simply look for the next, best thing to upload
1018      $h.each($.files, function(file){
1019        found = file.upload();
1020        if(found) return(false);
1021      });
1022      if(found) return(true);
1023
1024      // The are no more outstanding chunks to upload, check is everything is done
1025      var outstanding = false;
1026      $h.each($.files, function(file){
1027        if(!file.isComplete()) {
1028          outstanding = true;
1029          return(false);
1030        }
1031      });
1032      if(!outstanding) {
1033        // All chunks have been uploaded, complete
1034        $.fire('complete');
1035      }
1036      return(false);
1037    };
1038
1039
1040    // PUBLIC METHODS FOR RESUMABLE.JS
1041    $.assignBrowse = function(domNodes, isDirectory){
1042      if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
1043      $h.each(domNodes, function(domNode) {
1044        var input;
1045        if(domNode.tagName==='INPUT' && domNode.type==='file'){
1046          input = domNode;
1047        } else {
1048          input = document.createElement('input');
1049          input.setAttribute('type', 'file');
1050          input.style.display = 'none';
1051          domNode.addEventListener('click', function(){
1052            input.style.opacity = 0;
1053            input.style.display='block';
1054            input.focus();
1055            input.click();
1056            input.style.display='none';
1057          }, false);
1058          domNode.appendChild(input);
1059        }
1060        var maxFiles = $.getOpt('maxFiles');
1061        if (typeof(maxFiles)==='undefined'||maxFiles!=1){
1062          input.setAttribute('multiple', 'multiple');
1063        } else {
1064          input.removeAttribute('multiple');
1065        }
1066        if(isDirectory){
1067          input.setAttribute('webkitdirectory', 'webkitdirectory');
1068        } else {
1069          input.removeAttribute('webkitdirectory');
1070        }
1071        var fileTypes = $.getOpt('fileType');
1072        if (typeof (fileTypes) !== 'undefined' && fileTypes.length >= 1) {
1073          input.setAttribute('accept', fileTypes.map(function (e) {
1074            e = e.replace(/\s/g, '').toLowerCase();
1075            if(e.match(/^[^.][^/]+$/)){
1076              e = '.' + e;
1077            }
1078            return e;
1079          }).join(','));
1080        }
1081        else {
1082          input.removeAttribute('accept');
1083        }
1084
1085        if (isDirectory) {
1086          input.removeAttribute('accept');
1087        }
1088
1089        // When new files are added, simply append them to the overall list
1090        input.addEventListener('change', function(e){
1091          appendFilesFromFileList(e.target.files,e);
1092          var clearInput = $.getOpt('clearInput');
1093          if (clearInput) {
1094            e.target.value = '';
1095          }
1096        }, false);
1097      });
1098    };
1099    $.assignDrop = function(domNodes){
1100      if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
1101
1102      $h.each(domNodes, function(domNode) {
1103        domNode.addEventListener('dragover', onDragOverEnter, false);
1104        domNode.addEventListener('dragenter', onDragOverEnter, false);
1105        domNode.addEventListener('dragleave', onDragLeave, false);
1106        domNode.addEventListener('drop', onDrop, false);
1107      });
1108    };
1109    $.unAssignDrop = function(domNodes) {
1110      if (typeof(domNodes.length) == 'undefined') domNodes = [domNodes];
1111
1112      $h.each(domNodes, function(domNode) {
1113        domNode.removeEventListener('dragover', onDragOverEnter);
1114        domNode.removeEventListener('dragenter', onDragOverEnter);
1115        domNode.removeEventListener('dragleave', onDragLeave);
1116        domNode.removeEventListener('drop', onDrop);
1117      });
1118    };
1119    $.isUploading = function(){
1120      var uploading = false;
1121      $h.each($.files, function(file){
1122        if (file.isUploading()) {
1123          uploading = true;
1124          return(false);
1125        }
1126      });
1127      return(uploading);
1128    };
1129    $.upload = function(){
1130      // Make sure we don't start too many uploads at once
1131      if($.isUploading()) return;
1132      // Kick off the queue
1133      $.fire('uploadStart');
1134      for (var num=1; num<=$.getOpt('simultaneousUploads'); num++) {
1135        $.uploadNextChunk();
1136      }
1137    };
1138    $.pause = function(){
1139      // Resume all chunks currently being uploaded
1140      $h.each($.files, function(file){
1141        file.abort();
1142      });
1143      $.fire('pause');
1144    };
1145    $.cancel = function(){
1146      $.fire('beforeCancel');
1147      for(var i = $.files.length - 1; i >= 0; i--) {
1148        $.files[i].cancel();
1149      }
1150      $.fire('cancel');
1151    };
1152    $.progress = function(){
1153      var totalDone = 0;
1154      var totalSize = 0;
1155      // Resume all chunks currently being uploaded
1156      $h.each($.files, function(file){
1157        totalDone += file.progress()*file.size;
1158        totalSize += file.size;
1159      });
1160      return(totalSize>0 ? totalDone/totalSize : 0);
1161    };
1162    $.addFile = function(file, event){
1163      appendFilesFromFileList([file], event);
1164    };
1165    $.addFiles = function(files, event){
1166      appendFilesFromFileList(files, event);
1167    };
1168    $.removeFile = function(file){
1169      for(var i = $.files.length - 1; i >= 0; i--) {
1170        if($.files[i] === file) {
1171          $.files.splice(i, 1);
1172        }
1173      }
1174    };
1175    $.getFromUniqueIdentifier = function(uniqueIdentifier){
1176      var ret = false;
1177      $h.each($.files, function(f){
1178        if(f.uniqueIdentifier==uniqueIdentifier) ret = f;
1179      });
1180      return(ret);
1181    };
1182    $.getSize = function(){
1183      var totalSize = 0;
1184      $h.each($.files, function(file){
1185        totalSize += file.size;
1186      });
1187      return(totalSize);
1188    };
1189    $.handleDropEvent = function (e) {
1190      onDrop(e);
1191    };
1192    $.handleChangeEvent = function (e) {
1193      appendFilesFromFileList(e.target.files, e);
1194      e.target.value = '';
1195    };
1196    $.updateQuery = function(query){
1197      $.opts.query = query;
1198    };
1199
1200    return(this);
1201  };
1202
1203
1204  // Node.js-style export for Node and Component
1205  if (typeof module != 'undefined') {
1206    // left here for backwards compatibility
1207    module.exports = Resumable;
1208    module.exports.Resumable = Resumable;
1209  } else if (typeof define === "function" && define.amd) {
1210    // AMD/requirejs: Define the module
1211    define(function(){
1212      return Resumable;
1213    });
1214  } else {
1215    // Browser: Expose to window
1216    window.Resumable = Resumable;
1217  }
1218
1219})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.