PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 3.5.2
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v3.5.2
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / assets / js / dropzone / dropzone.js
everest-forms / assets / js / dropzone Last commit date
dropzone.js 2 years ago dropzone.min.js 2 years ago
dropzone.js
3534 lines
1 "use strict";
2
3 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4
5 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6
7 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8
9 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
11 /*
12 *
13 * More info at [www.dropzonejs.com](http://www.dropzonejs.com)
14 *
15 * Copyright (c) 2012, Matias Meno
16 *
17 * Permission is hereby granted, free of charge, to any person obtaining a copy
18 * of this software and associated documentation files (the "Software"), to deal
19 * in the Software without restriction, including without limitation the rights
20 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 * copies of the Software, and to permit persons to whom the Software is
22 * furnished to do so, subject to the following conditions:
23 *
24 * The above copyright notice and this permission notice shall be included in
25 * all copies or substantial portions of the Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 * THE SOFTWARE.
34 *
35 */
36
37 // The Emitter class provides the ability to call `.on()` on Dropzone to listen
38 // to events.
39 // It is strongly based on component's emitter class, and I removed the
40 // functionality because of the dependency hell with different frameworks.
41 var Emitter = function () {
42 function Emitter() {
43 _classCallCheck(this, Emitter);
44 }
45
46 _createClass(Emitter, [{
47 key: "on",
48
49 // Add an event listener for given event
50 value: function on(event, fn) {
51 this._callbacks = this._callbacks || {};
52 // Create namespace for this event
53 if (!this._callbacks[event]) {
54 this._callbacks[event] = [];
55 }
56 this._callbacks[event].push(fn);
57 return this;
58 }
59 }, {
60 key: "emit",
61 value: function emit(event) {
62 this._callbacks = this._callbacks || {};
63 var callbacks = this._callbacks[event];
64
65 if (callbacks) {
66 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
67 args[_key - 1] = arguments[_key];
68 }
69
70 for (var _iterator = callbacks, _isArray = true, _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
71 var _ref;
72
73 if (_isArray) {
74 if (_i >= _iterator.length) break;
75 _ref = _iterator[_i++];
76 } else {
77 _i = _iterator.next();
78 if (_i.done) break;
79 _ref = _i.value;
80 }
81
82 var callback = _ref;
83
84 callback.apply(this, args);
85 }
86 }
87
88 return this;
89 }
90
91 // Remove event listener for given event. If fn is not provided, all event
92 // listeners for that event will be removed. If neither is provided, all
93 // event listeners will be removed.
94
95 }, {
96 key: "off",
97 value: function off(event, fn) {
98 if (!this._callbacks || arguments.length === 0) {
99 this._callbacks = {};
100 return this;
101 }
102
103 // specific event
104 var callbacks = this._callbacks[event];
105 if (!callbacks) {
106 return this;
107 }
108
109 // remove all handlers
110 if (arguments.length === 1) {
111 delete this._callbacks[event];
112 return this;
113 }
114
115 // remove specific handler
116 for (var i = 0; i < callbacks.length; i++) {
117 var callback = callbacks[i];
118 if (callback === fn) {
119 callbacks.splice(i, 1);
120 break;
121 }
122 }
123
124 return this;
125 }
126 }]);
127
128 return Emitter;
129 }();
130
131 var Dropzone = function (_Emitter) {
132 _inherits(Dropzone, _Emitter);
133
134 _createClass(Dropzone, null, [{
135 key: "initClass",
136 value: function initClass() {
137
138 // Exposing the emitter class, mainly for tests
139 this.prototype.Emitter = Emitter;
140
141 /*
142 This is a list of all available events you can register on a dropzone object.
143 You can register an event handler like this:
144 dropzone.on("dragEnter", function() { });
145 */
146 this.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"];
147
148 this.prototype.defaultOptions = {
149 /**
150 * Has to be specified on elements other than form (or when the form
151 * doesn't have an `action` attribute). You can also
152 * provide a function that will be called with `files` and
153 * must return the url (since `v3.12.0`)
154 */
155 url: null,
156
157 /**
158 * Can be changed to `"put"` if necessary. You can also provide a function
159 * that will be called with `files` and must return the method (since `v3.12.0`).
160 */
161 method: "post",
162
163 /**
164 * Will be set on the XHRequest.
165 */
166 withCredentials: false,
167
168 /**
169 * The timeout for the XHR requests in milliseconds (since `v4.4.0`).
170 */
171 timeout: 30000,
172
173 /**
174 * How many file uploads to process in parallel (See the
175 * Enqueuing file uploads* documentation section for more info)
176 */
177 parallelUploads: 2,
178
179 /**
180 * Whether to send multiple files in one request. If
181 * this it set to true, then the fallback file input element will
182 * have the `multiple` attribute as well. This option will
183 * also trigger additional events (like `processingmultiple`). See the events
184 * documentation section for more information.
185 */
186 uploadMultiple: false,
187
188 /**
189 * Whether you want files to be uploaded in chunks to your server. This can't be
190 * used in combination with `uploadMultiple`.
191 *
192 * See [chunksUploaded](#config-chunksUploaded) for the callback to finalise an upload.
193 */
194 chunking: false,
195
196 /**
197 * If `chunking` is enabled, this defines whether **every** file should be chunked,
198 * even if the file size is below chunkSize. This means, that the additional chunk
199 * form data will be submitted and the `chunksUploaded` callback will be invoked.
200 */
201 forceChunking: false,
202
203 /**
204 * If `chunking` is `true`, then this defines the chunk size in bytes.
205 */
206 chunkSize: 2000000,
207
208 /**
209 * If `true`, the individual chunks of a file are being uploaded simultaneously.
210 */
211 parallelChunkUploads: false,
212
213 /**
214 * Whether a chunk should be retried if it fails.
215 */
216 retryChunks: false,
217
218 /**
219 * If `retryChunks` is true, how many times should it be retried.
220 */
221 retryChunksLimit: 3,
222
223 /**
224 * If not `null` defines how many files this Dropzone handles. If it exceeds,
225 * the event `maxfilesexceeded` will be called. The dropzone element gets the
226 * class `dz-max-files-reached` accordingly so you can provide visual feedback.
227 */
228 maxFilesize: 256,
229
230 /**
231 * The name of the file param that gets transferred.
232 * **NOTE**: If you have the option `uploadMultiple` set to `true`, then
233 * Dropzone will append `[]` to the name.
234 */
235 paramName: "file",
236
237 /**
238 * Whether thumbnails for images should be generated
239 */
240 createImageThumbnails: true,
241
242 /**
243 * In MB. When the filename exceeds this limit, the thumbnail will not be generated.
244 */
245 maxThumbnailFilesize: 10,
246
247 /**
248 * If `null`, the ratio of the image will be used to calculate it.
249 */
250 thumbnailWidth: 120,
251
252 /**
253 * The same as `thumbnailWidth`. If both are null, images will not be resized.
254 */
255 thumbnailHeight: 120,
256
257 /**
258 * How the images should be scaled down in case both, `thumbnailWidth` and `thumbnailHeight` are provided.
259 * Can be either `contain` or `crop`.
260 */
261 thumbnailMethod: 'crop',
262
263 /**
264 * If set, images will be resized to these dimensions before being **uploaded**.
265 * If only one, `resizeWidth` **or** `resizeHeight` is provided, the original aspect
266 * ratio of the file will be preserved.
267 *
268 * The `options.transformFile` function uses these options, so if the `transformFile` function
269 * is overridden, these options don't do anything.
270 */
271 resizeWidth: null,
272
273 /**
274 * See `resizeWidth`.
275 */
276 resizeHeight: null,
277
278 /**
279 * The mime type of the resized image (before it gets uploaded to the server).
280 * If `null` the original mime type will be used. To force jpeg, for example, use `image/jpeg`.
281 * See `resizeWidth` for more information.
282 */
283 resizeMimeType: null,
284
285 /**
286 * The quality of the resized images. See `resizeWidth`.
287 */
288 resizeQuality: 0.8,
289
290 /**
291 * How the images should be scaled down in case both, `resizeWidth` and `resizeHeight` are provided.
292 * Can be either `contain` or `crop`.
293 */
294 resizeMethod: 'contain',
295
296 /**
297 * The base that is used to calculate the filesize. You can change this to
298 * 1024 if you would rather display kibibytes, mebibytes, etc...
299 * 1024 is technically incorrect, because `1024 bytes` are `1 kibibyte` not `1 kilobyte`.
300 * You can change this to `1024` if you don't care about validity.
301 */
302 filesizeBase: 1000,
303
304 /**
305 * Can be used to limit the maximum number of files that will be handled by this Dropzone
306 */
307 maxFiles: null,
308
309 /**
310 * An optional object to send additional headers to the server. Eg:
311 * `{ "My-Awesome-Header": "header value" }`
312 */
313 headers: null,
314
315 /**
316 * If `true`, the dropzone element itself will be clickable, if `false`
317 * nothing will be clickable.
318 *
319 * You can also pass an HTML element, a CSS selector (for multiple elements)
320 * or an array of those. In that case, all of those elements will trigger an
321 * upload when clicked.
322 */
323 clickable: true,
324
325 /**
326 * Whether hidden files in directories should be ignored.
327 */
328 ignoreHiddenFiles: true,
329
330 /**
331 * The default implementation of `accept` checks the file's mime type or
332 * extension against this list. This is a comma separated list of mime
333 * types or file extensions.
334 *
335 * Eg.: `image/*,application/pdf,.psd`
336 *
337 * If the Dropzone is `clickable` this option will also be used as
338 * [`accept`](https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept)
339 * parameter on the hidden file input as well.
340 */
341 acceptedFiles: null,
342
343 /**
344 * **Deprecated!**
345 * Use acceptedFiles instead.
346 */
347 acceptedMimeTypes: null,
348
349 /**
350 * If false, files will be added to the queue but the queue will not be
351 * processed automatically.
352 * This can be useful if you need some additional user input before sending
353 * files (or if you want want all files sent at once).
354 * If you're ready to send the file simply call `myDropzone.processQueue()`.
355 *
356 * See the [enqueuing file uploads](#enqueuing-file-uploads) documentation
357 * section for more information.
358 */
359 autoProcessQueue: true,
360
361 /**
362 * If false, files added to the dropzone will not be queued by default.
363 * You'll have to call `enqueueFile(file)` manually.
364 */
365 autoQueue: true,
366
367 /**
368 * If `true`, this will add a link to every file preview to remove or cancel (if
369 * already uploading) the file. The `dictCancelUpload`, `dictCancelUploadConfirmation`
370 * and `dictRemoveFile` options are used for the wording.
371 */
372 addRemoveLinks: false,
373
374 /**
375 * Defines where to display the file previews – if `null` the
376 * Dropzone element itself is used. Can be a plain `HTMLElement` or a CSS
377 * selector. The element should have the `dropzone-previews` class so
378 * the previews are displayed properly.
379 */
380 previewsContainer: null,
381
382 /**
383 * This is the element the hidden input field (which is used when clicking on the
384 * dropzone to trigger file selection) will be appended to. This might
385 * be important in case you use frameworks to switch the content of your page.
386 *
387 * Can be a selector string, or an element directly.
388 */
389 hiddenInputContainer: "body",
390
391 /**
392 * If null, no capture type will be specified
393 * If camera, mobile devices will skip the file selection and choose camera
394 * If microphone, mobile devices will skip the file selection and choose the microphone
395 * If camcorder, mobile devices will skip the file selection and choose the camera in video mode
396 * On apple devices multiple must be set to false. AcceptedFiles may need to
397 * be set to an appropriate mime type (e.g. "image/*", "audio/*", or "video/*").
398 */
399 capture: null,
400
401 /**
402 * **Deprecated**. Use `renameFile` instead.
403 */
404 renameFilename: null,
405
406 /**
407 * A function that is invoked before the file is uploaded to the server and renames the file.
408 * This function gets the `File` as argument and can use the `file.name`. The actual name of the
409 * file that gets used during the upload can be accessed through `file.upload.filename`.
410 */
411 renameFile: null,
412
413 /**
414 * If `true` the fallback will be forced. This is very useful to test your server
415 * implementations first and make sure that everything works as
416 * expected without dropzone if you experience problems, and to test
417 * how your fallbacks will look.
418 */
419 forceFallback: false,
420
421 /**
422 * The text used before any files are dropped.
423 */
424 dictDefaultMessage: "Drop files here to upload",
425
426 /**
427 * The text that replaces the default message text it the browser is not supported.
428 */
429 dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
430
431 /**
432 * The text that will be added before the fallback form.
433 * If you provide a fallback element yourself, or if this option is `null` this will
434 * be ignored.
435 */
436 dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
437
438 /**
439 * If the filesize is too big.
440 * `{{filesize}}` and `{{maxFilesize}}` will be replaced with the respective configuration values.
441 */
442 dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
443
444 /**
445 * If the file doesn't match the file type.
446 */
447 dictInvalidFileType: "You can't upload files of this type.",
448
449 /**
450 * If the server response was invalid.
451 * `{{statusCode}}` will be replaced with the servers status code.
452 */
453 dictResponseError: "Server responded with {{statusCode}} code.",
454
455 /**
456 * If `addRemoveLinks` is true, the text to be used for the cancel upload link.
457 */
458 dictCancelUpload: "Cancel upload",
459
460 /**
461 * The text that is displayed if an upload was manually canceled
462 */
463 dictUploadCanceled: "Upload canceled.",
464
465 /**
466 * If `addRemoveLinks` is true, the text to be used for confirmation when cancelling upload.
467 */
468 dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
469
470 /**
471 * If `addRemoveLinks` is true, the text to be used to remove a file.
472 */
473 dictRemoveFile: "Remove file",
474
475 /**
476 * If this is not null, then the user will be prompted before removing a file.
477 */
478 dictRemoveFileConfirmation: null,
479
480 /**
481 * Displayed if `maxFiles` is st and exceeded.
482 * The string `{{maxFiles}}` will be replaced by the configuration value.
483 */
484 dictMaxFilesExceeded: "You can not upload any more files.",
485
486 /**
487 * Allows you to translate the different units. Starting with `tb` for terabytes and going down to
488 * `b` for bytes.
489 */
490 dictFileSizeUnits: { tb: "TB", gb: "GB", mb: "MB", kb: "KB", b: "b" },
491 /**
492 * Called when dropzone initialized
493 * You can add event listeners here
494 */
495 init: function init() {},
496
497
498 /**
499 * Can be an **object** of additional parameters to transfer to the server, **or** a `Function`
500 * that gets invoked with the `files`, `xhr` and, if it's a chunked upload, `chunk` arguments. In case
501 * of a function, this needs to return a map.
502 *
503 * The default implementation does nothing for normal uploads, but adds relevant information for
504 * chunked uploads.
505 *
506 * This is the same as adding hidden input fields in the form element.
507 */
508 params: function params(files, xhr, chunk) {
509 if (chunk) {
510 return {
511 dzuuid: chunk.file.upload.uuid,
512 dzchunkindex: chunk.index,
513 dztotalfilesize: chunk.file.size,
514 dzchunksize: this.options.chunkSize,
515 dztotalchunkcount: chunk.file.upload.totalChunkCount,
516 dzchunkbyteoffset: chunk.index * this.options.chunkSize
517 };
518 }
519 },
520
521
522 /**
523 * A function that gets a [file](https://developer.mozilla.org/en-US/docs/DOM/File)
524 * and a `done` function as parameters.
525 *
526 * If the done function is invoked without arguments, the file is "accepted" and will
527 * be processed. If you pass an error message, the file is rejected, and the error
528 * message will be displayed.
529 * This function will not be called if the file is too big or doesn't match the mime types.
530 */
531 accept: function accept(file, done) {
532 return done();
533 },
534
535
536 /**
537 * The callback that will be invoked when all chunks have been uploaded for a file.
538 * It gets the file for which the chunks have been uploaded as the first parameter,
539 * and the `done` function as second. `done()` needs to be invoked when everything
540 * needed to finish the upload process is done.
541 */
542 chunksUploaded: function chunksUploaded(file, done) {
543 done();
544 },
545
546 /**
547 * Gets called when the browser is not supported.
548 * The default implementation shows the fallback input field and adds
549 * a text.
550 */
551 fallback: function fallback() {
552 // This code should pass in IE7... :(
553 var messageElement = void 0;
554 this.element.className = this.element.className + " dz-browser-not-supported";
555
556 for (var _iterator2 = this.element.getElementsByTagName("div"), _isArray2 = true, _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
557 var _ref2;
558
559 if (_isArray2) {
560 if (_i2 >= _iterator2.length) break;
561 _ref2 = _iterator2[_i2++];
562 } else {
563 _i2 = _iterator2.next();
564 if (_i2.done) break;
565 _ref2 = _i2.value;
566 }
567
568 var child = _ref2;
569
570 if (/(^| )dz-message($| )/.test(child.className)) {
571 messageElement = child;
572 child.className = "dz-message"; // Removes the 'dz-default' class
573 break;
574 }
575 }
576 if (!messageElement) {
577 messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>");
578 this.element.appendChild(messageElement);
579 }
580
581 var span = messageElement.getElementsByTagName("span")[0];
582 if (span) {
583 if (span.textContent != null) {
584 span.textContent = this.options.dictFallbackMessage;
585 } else if (span.innerText != null) {
586 span.innerText = this.options.dictFallbackMessage;
587 }
588 }
589
590 return this.element.appendChild(this.getFallbackForm());
591 },
592
593
594 /**
595 * Gets called to calculate the thumbnail dimensions.
596 *
597 * It gets `file`, `width` and `height` (both may be `null`) as parameters and must return an object containing:
598 *
599 * - `srcWidth` & `srcHeight` (required)
600 * - `trgWidth` & `trgHeight` (required)
601 * - `srcX` & `srcY` (optional, default `0`)
602 * - `trgX` & `trgY` (optional, default `0`)
603 *
604 * Those values are going to be used by `ctx.drawImage()`.
605 */
606 resize: function resize(file, width, height, resizeMethod) {
607 var info = {
608 srcX: 0,
609 srcY: 0,
610 srcWidth: file.width,
611 srcHeight: file.height
612 };
613
614 var srcRatio = file.width / file.height;
615
616 // Automatically calculate dimensions if not specified
617 if (width == null && height == null) {
618 width = info.srcWidth;
619 height = info.srcHeight;
620 } else if (width == null) {
621 width = height * srcRatio;
622 } else if (height == null) {
623 height = width / srcRatio;
624 }
625
626 // Make sure images aren't upscaled
627 width = Math.min(width, info.srcWidth);
628 height = Math.min(height, info.srcHeight);
629
630 var trgRatio = width / height;
631
632 if (info.srcWidth > width || info.srcHeight > height) {
633 // Image is bigger and needs rescaling
634 if (resizeMethod === 'crop') {
635 if (srcRatio > trgRatio) {
636 info.srcHeight = file.height;
637 info.srcWidth = info.srcHeight * trgRatio;
638 } else {
639 info.srcWidth = file.width;
640 info.srcHeight = info.srcWidth / trgRatio;
641 }
642 } else if (resizeMethod === 'contain') {
643 // Method 'contain'
644 if (srcRatio > trgRatio) {
645 height = width / srcRatio;
646 } else {
647 width = height * srcRatio;
648 }
649 } else {
650 throw new Error("Unknown resizeMethod '" + resizeMethod + "'");
651 }
652 }
653
654 info.srcX = (file.width - info.srcWidth) / 2;
655 info.srcY = (file.height - info.srcHeight) / 2;
656
657 info.trgWidth = width;
658 info.trgHeight = height;
659
660 return info;
661 },
662
663
664 /**
665 * Can be used to transform the file (for example, resize an image if necessary).
666 *
667 * The default implementation uses `resizeWidth` and `resizeHeight` (if provided) and resizes
668 * images according to those dimensions.
669 *
670 * Gets the `file` as the first parameter, and a `done()` function as the second, that needs
671 * to be invoked with the file when the transformation is done.
672 */
673 transformFile: function transformFile(file, done) {
674 if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) {
675 return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done);
676 } else {
677 return done(file);
678 }
679 },
680
681
682 /**
683 * A string that contains the template used for each dropped
684 * file. Change it to fulfill your needs but make sure to properly
685 * provide all elements.
686 *
687 * If you want to use an actual HTML element instead of providing a String
688 * as a config option, you could create a div with the id `tpl`,
689 * put the template inside it and provide the element like this:
690 *
691 * document
692 * .querySelector('#tpl')
693 * .innerHTML
694 *
695 */
696 previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n <div class=\"dz-details\">\n <div class=\"dz-size\"><span data-dz-size></span></div>\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n <div class=\"dz-success-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Check</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </svg>\n </div>\n <div class=\"dz-error-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Error</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>",
697
698 // END OPTIONS
699 // (Required by the dropzone documentation parser)
700
701
702 /*
703 Those functions register themselves to the events on init and handle all
704 the user interface specific stuff. Overwriting them won't break the upload
705 but can break the way it's displayed.
706 You can overwrite them if you don't like the default behavior. If you just
707 want to add an additional event handler, register it on the dropzone object
708 and don't overwrite those options.
709 */
710
711 // Those are self explanatory and simply concern the DragnDrop.
712 drop: function drop(e) {
713 return this.element.classList.remove("dz-drag-hover");
714 },
715 dragstart: function dragstart(e) {},
716 dragend: function dragend(e) {
717 return this.element.classList.remove("dz-drag-hover");
718 },
719 dragenter: function dragenter(e) {
720 return this.element.classList.add("dz-drag-hover");
721 },
722 dragover: function dragover(e) {
723 return this.element.classList.add("dz-drag-hover");
724 },
725 dragleave: function dragleave(e) {
726 return this.element.classList.remove("dz-drag-hover");
727 },
728 paste: function paste(e) {},
729
730
731 // Called whenever there are no files left in the dropzone anymore, and the
732 // dropzone should be displayed as if in the initial state.
733 reset: function reset() {
734 return this.element.classList.remove("dz-started");
735 },
736
737
738 // Called when a file is added to the queue
739 // Receives `file`
740 addedfile: function addedfile(file) {
741 var _this2 = this;
742
743 if (this.element === this.previewsContainer) {
744 this.element.classList.add("dz-started");
745 }
746
747 if (this.previewsContainer) {
748 file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
749 file.previewTemplate = file.previewElement; // Backwards compatibility
750
751 this.previewsContainer.appendChild(file.previewElement);
752 for (var _iterator3 = file.previewElement.querySelectorAll("[data-dz-name]"), _isArray3 = true, _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
753 var _ref3;
754
755 if (_isArray3) {
756 if (_i3 >= _iterator3.length) break;
757 _ref3 = _iterator3[_i3++];
758 } else {
759 _i3 = _iterator3.next();
760 if (_i3.done) break;
761 _ref3 = _i3.value;
762 }
763
764 var node = _ref3;
765
766 node.textContent = file.name;
767 }
768 for (var _iterator4 = file.previewElement.querySelectorAll("[data-dz-size]"), _isArray4 = true, _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
769 if (_isArray4) {
770 if (_i4 >= _iterator4.length) break;
771 node = _iterator4[_i4++];
772 } else {
773 _i4 = _iterator4.next();
774 if (_i4.done) break;
775 node = _i4.value;
776 }
777
778 node.innerHTML = this.filesize(file.size);
779 }
780
781 if (this.options.addRemoveLinks) {
782 file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
783 file.previewElement.appendChild(file._removeLink);
784 }
785
786 var removeFileEvent = function removeFileEvent(e) {
787 e.preventDefault();
788 e.stopPropagation();
789 if (file.status === Dropzone.UPLOADING) {
790 return Dropzone.confirm(_this2.options.dictCancelUploadConfirmation, function () {
791 return _this2.removeFile(file);
792 });
793 } else {
794 if (_this2.options.dictRemoveFileConfirmation) {
795 return Dropzone.confirm(_this2.options.dictRemoveFileConfirmation, function () {
796 return _this2.removeFile(file);
797 });
798 } else {
799 return _this2.removeFile(file);
800 }
801 }
802 };
803
804 for (var _iterator5 = file.previewElement.querySelectorAll("[data-dz-remove]"), _isArray5 = true, _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
805 var _ref4;
806
807 if (_isArray5) {
808 if (_i5 >= _iterator5.length) break;
809 _ref4 = _iterator5[_i5++];
810 } else {
811 _i5 = _iterator5.next();
812 if (_i5.done) break;
813 _ref4 = _i5.value;
814 }
815
816 var removeLink = _ref4;
817
818 removeLink.addEventListener("click", removeFileEvent);
819 }
820 }
821 },
822
823
824 // Called whenever a file is removed.
825 removedfile: function removedfile(file) {
826 if (file.previewElement != null && file.previewElement.parentNode != null) {
827 file.previewElement.parentNode.removeChild(file.previewElement);
828 }
829 return this._updateMaxFilesReachedClass();
830 },
831
832
833 // Called when a thumbnail has been generated
834 // Receives `file` and `dataUrl`
835 thumbnail: function thumbnail(file, dataUrl) {
836 if (file.previewElement) {
837 file.previewElement.classList.remove("dz-file-preview");
838 for (var _iterator6 = file.previewElement.querySelectorAll("[data-dz-thumbnail]"), _isArray6 = true, _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
839 var _ref5;
840
841 if (_isArray6) {
842 if (_i6 >= _iterator6.length) break;
843 _ref5 = _iterator6[_i6++];
844 } else {
845 _i6 = _iterator6.next();
846 if (_i6.done) break;
847 _ref5 = _i6.value;
848 }
849
850 var thumbnailElement = _ref5;
851
852 thumbnailElement.alt = file.name;
853 thumbnailElement.src = dataUrl;
854 }
855
856 return setTimeout(function () {
857 return file.previewElement.classList.add("dz-image-preview");
858 }, 1);
859 }
860 },
861
862
863 // Called whenever an error occurs
864 // Receives `file` and `message`
865 error: function error(file, message) {
866 if (file.previewElement) {
867 file.previewElement.classList.add("dz-error");
868
869 if (typeof message !== "String" && message.error) {
870 message = message.error;
871 }
872 for (var _iterator7 = file.previewElement.querySelectorAll("[data-dz-errormessage]"), _isArray7 = true, _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
873 var _ref6;
874
875 if (_isArray7) {
876 if (_i7 >= _iterator7.length) break;
877 _ref6 = _iterator7[_i7++];
878 } else {
879 _i7 = _iterator7.next();
880 if (_i7.done) break;
881 _ref6 = _i7.value;
882 }
883
884 var node = _ref6;
885
886 node.textContent = message;
887 }
888 }
889 },
890 errormultiple: function errormultiple() {},
891
892
893 // Called when a file gets processed. Since there is a cue, not all added
894 // files are processed immediately.
895 // Receives `file`
896 processing: function processing(file) {
897 if (file.previewElement) {
898 file.previewElement.classList.add("dz-processing");
899 if (file._removeLink) {
900 return file._removeLink.innerHTML = this.options.dictCancelUpload;
901 }
902 }
903 },
904 processingmultiple: function processingmultiple() {},
905
906
907 // Called whenever the upload progress gets updated.
908 // Receives `file`, `progress` (percentage 0-100) and `bytesSent`.
909 // To get the total number of bytes of the file, use `file.size`
910 uploadprogress: function uploadprogress(file, progress, bytesSent) {
911 if (file.previewElement) {
912 for (var _iterator8 = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"), _isArray8 = true, _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
913 var _ref7;
914
915 if (_isArray8) {
916 if (_i8 >= _iterator8.length) break;
917 _ref7 = _iterator8[_i8++];
918 } else {
919 _i8 = _iterator8.next();
920 if (_i8.done) break;
921 _ref7 = _i8.value;
922 }
923
924 var node = _ref7;
925
926 node.nodeName === 'PROGRESS' ? node.value = progress : node.style.width = progress + "%";
927 }
928 }
929 },
930
931
932 // Called whenever the total upload progress gets updated.
933 // Called with totalUploadProgress (0-100), totalBytes and totalBytesSent
934 totaluploadprogress: function totaluploadprogress() {},
935
936
937 // Called just before the file is sent. Gets the `xhr` object as second
938 // parameter, so you can modify it (for example to add a CSRF token) and a
939 // `formData` object to add additional information.
940 sending: function sending() {},
941 sendingmultiple: function sendingmultiple() {},
942
943
944 // When the complete upload is finished and successful
945 // Receives `file`
946 success: function success(file) {
947 if (file.previewElement) {
948 return file.previewElement.classList.add("dz-success");
949 }
950 },
951 successmultiple: function successmultiple() {},
952
953
954 // When the upload is canceled.
955 canceled: function canceled(file) {
956 return this.emit("error", file, this.options.dictUploadCanceled);
957 },
958 canceledmultiple: function canceledmultiple() {},
959
960
961 // When the upload is finished, either with success or an error.
962 // Receives `file`
963 complete: function complete(file) {
964 if (file._removeLink) {
965 file._removeLink.innerHTML = this.options.dictRemoveFile;
966 }
967 if (file.previewElement) {
968 return file.previewElement.classList.add("dz-complete");
969 }
970 },
971 completemultiple: function completemultiple() {},
972 maxfilesexceeded: function maxfilesexceeded() {},
973 maxfilesreached: function maxfilesreached() {},
974 queuecomplete: function queuecomplete() {},
975 addedfiles: function addedfiles() {}
976 };
977
978 this.prototype._thumbnailQueue = [];
979 this.prototype._processingThumbnail = false;
980 }
981
982 // global utility
983
984 }, {
985 key: "extend",
986 value: function extend(target) {
987 for (var _len2 = arguments.length, objects = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
988 objects[_key2 - 1] = arguments[_key2];
989 }
990
991 for (var _iterator9 = objects, _isArray9 = true, _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
992 var _ref8;
993
994 if (_isArray9) {
995 if (_i9 >= _iterator9.length) break;
996 _ref8 = _iterator9[_i9++];
997 } else {
998 _i9 = _iterator9.next();
999 if (_i9.done) break;
1000 _ref8 = _i9.value;
1001 }
1002
1003 var object = _ref8;
1004
1005 for (var key in object) {
1006 var val = object[key];
1007 target[key] = val;
1008 }
1009 }
1010 return target;
1011 }
1012 }]);
1013
1014 function Dropzone(el, options) {
1015 _classCallCheck(this, Dropzone);
1016
1017 var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this));
1018
1019 var fallback = void 0,
1020 left = void 0;
1021 _this.element = el;
1022 // For backwards compatibility since the version was in the prototype previously
1023 _this.version = Dropzone.version;
1024
1025 _this.defaultOptions.previewTemplate = _this.defaultOptions.previewTemplate.replace(/\n*/g, "");
1026
1027 _this.clickableElements = [];
1028 _this.listeners = [];
1029 _this.files = []; // All files
1030
1031 if (typeof _this.element === "string") {
1032 _this.element = document.querySelector(_this.element);
1033 }
1034
1035 // Not checking if instance of HTMLElement or Element since IE9 is extremely weird.
1036 if (!_this.element || _this.element.nodeType == null) {
1037 throw new Error("Invalid dropzone element.");
1038 }
1039
1040 if (_this.element.dropzone) {
1041 throw new Error("Dropzone already attached.");
1042 }
1043
1044 // Now add this dropzone to the instances.
1045 Dropzone.instances.push(_this);
1046
1047 // Put the dropzone inside the element itself.
1048 _this.element.dropzone = _this;
1049
1050 var elementOptions = (left = Dropzone.optionsForElement(_this.element)) != null ? left : {};
1051
1052 _this.options = Dropzone.extend({}, _this.defaultOptions, elementOptions, options != null ? options : {});
1053
1054 // If the browser failed, just call the fallback and leave
1055 if (_this.options.forceFallback || !Dropzone.isBrowserSupported()) {
1056 var _ret;
1057
1058 return _ret = _this.options.fallback.call(_this), _possibleConstructorReturn(_this, _ret);
1059 }
1060
1061 // @options.url = @element.getAttribute "action" unless @options.url?
1062 if (_this.options.url == null) {
1063 _this.options.url = _this.element.getAttribute("action");
1064 }
1065
1066 if (!_this.options.url) {
1067 throw new Error("No URL provided.");
1068 }
1069
1070 if (_this.options.acceptedFiles && _this.options.acceptedMimeTypes) {
1071 throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
1072 }
1073
1074 if (_this.options.uploadMultiple && _this.options.chunking) {
1075 throw new Error('You cannot set both: uploadMultiple and chunking.');
1076 }
1077
1078 // Backwards compatibility
1079 if (_this.options.acceptedMimeTypes) {
1080 _this.options.acceptedFiles = _this.options.acceptedMimeTypes;
1081 delete _this.options.acceptedMimeTypes;
1082 }
1083
1084 // Backwards compatibility
1085 if (_this.options.renameFilename != null) {
1086 _this.options.renameFile = function (file) {
1087 return _this.options.renameFilename.call(_this, file.name, file);
1088 };
1089 }
1090
1091 _this.options.method = _this.options.method.toUpperCase();
1092
1093 if ((fallback = _this.getExistingFallback()) && fallback.parentNode) {
1094 // Remove the fallback
1095 fallback.parentNode.removeChild(fallback);
1096 }
1097
1098 // Display previews in the previewsContainer element or the Dropzone element unless explicitly set to false
1099 if (_this.options.previewsContainer !== false) {
1100 if (_this.options.previewsContainer) {
1101 _this.previewsContainer = Dropzone.getElement(_this.options.previewsContainer, "previewsContainer");
1102 } else {
1103 _this.previewsContainer = _this.element;
1104 }
1105 }
1106
1107 if (_this.options.clickable) {
1108 if (_this.options.clickable === true) {
1109 _this.clickableElements = [_this.element];
1110 } else {
1111 _this.clickableElements = Dropzone.getElements(_this.options.clickable, "clickable");
1112 }
1113 }
1114
1115 _this.init();
1116 return _this;
1117 }
1118
1119 // Returns all files that have been accepted
1120
1121
1122 _createClass(Dropzone, [{
1123 key: "getAcceptedFiles",
1124 value: function getAcceptedFiles() {
1125 return this.files.filter(function (file) {
1126 return file.accepted;
1127 }).map(function (file) {
1128 return file;
1129 });
1130 }
1131
1132 // Returns all files that have been rejected
1133 // Not sure when that's going to be useful, but added for completeness.
1134
1135 }, {
1136 key: "getRejectedFiles",
1137 value: function getRejectedFiles() {
1138 return this.files.filter(function (file) {
1139 return !file.accepted;
1140 }).map(function (file) {
1141 return file;
1142 });
1143 }
1144 }, {
1145 key: "getFilesWithStatus",
1146 value: function getFilesWithStatus(status) {
1147 return this.files.filter(function (file) {
1148 return file.status === status;
1149 }).map(function (file) {
1150 return file;
1151 });
1152 }
1153
1154 // Returns all files that are in the queue
1155
1156 }, {
1157 key: "getQueuedFiles",
1158 value: function getQueuedFiles() {
1159 return this.getFilesWithStatus(Dropzone.QUEUED);
1160 }
1161 }, {
1162 key: "getUploadingFiles",
1163 value: function getUploadingFiles() {
1164 return this.getFilesWithStatus(Dropzone.UPLOADING);
1165 }
1166 }, {
1167 key: "getAddedFiles",
1168 value: function getAddedFiles() {
1169 return this.getFilesWithStatus(Dropzone.ADDED);
1170 }
1171
1172 // Files that are either queued or uploading
1173
1174 }, {
1175 key: "getActiveFiles",
1176 value: function getActiveFiles() {
1177 return this.files.filter(function (file) {
1178 return file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED;
1179 }).map(function (file) {
1180 return file;
1181 });
1182 }
1183
1184 // The function that gets called when Dropzone is initialized. You
1185 // can (and should) setup event listeners inside this function.
1186
1187 }, {
1188 key: "init",
1189 value: function init() {
1190 var _this3 = this;
1191
1192 // In case it isn't set already
1193 if (this.element.tagName === "form") {
1194 this.element.setAttribute("enctype", "multipart/form-data");
1195 }
1196
1197 if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
1198 this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>"));
1199 }
1200
1201 if (this.clickableElements.length) {
1202 var setupHiddenFileInput = function setupHiddenFileInput() {
1203 if (_this3.hiddenFileInput) {
1204 _this3.hiddenFileInput.parentNode.removeChild(_this3.hiddenFileInput);
1205 }
1206 _this3.hiddenFileInput = document.createElement("input");
1207 _this3.hiddenFileInput.setAttribute("type", "file");
1208 if (_this3.options.maxFiles === null || _this3.options.maxFiles > 1) {
1209 _this3.hiddenFileInput.setAttribute("multiple", "multiple");
1210 }
1211 _this3.hiddenFileInput.className = "dz-hidden-input";
1212
1213 if (_this3.options.acceptedFiles !== null) {
1214 _this3.hiddenFileInput.setAttribute("accept", _this3.options.acceptedFiles);
1215 }
1216 if (_this3.options.capture !== null) {
1217 _this3.hiddenFileInput.setAttribute("capture", _this3.options.capture);
1218 }
1219
1220 // Not setting `display="none"` because some browsers don't accept clicks
1221 // on elements that aren't displayed.
1222 _this3.hiddenFileInput.style.visibility = "hidden";
1223 _this3.hiddenFileInput.style.position = "absolute";
1224 _this3.hiddenFileInput.style.top = "0";
1225 _this3.hiddenFileInput.style.left = "0";
1226 _this3.hiddenFileInput.style.height = "0";
1227 _this3.hiddenFileInput.style.width = "0";
1228 Dropzone.getElement(_this3.options.hiddenInputContainer, 'hiddenInputContainer').appendChild(_this3.hiddenFileInput);
1229 return _this3.hiddenFileInput.addEventListener("change", function () {
1230 var files = _this3.hiddenFileInput.files;
1231
1232 if (files.length) {
1233 for (var _iterator10 = files, _isArray10 = true, _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) {
1234 var _ref9;
1235
1236 if (_isArray10) {
1237 if (_i10 >= _iterator10.length) break;
1238 _ref9 = _iterator10[_i10++];
1239 } else {
1240 _i10 = _iterator10.next();
1241 if (_i10.done) break;
1242 _ref9 = _i10.value;
1243 }
1244
1245 var file = _ref9;
1246
1247 _this3.addFile(file);
1248 }
1249 }
1250 _this3.emit("addedfiles", files);
1251 return setupHiddenFileInput();
1252 });
1253 };
1254 setupHiddenFileInput();
1255 }
1256
1257 this.URL = window.URL !== null ? window.URL : window.webkitURL;
1258
1259 // Setup all event listeners on the Dropzone object itself.
1260 // They're not in @setupEventListeners() because they shouldn't be removed
1261 // again when the dropzone gets disabled.
1262 for (var _iterator11 = this.events, _isArray11 = true, _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) {
1263 var _ref10;
1264
1265 if (_isArray11) {
1266 if (_i11 >= _iterator11.length) break;
1267 _ref10 = _iterator11[_i11++];
1268 } else {
1269 _i11 = _iterator11.next();
1270 if (_i11.done) break;
1271 _ref10 = _i11.value;
1272 }
1273
1274 var eventName = _ref10;
1275
1276 this.on(eventName, this.options[eventName]);
1277 }
1278
1279 this.on("uploadprogress", function () {
1280 return _this3.updateTotalUploadProgress();
1281 });
1282
1283 this.on("removedfile", function () {
1284 return _this3.updateTotalUploadProgress();
1285 });
1286
1287 this.on("canceled", function (file) {
1288 return _this3.emit("complete", file);
1289 });
1290
1291 // Emit a `queuecomplete` event if all files finished uploading.
1292 this.on("complete", function (file) {
1293 if (_this3.getAddedFiles().length === 0 && _this3.getUploadingFiles().length === 0 && _this3.getQueuedFiles().length === 0) {
1294 // This needs to be deferred so that `queuecomplete` really triggers after `complete`
1295 return setTimeout(function () {
1296 return _this3.emit("queuecomplete");
1297 }, 0);
1298 }
1299 });
1300
1301 var noPropagation = function noPropagation(e) {
1302 e.stopPropagation();
1303 if (e.preventDefault) {
1304 return e.preventDefault();
1305 } else {
1306 return e.returnValue = false;
1307 }
1308 };
1309
1310 // Create the listeners
1311 this.listeners = [{
1312 element: this.element,
1313 events: {
1314 "dragstart": function dragstart(e) {
1315 return _this3.emit("dragstart", e);
1316 },
1317 "dragenter": function dragenter(e) {
1318 noPropagation(e);
1319 return _this3.emit("dragenter", e);
1320 },
1321 "dragover": function dragover(e) {
1322 // Makes it possible to drag files from chrome's download bar
1323 // http://stackoverflow.com/questions/19526430/drag-and-drop-file-uploads-from-chrome-downloads-bar
1324 // Try is required to prevent bug in Internet Explorer 11 (SCRIPT65535 exception)
1325 var efct = void 0;
1326 try {
1327 efct = e.dataTransfer.effectAllowed;
1328 } catch (error) {}
1329 e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
1330
1331 noPropagation(e);
1332 return _this3.emit("dragover", e);
1333 },
1334 "dragleave": function dragleave(e) {
1335 return _this3.emit("dragleave", e);
1336 },
1337 "drop": function drop(e) {
1338 noPropagation(e);
1339 return _this3.drop(e);
1340 },
1341 "dragend": function dragend(e) {
1342 return _this3.emit("dragend", e);
1343 }
1344
1345 // This is disabled right now, because the browsers don't implement it properly.
1346 // "paste": (e) =>
1347 // noPropagation e
1348 // @paste e
1349 } }];
1350
1351 this.clickableElements.forEach(function (clickableElement) {
1352 return _this3.listeners.push({
1353 element: clickableElement,
1354 events: {
1355 "click": function click(evt) {
1356 // Only the actual dropzone or the message element should trigger file selection
1357 if (clickableElement !== _this3.element || evt.target === _this3.element || Dropzone.elementInside(evt.target, _this3.element.querySelector(".dz-message"))) {
1358 _this3.hiddenFileInput.click(); // Forward the click
1359 }
1360 return true;
1361 }
1362 }
1363 });
1364 });
1365
1366 this.enable();
1367
1368 return this.options.init.call(this);
1369 }
1370
1371 // Not fully tested yet
1372
1373 }, {
1374 key: "destroy",
1375 value: function destroy() {
1376 this.disable();
1377 this.removeAllFiles(true);
1378 if (this.hiddenFileInput != null ? this.hiddenFileInput.parentNode : undefined) {
1379 this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
1380 this.hiddenFileInput = null;
1381 }
1382 delete this.element.dropzone;
1383 return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
1384 }
1385 }, {
1386 key: "updateTotalUploadProgress",
1387 value: function updateTotalUploadProgress() {
1388 var totalUploadProgress = void 0;
1389 var totalBytesSent = 0;
1390 var totalBytes = 0;
1391
1392 var activeFiles = this.getActiveFiles();
1393
1394 if (activeFiles.length) {
1395 for (var _iterator12 = this.getActiveFiles(), _isArray12 = true, _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) {
1396 var _ref11;
1397
1398 if (_isArray12) {
1399 if (_i12 >= _iterator12.length) break;
1400 _ref11 = _iterator12[_i12++];
1401 } else {
1402 _i12 = _iterator12.next();
1403 if (_i12.done) break;
1404 _ref11 = _i12.value;
1405 }
1406
1407 var file = _ref11;
1408
1409 totalBytesSent += file.upload.bytesSent;
1410 totalBytes += file.upload.total;
1411 }
1412 totalUploadProgress = 100 * totalBytesSent / totalBytes;
1413 } else {
1414 totalUploadProgress = 100;
1415 }
1416
1417 return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
1418 }
1419
1420 // @options.paramName can be a function taking one parameter rather than a string.
1421 // A parameter name for a file is obtained simply by calling this with an index number.
1422
1423 }, {
1424 key: "_getParamName",
1425 value: function _getParamName(n) {
1426 if (typeof this.options.paramName === "function") {
1427 return this.options.paramName(n);
1428 } else {
1429 return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
1430 }
1431 }
1432
1433 // If @options.renameFile is a function,
1434 // the function will be used to rename the file.name before appending it to the formData
1435
1436 }, {
1437 key: "_renameFile",
1438 value: function _renameFile(file) {
1439 if (typeof this.options.renameFile !== "function") {
1440 return file.name;
1441 }
1442 return this.options.renameFile(file);
1443 }
1444
1445 // Returns a form that can be used as fallback if the browser does not support DragnDrop
1446 //
1447 // If the dropzone is already a form, only the input field and button are returned. Otherwise a complete form element is provided.
1448 // This code has to pass in IE7 :(
1449
1450 }, {
1451 key: "getFallbackForm",
1452 value: function getFallbackForm() {
1453 var existingFallback = void 0,
1454 form = void 0;
1455 if (existingFallback = this.getExistingFallback()) {
1456 return existingFallback;
1457 }
1458
1459 var fieldsString = "<div class=\"dz-fallback\">";
1460 if (this.options.dictFallbackText) {
1461 fieldsString += "<p>" + this.options.dictFallbackText + "</p>";
1462 }
1463 fieldsString += "<input type=\"file\" name=\"" + this._getParamName(0) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : undefined) + " /><input type=\"submit\" value=\"Upload!\"></div>";
1464
1465 var fields = Dropzone.createElement(fieldsString);
1466 if (this.element.tagName !== "FORM") {
1467 form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>");
1468 form.appendChild(fields);
1469 } else {
1470 // Make sure that the enctype and method attributes are set properly
1471 this.element.setAttribute("enctype", "multipart/form-data");
1472 this.element.setAttribute("method", this.options.method);
1473 }
1474 return form != null ? form : fields;
1475 }
1476
1477 // Returns the fallback elements if they exist already
1478 //
1479 // This code has to pass in IE7 :(
1480
1481 }, {
1482 key: "getExistingFallback",
1483 value: function getExistingFallback() {
1484 var getFallback = function getFallback(elements) {
1485 for (var _iterator13 = elements, _isArray13 = true, _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) {
1486 var _ref12;
1487
1488 if (_isArray13) {
1489 if (_i13 >= _iterator13.length) break;
1490 _ref12 = _iterator13[_i13++];
1491 } else {
1492 _i13 = _iterator13.next();
1493 if (_i13.done) break;
1494 _ref12 = _i13.value;
1495 }
1496
1497 var el = _ref12;
1498
1499 if (/(^| )fallback($| )/.test(el.className)) {
1500 return el;
1501 }
1502 }
1503 };
1504
1505 var _arr = ["div", "form"];
1506 for (var _i14 = 0; _i14 < _arr.length; _i14++) {
1507 var tagName = _arr[_i14];
1508 var fallback;
1509 if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
1510 return fallback;
1511 }
1512 }
1513 }
1514
1515 // Activates all listeners stored in @listeners
1516
1517 }, {
1518 key: "setupEventListeners",
1519 value: function setupEventListeners() {
1520 return this.listeners.map(function (elementListeners) {
1521 return function () {
1522 var result = [];
1523 for (var event in elementListeners.events) {
1524 var listener = elementListeners.events[event];
1525 result.push(elementListeners.element.addEventListener(event, listener, false));
1526 }
1527 return result;
1528 }();
1529 });
1530 }
1531
1532 // Deactivates all listeners stored in @listeners
1533
1534 }, {
1535 key: "removeEventListeners",
1536 value: function removeEventListeners() {
1537 return this.listeners.map(function (elementListeners) {
1538 return function () {
1539 var result = [];
1540 for (var event in elementListeners.events) {
1541 var listener = elementListeners.events[event];
1542 result.push(elementListeners.element.removeEventListener(event, listener, false));
1543 }
1544 return result;
1545 }();
1546 });
1547 }
1548
1549 // Removes all event listeners and cancels all files in the queue or being processed.
1550
1551 }, {
1552 key: "disable",
1553 value: function disable() {
1554 var _this4 = this;
1555
1556 this.clickableElements.forEach(function (element) {
1557 return element.classList.remove("dz-clickable");
1558 });
1559 this.removeEventListeners();
1560 this.disabled = true;
1561
1562 return this.files.map(function (file) {
1563 return _this4.cancelUpload(file);
1564 });
1565 }
1566 }, {
1567 key: "enable",
1568 value: function enable() {
1569 delete this.disabled;
1570 this.clickableElements.forEach(function (element) {
1571 return element.classList.add("dz-clickable");
1572 });
1573 return this.setupEventListeners();
1574 }
1575
1576 // Returns a nicely formatted filesize
1577
1578 }, {
1579 key: "filesize",
1580 value: function filesize(size) {
1581 var selectedSize = 0;
1582 var selectedUnit = "b";
1583
1584 if (size > 0) {
1585 var units = ['tb', 'gb', 'mb', 'kb', 'b'];
1586
1587 for (var i = 0; i < units.length; i++) {
1588 var unit = units[i];
1589 var cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;
1590
1591 if (size >= cutoff) {
1592 selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
1593 selectedUnit = unit;
1594 break;
1595 }
1596 }
1597
1598 selectedSize = Math.round(10 * selectedSize) / 10; // Cutting of digits
1599 }
1600
1601 return "<strong>" + selectedSize + "</strong> " + this.options.dictFileSizeUnits[selectedUnit];
1602 }
1603
1604 // Adds or removes the `dz-max-files-reached` class from the form.
1605
1606 }, {
1607 key: "_updateMaxFilesReachedClass",
1608 value: function _updateMaxFilesReachedClass() {
1609 if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {
1610 if (this.getAcceptedFiles().length === this.options.maxFiles) {
1611 this.emit('maxfilesreached', this.files);
1612 }
1613 return this.element.classList.add("dz-max-files-reached");
1614 } else {
1615 return this.element.classList.remove("dz-max-files-reached");
1616 }
1617 }
1618 }, {
1619 key: "drop",
1620 value: function drop(e) {
1621 if (!e.dataTransfer) {
1622 return;
1623 }
1624 this.emit("drop", e);
1625
1626 // Convert the FileList to an Array
1627 // This is necessary for IE11
1628 var files = [];
1629 for (var i = 0; i < e.dataTransfer.files.length; i++) {
1630 files[i] = e.dataTransfer.files[i];
1631 }
1632
1633 this.emit("addedfiles", files);
1634
1635 // Even if it's a folder, files.length will contain the folders.
1636 if (files.length) {
1637 var items = e.dataTransfer.items;
1638
1639 if (items && items.length && items[0].webkitGetAsEntry != null) {
1640 // The browser supports dropping of folders, so handle items instead of files
1641 this._addFilesFromItems(items);
1642 } else {
1643 this.handleFiles(files);
1644 }
1645 }
1646 }
1647 }, {
1648 key: "paste",
1649 value: function paste(e) {
1650 if (__guard__(e != null ? e.clipboardData : undefined, function (x) {
1651 return x.items;
1652 }) == null) {
1653 return;
1654 }
1655
1656 this.emit("paste", e);
1657 var items = e.clipboardData.items;
1658
1659
1660 if (items.length) {
1661 return this._addFilesFromItems(items);
1662 }
1663 }
1664 }, {
1665 key: "handleFiles",
1666 value: function handleFiles(files) {
1667 for (var _iterator14 = files, _isArray14 = true, _i15 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) {
1668 var _ref13;
1669
1670 if (_isArray14) {
1671 if (_i15 >= _iterator14.length) break;
1672 _ref13 = _iterator14[_i15++];
1673 } else {
1674 _i15 = _iterator14.next();
1675 if (_i15.done) break;
1676 _ref13 = _i15.value;
1677 }
1678
1679 var file = _ref13;
1680
1681 this.addFile(file);
1682 }
1683 }
1684
1685 // When a folder is dropped (or files are pasted), items must be handled
1686 // instead of files.
1687
1688 }, {
1689 key: "_addFilesFromItems",
1690 value: function _addFilesFromItems(items) {
1691 var _this5 = this;
1692
1693 return function () {
1694 var result = [];
1695 for (var _iterator15 = items, _isArray15 = true, _i16 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) {
1696 var _ref14;
1697
1698 if (_isArray15) {
1699 if (_i16 >= _iterator15.length) break;
1700 _ref14 = _iterator15[_i16++];
1701 } else {
1702 _i16 = _iterator15.next();
1703 if (_i16.done) break;
1704 _ref14 = _i16.value;
1705 }
1706
1707 var item = _ref14;
1708
1709 var entry;
1710 if (item.webkitGetAsEntry != null && (entry = item.webkitGetAsEntry())) {
1711 if (entry.isFile) {
1712 result.push(_this5.addFile(item.getAsFile()));
1713 } else if (entry.isDirectory) {
1714 // Append all files from that directory to files
1715 result.push(_this5._addFilesFromDirectory(entry, entry.name));
1716 } else {
1717 result.push(undefined);
1718 }
1719 } else if (item.getAsFile != null) {
1720 if (item.kind == null || item.kind === "file") {
1721 result.push(_this5.addFile(item.getAsFile()));
1722 } else {
1723 result.push(undefined);
1724 }
1725 } else {
1726 result.push(undefined);
1727 }
1728 }
1729 return result;
1730 }();
1731 }
1732
1733 // Goes through the directory, and adds each file it finds recursively
1734
1735 }, {
1736 key: "_addFilesFromDirectory",
1737 value: function _addFilesFromDirectory(directory, path) {
1738 var _this6 = this;
1739
1740 var dirReader = directory.createReader();
1741
1742 var errorHandler = function errorHandler(error) {
1743 return __guardMethod__(console, 'log', function (o) {
1744 return o.log(error);
1745 });
1746 };
1747
1748 var readEntries = function readEntries() {
1749 return dirReader.readEntries(function (entries) {
1750 if (entries.length > 0) {
1751 for (var _iterator16 = entries, _isArray16 = true, _i17 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) {
1752 var _ref15;
1753
1754 if (_isArray16) {
1755 if (_i17 >= _iterator16.length) break;
1756 _ref15 = _iterator16[_i17++];
1757 } else {
1758 _i17 = _iterator16.next();
1759 if (_i17.done) break;
1760 _ref15 = _i17.value;
1761 }
1762
1763 var entry = _ref15;
1764
1765 if (entry.isFile) {
1766 entry.file(function (file) {
1767 if (_this6.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
1768 return;
1769 }
1770 file.fullPath = path + "/" + file.name;
1771 return _this6.addFile(file);
1772 });
1773 } else if (entry.isDirectory) {
1774 _this6._addFilesFromDirectory(entry, path + "/" + entry.name);
1775 }
1776 }
1777
1778 // Recursively call readEntries() again, since browser only handle
1779 // the first 100 entries.
1780 // See: https://developer.mozilla.org/en-US/docs/Web/API/DirectoryReader#readEntries
1781 readEntries();
1782 }
1783 return null;
1784 }, errorHandler);
1785 };
1786
1787 return readEntries();
1788 }
1789
1790 // If `done()` is called without argument the file is accepted
1791 // If you call it with an error message, the file is rejected
1792 // (This allows for asynchronous validation)
1793 //
1794 // This function checks the filesize, and if the file.type passes the
1795 // `acceptedFiles` check.
1796
1797 }, {
1798 key: "accept",
1799 value: function accept(file, done) {
1800 if (this.options.maxFilesize && file.size > this.options.maxFilesize * 1024 * 1024) {
1801 return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
1802 } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
1803 return done(this.options.dictInvalidFileType);
1804 } else if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {
1805 done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
1806 return this.emit("maxfilesexceeded", file);
1807 } else {
1808 return this.options.accept.call(this, file, done);
1809 }
1810 }
1811 }, {
1812 key: "addFile",
1813 value: function addFile(file) {
1814 var _this7 = this;
1815
1816 file.upload = {
1817 uuid: Dropzone.uuidv4(),
1818 progress: 0,
1819 // Setting the total upload size to file.size for the beginning
1820 // It's actual different than the size to be transmitted.
1821 total: file.size,
1822 bytesSent: 0,
1823 filename: this._renameFile(file),
1824 chunked: this.options.chunking && (this.options.forceChunking || file.size > this.options.chunkSize),
1825 totalChunkCount: Math.ceil(file.size / this.options.chunkSize)
1826 };
1827 this.files.push(file);
1828
1829 file.status = Dropzone.ADDED;
1830
1831 this.emit("addedfile", file);
1832
1833 this._enqueueThumbnail(file);
1834
1835 return this.accept(file, function (error) {
1836 if (error) {
1837 file.accepted = false;
1838 _this7._errorProcessing([file], error); // Will set the file.status
1839 } else {
1840 file.accepted = true;
1841 if (_this7.options.autoQueue) {
1842 _this7.enqueueFile(file);
1843 } // Will set .accepted = true
1844 }
1845 return _this7._updateMaxFilesReachedClass();
1846 });
1847 }
1848
1849 // Wrapper for enqueueFile
1850
1851 }, {
1852 key: "enqueueFiles",
1853 value: function enqueueFiles(files) {
1854 for (var _iterator17 = files, _isArray17 = true, _i18 = 0, _iterator17 = _isArray17 ? _iterator17 : _iterator17[Symbol.iterator]();;) {
1855 var _ref16;
1856
1857 if (_isArray17) {
1858 if (_i18 >= _iterator17.length) break;
1859 _ref16 = _iterator17[_i18++];
1860 } else {
1861 _i18 = _iterator17.next();
1862 if (_i18.done) break;
1863 _ref16 = _i18.value;
1864 }
1865
1866 var file = _ref16;
1867
1868 this.enqueueFile(file);
1869 }
1870 return null;
1871 }
1872 }, {
1873 key: "enqueueFile",
1874 value: function enqueueFile(file) {
1875 var _this8 = this;
1876
1877 if (file.status === Dropzone.ADDED && file.accepted === true) {
1878 file.status = Dropzone.QUEUED;
1879 if (this.options.autoProcessQueue) {
1880 return setTimeout(function () {
1881 return _this8.processQueue();
1882 }, 0); // Deferring the call
1883 }
1884 } else {
1885 throw new Error("This file can't be queued because it has already been processed or was rejected.");
1886 }
1887 }
1888 }, {
1889 key: "_enqueueThumbnail",
1890 value: function _enqueueThumbnail(file) {
1891 var _this9 = this;
1892
1893 if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
1894 this._thumbnailQueue.push(file);
1895 return setTimeout(function () {
1896 return _this9._processThumbnailQueue();
1897 }, 0); // Deferring the call
1898 }
1899 }
1900 }, {
1901 key: "_processThumbnailQueue",
1902 value: function _processThumbnailQueue() {
1903 var _this10 = this;
1904
1905 if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
1906 return;
1907 }
1908
1909 this._processingThumbnail = true;
1910 var file = this._thumbnailQueue.shift();
1911 return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, function (dataUrl) {
1912 _this10.emit("thumbnail", file, dataUrl);
1913 _this10._processingThumbnail = false;
1914 return _this10._processThumbnailQueue();
1915 });
1916 }
1917
1918 // Can be called by the user to remove a file
1919
1920 }, {
1921 key: "removeFile",
1922 value: function removeFile(file) {
1923 if (file.status === Dropzone.UPLOADING) {
1924 this.cancelUpload(file);
1925 }
1926 this.files = without(this.files, file);
1927
1928 this.emit("removedfile", file);
1929 if (this.files.length === 0) {
1930 return this.emit("reset");
1931 }
1932 }
1933
1934 // Removes all files that aren't currently processed from the list
1935
1936 }, {
1937 key: "removeAllFiles",
1938 value: function removeAllFiles(cancelIfNecessary) {
1939 // Create a copy of files since removeFile() changes the @files array.
1940 if (cancelIfNecessary == null) {
1941 cancelIfNecessary = false;
1942 }
1943 for (var _iterator18 = this.files.slice(), _isArray18 = true, _i19 = 0, _iterator18 = _isArray18 ? _iterator18 : _iterator18[Symbol.iterator]();;) {
1944 var _ref17;
1945
1946 if (_isArray18) {
1947 if (_i19 >= _iterator18.length) break;
1948 _ref17 = _iterator18[_i19++];
1949 } else {
1950 _i19 = _iterator18.next();
1951 if (_i19.done) break;
1952 _ref17 = _i19.value;
1953 }
1954
1955 var file = _ref17;
1956
1957 if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
1958 this.removeFile(file);
1959 }
1960 }
1961 return null;
1962 }
1963
1964 // Resizes an image before it gets sent to the server. This function is the default behavior of
1965 // `options.transformFile` if `resizeWidth` or `resizeHeight` are set. The callback is invoked with
1966 // the resized blob.
1967
1968 }, {
1969 key: "resizeImage",
1970 value: function resizeImage(file, width, height, resizeMethod, callback) {
1971 var _this11 = this;
1972
1973 return this.createThumbnail(file, width, height, resizeMethod, true, function (dataUrl, canvas) {
1974 if (canvas == null) {
1975 // The image has not been resized
1976 return callback(file);
1977 } else {
1978 var resizeMimeType = _this11.options.resizeMimeType;
1979
1980 if (resizeMimeType == null) {
1981 resizeMimeType = file.type;
1982 }
1983 var resizedDataURL = canvas.toDataURL(resizeMimeType, _this11.options.resizeQuality);
1984 if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') {
1985 // Now add the original EXIF information
1986 resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL);
1987 }
1988 return callback(Dropzone.dataURItoBlob(resizedDataURL));
1989 }
1990 });
1991 }
1992 }, {
1993 key: "createThumbnail",
1994 value: function createThumbnail(file, width, height, resizeMethod, fixOrientation, callback) {
1995 var _this12 = this;
1996
1997 var fileReader = new FileReader();
1998
1999 fileReader.onload = function () {
2000
2001 file.dataURL = fileReader.result;
2002
2003 // Don't bother creating a thumbnail for SVG images since they're vector
2004 if (file.type === "image/svg+xml") {
2005 if (callback != null) {
2006 callback(fileReader.result);
2007 }
2008 return;
2009 }
2010
2011 return _this12.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback);
2012 };
2013
2014 return fileReader.readAsDataURL(file);
2015 }
2016 }, {
2017 key: "createThumbnailFromUrl",
2018 value: function createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) {
2019 var _this13 = this;
2020
2021 // Not using `new Image` here because of a bug in latest Chrome versions.
2022 // See https://github.com/enyo/dropzone/pull/226
2023 var img = document.createElement("img");
2024
2025 if (crossOrigin) {
2026 img.crossOrigin = crossOrigin;
2027 }
2028
2029 img.onload = function () {
2030 var loadExif = function loadExif(callback) {
2031 return callback(1);
2032 };
2033 if (typeof EXIF !== 'undefined' && EXIF !== null && fixOrientation) {
2034 loadExif = function loadExif(callback) {
2035 return EXIF.getData(img, function () {
2036 return callback(EXIF.getTag(this, 'Orientation'));
2037 });
2038 };
2039 }
2040
2041 return loadExif(function (orientation) {
2042 file.width = img.width;
2043 file.height = img.height;
2044
2045 var resizeInfo = _this13.options.resize.call(_this13, file, width, height, resizeMethod);
2046
2047 var canvas = document.createElement("canvas");
2048 var ctx = canvas.getContext("2d");
2049
2050 canvas.width = resizeInfo.trgWidth;
2051 canvas.height = resizeInfo.trgHeight;
2052
2053 if (orientation > 4) {
2054 canvas.width = resizeInfo.trgHeight;
2055 canvas.height = resizeInfo.trgWidth;
2056 }
2057
2058 switch (orientation) {
2059 case 2:
2060 // horizontal flip
2061 ctx.translate(canvas.width, 0);
2062 ctx.scale(-1, 1);
2063 break;
2064 case 3:
2065 // 180° rotate left
2066 ctx.translate(canvas.width, canvas.height);
2067 ctx.rotate(Math.PI);
2068 break;
2069 case 4:
2070 // vertical flip
2071 ctx.translate(0, canvas.height);
2072 ctx.scale(1, -1);
2073 break;
2074 case 5:
2075 // vertical flip + 90 rotate right
2076 ctx.rotate(0.5 * Math.PI);
2077 ctx.scale(1, -1);
2078 break;
2079 case 6:
2080 // 90° rotate right
2081 ctx.rotate(0.5 * Math.PI);
2082 ctx.translate(0, -canvas.width);
2083 break;
2084 case 7:
2085 // horizontal flip + 90 rotate right
2086 ctx.rotate(0.5 * Math.PI);
2087 ctx.translate(canvas.height, -canvas.width);
2088 ctx.scale(-1, 1);
2089 break;
2090 case 8:
2091 // 90° rotate left
2092 ctx.rotate(-0.5 * Math.PI);
2093 ctx.translate(-canvas.height, 0);
2094 break;
2095 }
2096
2097 // This is a bugfix for iOS' scaling bug.
2098 drawImageIOSFix(ctx, img, resizeInfo.srcX != null ? resizeInfo.srcX : 0, resizeInfo.srcY != null ? resizeInfo.srcY : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, resizeInfo.trgX != null ? resizeInfo.trgX : 0, resizeInfo.trgY != null ? resizeInfo.trgY : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
2099
2100 var thumbnail = canvas.toDataURL("image/png");
2101
2102 if (callback != null) {
2103 return callback(thumbnail, canvas);
2104 }
2105 });
2106 };
2107
2108 if (callback != null) {
2109 img.onerror = callback;
2110 }
2111
2112 return img.src = file.dataURL;
2113 }
2114
2115 // Goes through the queue and processes files if there aren't too many already.
2116
2117 }, {
2118 key: "processQueue",
2119 value: function processQueue() {
2120 var parallelUploads = this.options.parallelUploads;
2121
2122 var processingLength = this.getUploadingFiles().length;
2123 var i = processingLength;
2124
2125 // There are already at least as many files uploading than should be
2126 if (processingLength >= parallelUploads) {
2127 return;
2128 }
2129
2130 var queuedFiles = this.getQueuedFiles();
2131
2132 if (!(queuedFiles.length > 0)) {
2133 return;
2134 }
2135
2136 if (this.options.uploadMultiple) {
2137 // The files should be uploaded in one request
2138 return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
2139 } else {
2140 while (i < parallelUploads) {
2141 if (!queuedFiles.length) {
2142 return;
2143 } // Nothing left to process
2144 this.processFile(queuedFiles.shift());
2145 i++;
2146 }
2147 }
2148 }
2149
2150 // Wrapper for `processFiles`
2151
2152 }, {
2153 key: "processFile",
2154 value: function processFile(file) {
2155 return this.processFiles([file]);
2156 }
2157
2158 // Loads the file, then calls finishedLoading()
2159
2160 }, {
2161 key: "processFiles",
2162 value: function processFiles(files) {
2163 for (var _iterator19 = files, _isArray19 = true, _i20 = 0, _iterator19 = _isArray19 ? _iterator19 : _iterator19[Symbol.iterator]();;) {
2164 var _ref18;
2165
2166 if (_isArray19) {
2167 if (_i20 >= _iterator19.length) break;
2168 _ref18 = _iterator19[_i20++];
2169 } else {
2170 _i20 = _iterator19.next();
2171 if (_i20.done) break;
2172 _ref18 = _i20.value;
2173 }
2174
2175 var file = _ref18;
2176
2177 file.processing = true; // Backwards compatibility
2178 file.status = Dropzone.UPLOADING;
2179
2180 this.emit("processing", file);
2181 }
2182
2183 if (this.options.uploadMultiple) {
2184 this.emit("processingmultiple", files);
2185 }
2186
2187 return this.uploadFiles(files);
2188 }
2189 }, {
2190 key: "_getFilesWithXhr",
2191 value: function _getFilesWithXhr(xhr) {
2192 var files = void 0;
2193 return files = this.files.filter(function (file) {
2194 return file.xhr === xhr;
2195 }).map(function (file) {
2196 return file;
2197 });
2198 }
2199
2200 // Cancels the file upload and sets the status to CANCELED
2201 // **if** the file is actually being uploaded.
2202 // If it's still in the queue, the file is being removed from it and the status
2203 // set to CANCELED.
2204
2205 }, {
2206 key: "cancelUpload",
2207 value: function cancelUpload(file) {
2208 if (file.status === Dropzone.UPLOADING) {
2209 var groupedFiles = this._getFilesWithXhr(file.xhr);
2210 for (var _iterator20 = groupedFiles, _isArray20 = true, _i21 = 0, _iterator20 = _isArray20 ? _iterator20 : _iterator20[Symbol.iterator]();;) {
2211 var _ref19;
2212
2213 if (_isArray20) {
2214 if (_i21 >= _iterator20.length) break;
2215 _ref19 = _iterator20[_i21++];
2216 } else {
2217 _i21 = _iterator20.next();
2218 if (_i21.done) break;
2219 _ref19 = _i21.value;
2220 }
2221
2222 var groupedFile = _ref19;
2223
2224 groupedFile.status = Dropzone.CANCELED;
2225 }
2226 if (typeof file.xhr !== 'undefined') {
2227 file.xhr.abort();
2228 }
2229 for (var _iterator21 = groupedFiles, _isArray21 = true, _i22 = 0, _iterator21 = _isArray21 ? _iterator21 : _iterator21[Symbol.iterator]();;) {
2230 var _ref20;
2231
2232 if (_isArray21) {
2233 if (_i22 >= _iterator21.length) break;
2234 _ref20 = _iterator21[_i22++];
2235 } else {
2236 _i22 = _iterator21.next();
2237 if (_i22.done) break;
2238 _ref20 = _i22.value;
2239 }
2240
2241 var _groupedFile = _ref20;
2242
2243 this.emit("canceled", _groupedFile);
2244 }
2245 if (this.options.uploadMultiple) {
2246 this.emit("canceledmultiple", groupedFiles);
2247 }
2248 } else if (file.status === Dropzone.ADDED || file.status === Dropzone.QUEUED) {
2249 file.status = Dropzone.CANCELED;
2250 this.emit("canceled", file);
2251 if (this.options.uploadMultiple) {
2252 this.emit("canceledmultiple", [file]);
2253 }
2254 }
2255
2256 if (this.options.autoProcessQueue) {
2257 return this.processQueue();
2258 }
2259 }
2260 }, {
2261 key: "resolveOption",
2262 value: function resolveOption(option) {
2263 if (typeof option === 'function') {
2264 for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
2265 args[_key3 - 1] = arguments[_key3];
2266 }
2267
2268 return option.apply(this, args);
2269 }
2270 return option;
2271 }
2272 }, {
2273 key: "uploadFile",
2274 value: function uploadFile(file) {
2275 return this.uploadFiles([file]);
2276 }
2277 }, {
2278 key: "uploadFiles",
2279 value: function uploadFiles(files) {
2280 var _this14 = this;
2281
2282 this._transformFiles(files, function (transformedFiles) {
2283 if (files[0].upload.chunked) {
2284 // This file should be sent in chunks!
2285
2286 // If the chunking option is set, we **know** that there can only be **one** file, since
2287 // uploadMultiple is not allowed with this option.
2288 var file = files[0];
2289 var transformedFile = transformedFiles[0];
2290 var startedChunkCount = 0;
2291
2292 file.upload.chunks = [];
2293
2294 var handleNextChunk = function handleNextChunk() {
2295 var chunkIndex = 0;
2296
2297 // Find the next item in file.upload.chunks that is not defined yet.
2298 while (file.upload.chunks[chunkIndex] !== undefined) {
2299 chunkIndex++;
2300 }
2301
2302 // This means, that all chunks have already been started.
2303 if (chunkIndex >= file.upload.totalChunkCount) return;
2304
2305 startedChunkCount++;
2306
2307 var start = chunkIndex * _this14.options.chunkSize;
2308 var end = Math.min(start + _this14.options.chunkSize, file.size);
2309
2310 var dataBlock = {
2311 name: _this14._getParamName(0),
2312 data: transformedFile.webkitSlice ? transformedFile.webkitSlice(start, end) : transformedFile.slice(start, end),
2313 filename: file.upload.filename,
2314 chunkIndex: chunkIndex
2315 };
2316
2317 file.upload.chunks[chunkIndex] = {
2318 file: file,
2319 index: chunkIndex,
2320 dataBlock: dataBlock, // In case we want to retry.
2321 status: Dropzone.UPLOADING,
2322 progress: 0,
2323 retries: 0 // The number of times this block has been retried.
2324 };
2325
2326 _this14._uploadData(files, [dataBlock]);
2327 };
2328
2329 file.upload.finishedChunkUpload = function (chunk) {
2330 var allFinished = true;
2331 chunk.status = Dropzone.SUCCESS;
2332
2333 // Clear the data from the chunk
2334 chunk.dataBlock = null;
2335 // Leaving this reference to xhr intact here will cause memory leaks in some browsers
2336 chunk.xhr = null;
2337
2338 for (var i = 0; i < file.upload.totalChunkCount; i++) {
2339 if (file.upload.chunks[i] === undefined) {
2340 return handleNextChunk();
2341 }
2342 if (file.upload.chunks[i].status !== Dropzone.SUCCESS) {
2343 allFinished = false;
2344 }
2345 }
2346
2347 if (allFinished) {
2348 _this14.options.chunksUploaded(file, function () {
2349 _this14._finished(files, '', null);
2350 });
2351 }
2352 };
2353
2354 if (_this14.options.parallelChunkUploads) {
2355 for (var i = 0; i < file.upload.totalChunkCount; i++) {
2356 handleNextChunk();
2357 }
2358 } else {
2359 handleNextChunk();
2360 }
2361 } else {
2362 var dataBlocks = [];
2363 for (var _i23 = 0; _i23 < files.length; _i23++) {
2364 dataBlocks[_i23] = {
2365 name: _this14._getParamName(_i23),
2366 data: transformedFiles[_i23],
2367 filename: files[_i23].upload.filename
2368 };
2369 }
2370 _this14._uploadData(files, dataBlocks);
2371 }
2372 });
2373 }
2374
2375 /// Returns the right chunk for given file and xhr
2376
2377 }, {
2378 key: "_getChunk",
2379 value: function _getChunk(file, xhr) {
2380 for (var i = 0; i < file.upload.totalChunkCount; i++) {
2381 if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].xhr === xhr) {
2382 return file.upload.chunks[i];
2383 }
2384 }
2385 }
2386
2387 // This function actually uploads the file(s) to the server.
2388 // If dataBlocks contains the actual data to upload (meaning, that this could either be transformed
2389 // files, or individual chunks for chunked upload).
2390
2391 }, {
2392 key: "_uploadData",
2393 value: function _uploadData(files, dataBlocks) {
2394 var _this15 = this;
2395
2396 var xhr = new XMLHttpRequest();
2397
2398 // Put the xhr object in the file objects to be able to reference it later.
2399 for (var _iterator22 = files, _isArray22 = true, _i24 = 0, _iterator22 = _isArray22 ? _iterator22 : _iterator22[Symbol.iterator]();;) {
2400 var _ref21;
2401
2402 if (_isArray22) {
2403 if (_i24 >= _iterator22.length) break;
2404 _ref21 = _iterator22[_i24++];
2405 } else {
2406 _i24 = _iterator22.next();
2407 if (_i24.done) break;
2408 _ref21 = _i24.value;
2409 }
2410
2411 var file = _ref21;
2412
2413 file.xhr = xhr;
2414 }
2415 if (files[0].upload.chunked) {
2416 // Put the xhr object in the right chunk object, so it can be associated later, and found with _getChunk
2417 files[0].upload.chunks[dataBlocks[0].chunkIndex].xhr = xhr;
2418 }
2419
2420 var method = this.resolveOption(this.options.method, files);
2421 var url = this.resolveOption(this.options.url, files);
2422 xhr.open(method, url, true);
2423
2424 // Setting the timeout after open because of IE11 issue: https://gitlab.com/meno/dropzone/issues/8
2425 xhr.timeout = this.resolveOption(this.options.timeout, files);
2426
2427 // Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
2428 xhr.withCredentials = !!this.options.withCredentials;
2429
2430 xhr.onload = function (e) {
2431 _this15._finishedUploading(files, xhr, e);
2432 };
2433
2434 xhr.onerror = function () {
2435 _this15._handleUploadError(files, xhr);
2436 };
2437
2438 // Some browsers do not have the .upload property
2439 var progressObj = xhr.upload != null ? xhr.upload : xhr;
2440 progressObj.onprogress = function (e) {
2441 return _this15._updateFilesUploadProgress(files, xhr, e);
2442 };
2443
2444 var headers = {
2445 "Accept": "application/json",
2446 "Cache-Control": "no-cache",
2447 "X-Requested-With": "XMLHttpRequest"
2448 };
2449
2450 if (this.options.headers) {
2451 Dropzone.extend(headers, this.options.headers);
2452 }
2453
2454 for (var headerName in headers) {
2455 var headerValue = headers[headerName];
2456 if (headerValue) {
2457 xhr.setRequestHeader(headerName, headerValue);
2458 }
2459 }
2460
2461 var formData = new FormData();
2462
2463 // Adding all @options parameters
2464 if (this.options.params) {
2465 var additionalParams = this.options.params;
2466 if (typeof additionalParams === 'function') {
2467 additionalParams = additionalParams.call(this, files, xhr, files[0].upload.chunked ? this._getChunk(files[0], xhr) : null);
2468 }
2469
2470 for (var key in additionalParams) {
2471 var value = additionalParams[key];
2472 formData.append(key, value);
2473 }
2474 }
2475
2476 // Let the user add additional data if necessary
2477 for (var _iterator23 = files, _isArray23 = true, _i25 = 0, _iterator23 = _isArray23 ? _iterator23 : _iterator23[Symbol.iterator]();;) {
2478 var _ref22;
2479
2480 if (_isArray23) {
2481 if (_i25 >= _iterator23.length) break;
2482 _ref22 = _iterator23[_i25++];
2483 } else {
2484 _i25 = _iterator23.next();
2485 if (_i25.done) break;
2486 _ref22 = _i25.value;
2487 }
2488
2489 var _file = _ref22;
2490
2491 this.emit("sending", _file, xhr, formData);
2492 }
2493 if (this.options.uploadMultiple) {
2494 this.emit("sendingmultiple", files, xhr, formData);
2495 }
2496
2497 this._addFormElementData(formData);
2498
2499 // Finally add the files
2500 // Has to be last because some servers (eg: S3) expect the file to be the last parameter
2501 for (var i = 0; i < dataBlocks.length; i++) {
2502 var dataBlock = dataBlocks[i];
2503 formData.append(dataBlock.name, dataBlock.data, dataBlock.filename);
2504 }
2505
2506 this.submitRequest(xhr, formData, files);
2507 }
2508
2509 // Transforms all files with this.options.transformFile and invokes done with the transformed files when done.
2510
2511 }, {
2512 key: "_transformFiles",
2513 value: function _transformFiles(files, done) {
2514 var _this16 = this;
2515
2516 var transformedFiles = [];
2517 // Clumsy way of handling asynchronous calls, until I get to add a proper Future library.
2518 var doneCounter = 0;
2519
2520 var _loop = function _loop(i) {
2521 _this16.options.transformFile.call(_this16, files[i], function (transformedFile) {
2522 transformedFiles[i] = transformedFile;
2523 if (++doneCounter === files.length) {
2524 done(transformedFiles);
2525 }
2526 });
2527 };
2528
2529 for (var i = 0; i < files.length; i++) {
2530 _loop(i);
2531 }
2532 }
2533
2534 // Takes care of adding other input elements of the form to the AJAX request
2535
2536 }, {
2537 key: "_addFormElementData",
2538 value: function _addFormElementData(formData) {
2539 // Take care of other input elements
2540 if (this.element.tagName === "FORM") {
2541 for (var _iterator24 = this.element.querySelectorAll("input, textarea, select, button"), _isArray24 = true, _i26 = 0, _iterator24 = _isArray24 ? _iterator24 : _iterator24[Symbol.iterator]();;) {
2542 var _ref23;
2543
2544 if (_isArray24) {
2545 if (_i26 >= _iterator24.length) break;
2546 _ref23 = _iterator24[_i26++];
2547 } else {
2548 _i26 = _iterator24.next();
2549 if (_i26.done) break;
2550 _ref23 = _i26.value;
2551 }
2552
2553 var input = _ref23;
2554
2555 var inputName = input.getAttribute("name");
2556 var inputType = input.getAttribute("type");
2557 if (inputType) inputType = inputType.toLowerCase();
2558
2559 // If the input doesn't have a name, we can't use it.
2560 if (typeof inputName === 'undefined' || inputName === null) continue;
2561
2562 if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
2563 // Possibly multiple values
2564 for (var _iterator25 = input.options, _isArray25 = true, _i27 = 0, _iterator25 = _isArray25 ? _iterator25 : _iterator25[Symbol.iterator]();;) {
2565 var _ref24;
2566
2567 if (_isArray25) {
2568 if (_i27 >= _iterator25.length) break;
2569 _ref24 = _iterator25[_i27++];
2570 } else {
2571 _i27 = _iterator25.next();
2572 if (_i27.done) break;
2573 _ref24 = _i27.value;
2574 }
2575
2576 var option = _ref24;
2577
2578 if (option.selected) {
2579 formData.append(inputName, option.value);
2580 }
2581 }
2582 } else if (!inputType || inputType !== "checkbox" && inputType !== "radio" || input.checked) {
2583 formData.append(inputName, input.value);
2584 }
2585 }
2586 }
2587 }
2588
2589 // Invoked when there is new progress information about given files.
2590 // If e is not provided, it is assumed that the upload is finished.
2591
2592 }, {
2593 key: "_updateFilesUploadProgress",
2594 value: function _updateFilesUploadProgress(files, xhr, e) {
2595 var progress = void 0;
2596 if (typeof e !== 'undefined') {
2597 progress = 100 * e.loaded / e.total;
2598
2599 if (files[0].upload.chunked) {
2600 var file = files[0];
2601 // Since this is a chunked upload, we need to update the appropriate chunk progress.
2602 var chunk = this._getChunk(file, xhr);
2603 chunk.progress = progress;
2604 chunk.total = e.total;
2605 chunk.bytesSent = e.loaded;
2606 var fileProgress = 0,
2607 fileTotal = void 0,
2608 fileBytesSent = void 0;
2609 file.upload.progress = 0;
2610 file.upload.total = 0;
2611 file.upload.bytesSent = 0;
2612 for (var i = 0; i < file.upload.totalChunkCount; i++) {
2613 if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].progress !== undefined) {
2614 file.upload.progress += file.upload.chunks[i].progress;
2615 file.upload.total += file.upload.chunks[i].total;
2616 file.upload.bytesSent += file.upload.chunks[i].bytesSent;
2617 }
2618 }
2619 file.upload.progress = file.upload.progress / file.upload.totalChunkCount;
2620 } else {
2621 for (var _iterator26 = files, _isArray26 = true, _i28 = 0, _iterator26 = _isArray26 ? _iterator26 : _iterator26[Symbol.iterator]();;) {
2622 var _ref25;
2623
2624 if (_isArray26) {
2625 if (_i28 >= _iterator26.length) break;
2626 _ref25 = _iterator26[_i28++];
2627 } else {
2628 _i28 = _iterator26.next();
2629 if (_i28.done) break;
2630 _ref25 = _i28.value;
2631 }
2632
2633 var _file2 = _ref25;
2634
2635 _file2.upload.progress = progress;
2636 _file2.upload.total = e.total;
2637 _file2.upload.bytesSent = e.loaded;
2638 }
2639 }
2640 for (var _iterator27 = files, _isArray27 = true, _i29 = 0, _iterator27 = _isArray27 ? _iterator27 : _iterator27[Symbol.iterator]();;) {
2641 var _ref26;
2642
2643 if (_isArray27) {
2644 if (_i29 >= _iterator27.length) break;
2645 _ref26 = _iterator27[_i29++];
2646 } else {
2647 _i29 = _iterator27.next();
2648 if (_i29.done) break;
2649 _ref26 = _i29.value;
2650 }
2651
2652 var _file3 = _ref26;
2653
2654 this.emit("uploadprogress", _file3, _file3.upload.progress, _file3.upload.bytesSent);
2655 }
2656 } else {
2657 // Called when the file finished uploading
2658
2659 var allFilesFinished = true;
2660
2661 progress = 100;
2662
2663 for (var _iterator28 = files, _isArray28 = true, _i30 = 0, _iterator28 = _isArray28 ? _iterator28 : _iterator28[Symbol.iterator]();;) {
2664 var _ref27;
2665
2666 if (_isArray28) {
2667 if (_i30 >= _iterator28.length) break;
2668 _ref27 = _iterator28[_i30++];
2669 } else {
2670 _i30 = _iterator28.next();
2671 if (_i30.done) break;
2672 _ref27 = _i30.value;
2673 }
2674
2675 var _file4 = _ref27;
2676
2677 if (_file4.upload.progress !== 100 || _file4.upload.bytesSent !== _file4.upload.total) {
2678 allFilesFinished = false;
2679 }
2680 _file4.upload.progress = progress;
2681 _file4.upload.bytesSent = _file4.upload.total;
2682 }
2683
2684 // Nothing to do, all files already at 100%
2685 if (allFilesFinished) {
2686 return;
2687 }
2688
2689 for (var _iterator29 = files, _isArray29 = true, _i31 = 0, _iterator29 = _isArray29 ? _iterator29 : _iterator29[Symbol.iterator]();;) {
2690 var _ref28;
2691
2692 if (_isArray29) {
2693 if (_i31 >= _iterator29.length) break;
2694 _ref28 = _iterator29[_i31++];
2695 } else {
2696 _i31 = _iterator29.next();
2697 if (_i31.done) break;
2698 _ref28 = _i31.value;
2699 }
2700
2701 var _file5 = _ref28;
2702
2703 this.emit("uploadprogress", _file5, progress, _file5.upload.bytesSent);
2704 }
2705 }
2706 }
2707 }, {
2708 key: "_finishedUploading",
2709 value: function _finishedUploading(files, xhr, e) {
2710 var response = void 0;
2711
2712 if (files[0].status === Dropzone.CANCELED) {
2713 return;
2714 }
2715
2716 if (xhr.readyState !== 4) {
2717 return;
2718 }
2719
2720 if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') {
2721 response = xhr.responseText;
2722
2723 if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
2724 try {
2725 response = JSON.parse(response);
2726 } catch (error) {
2727 e = error;
2728 response = "Invalid JSON response from server.";
2729 }
2730 }
2731 }
2732
2733 this._updateFilesUploadProgress(files);
2734
2735 if (!(200 <= xhr.status && xhr.status < 300)) {
2736 this._handleUploadError(files, xhr, response);
2737 } else {
2738 if (files[0].upload.chunked) {
2739 files[0].upload.finishedChunkUpload(this._getChunk(files[0], xhr));
2740 } else {
2741 this._finished(files, response, e);
2742 }
2743 }
2744 }
2745 }, {
2746 key: "_handleUploadError",
2747 value: function _handleUploadError(files, xhr, response) {
2748 if (files[0].status === Dropzone.CANCELED) {
2749 return;
2750 }
2751
2752 if (files[0].upload.chunked && this.options.retryChunks) {
2753 var chunk = this._getChunk(files[0], xhr);
2754 if (chunk.retries++ < this.options.retryChunksLimit) {
2755 this._uploadData(files, [chunk.dataBlock]);
2756 return;
2757 } else {
2758 console.warn('Retried this chunk too often. Giving up.');
2759 }
2760 }
2761
2762 for (var _iterator30 = files, _isArray30 = true, _i32 = 0, _iterator30 = _isArray30 ? _iterator30 : _iterator30[Symbol.iterator]();;) {
2763 var _ref29;
2764
2765 if (_isArray30) {
2766 if (_i32 >= _iterator30.length) break;
2767 _ref29 = _iterator30[_i32++];
2768 } else {
2769 _i32 = _iterator30.next();
2770 if (_i32.done) break;
2771 _ref29 = _i32.value;
2772 }
2773
2774 var file = _ref29;
2775 if (response.data) {
2776 response = response.data
2777 }
2778 this._errorProcessing(files, response || this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr);
2779 }
2780 }
2781 }, {
2782 key: "submitRequest",
2783 value: function submitRequest(xhr, formData, files) {
2784 xhr.send(formData);
2785 }
2786
2787 // Called internally when processing is finished.
2788 // Individual callbacks have to be called in the appropriate sections.
2789
2790 }, {
2791 key: "_finished",
2792 value: function _finished(files, responseText, e) {
2793 for (var _iterator31 = files, _isArray31 = true, _i33 = 0, _iterator31 = _isArray31 ? _iterator31 : _iterator31[Symbol.iterator]();;) {
2794 var _ref30;
2795
2796 if (_isArray31) {
2797 if (_i33 >= _iterator31.length) break;
2798 _ref30 = _iterator31[_i33++];
2799 } else {
2800 _i33 = _iterator31.next();
2801 if (_i33.done) break;
2802 _ref30 = _i33.value;
2803 }
2804
2805 var file = _ref30;
2806
2807 file.status = Dropzone.SUCCESS;
2808 this.emit("success", file, responseText, e);
2809 this.emit("complete", file);
2810 }
2811 if (this.options.uploadMultiple) {
2812 this.emit("successmultiple", files, responseText, e);
2813 this.emit("completemultiple", files);
2814 }
2815
2816 if (this.options.autoProcessQueue) {
2817 return this.processQueue();
2818 }
2819 }
2820
2821 // Called internally when processing is finished.
2822 // Individual callbacks have to be called in the appropriate sections.
2823
2824 }, {
2825 key: "_errorProcessing",
2826 value: function _errorProcessing(files, message, xhr) {
2827 for (var _iterator32 = files, _isArray32 = true, _i34 = 0, _iterator32 = _isArray32 ? _iterator32 : _iterator32[Symbol.iterator]();;) {
2828 var _ref31;
2829
2830 if (_isArray32) {
2831 if (_i34 >= _iterator32.length) break;
2832 _ref31 = _iterator32[_i34++];
2833 } else {
2834 _i34 = _iterator32.next();
2835 if (_i34.done) break;
2836 _ref31 = _i34.value;
2837 }
2838
2839 var file = _ref31;
2840
2841 file.status = Dropzone.ERROR;
2842 this.emit("error", file, message, xhr);
2843 this.emit("complete", file);
2844 }
2845 if (this.options.uploadMultiple) {
2846 this.emit("errormultiple", files, message, xhr);
2847 this.emit("completemultiple", files);
2848 }
2849
2850 if (this.options.autoProcessQueue) {
2851 return this.processQueue();
2852 }
2853 }
2854 }], [{
2855 key: "uuidv4",
2856 value: function uuidv4() {
2857 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
2858 var r = Math.random() * 16 | 0,
2859 v = c === 'x' ? r : r & 0x3 | 0x8;
2860 return v.toString(16);
2861 });
2862 }
2863 }]);
2864
2865 return Dropzone;
2866 }(Emitter);
2867
2868 Dropzone.initClass();
2869
2870 Dropzone.version = "5.5.0";
2871
2872 // This is a map of options for your different dropzones. Add configurations
2873 // to this object for your different dropzone elemens.
2874 //
2875 // Example:
2876 //
2877 // Dropzone.options.myDropzoneElementId = { maxFilesize: 1 };
2878 //
2879 // To disable autoDiscover for a specific element, you can set `false` as an option:
2880 //
2881 // Dropzone.options.myDisabledElementId = false;
2882 //
2883 // And in html:
2884 //
2885 // <form action="/upload" id="my-dropzone-element-id" class="dropzone"></form>
2886 Dropzone.options = {};
2887
2888 // Returns the options for an element or undefined if none available.
2889 Dropzone.optionsForElement = function (element) {
2890 // Get the `Dropzone.options.elementId` for this element if it exists
2891 if (element.getAttribute("id")) {
2892 return Dropzone.options[camelize(element.getAttribute("id"))];
2893 } else {
2894 return undefined;
2895 }
2896 };
2897
2898 // Holds a list of all dropzone instances
2899 Dropzone.instances = [];
2900
2901 // Returns the dropzone for given element if any
2902 Dropzone.forElement = function (element) {
2903 if (typeof element === "string") {
2904 element = document.querySelector(element);
2905 }
2906 if ((element != null ? element.dropzone : undefined) == null) {
2907 throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
2908 }
2909 return element.dropzone;
2910 };
2911
2912 // Set to false if you don't want Dropzone to automatically find and attach to .dropzone elements.
2913 Dropzone.autoDiscover = true;
2914
2915 // Looks for all .dropzone elements and creates a dropzone for them
2916 Dropzone.discover = function () {
2917 var dropzones = void 0;
2918 if (document.querySelectorAll) {
2919 dropzones = document.querySelectorAll(".dropzone");
2920 } else {
2921 dropzones = [];
2922 // IE :(
2923 var checkElements = function checkElements(elements) {
2924 return function () {
2925 var result = [];
2926 for (var _iterator33 = elements, _isArray33 = true, _i35 = 0, _iterator33 = _isArray33 ? _iterator33 : _iterator33[Symbol.iterator]();;) {
2927 var _ref32;
2928
2929 if (_isArray33) {
2930 if (_i35 >= _iterator33.length) break;
2931 _ref32 = _iterator33[_i35++];
2932 } else {
2933 _i35 = _iterator33.next();
2934 if (_i35.done) break;
2935 _ref32 = _i35.value;
2936 }
2937
2938 var el = _ref32;
2939
2940 if (/(^| )dropzone($| )/.test(el.className)) {
2941 result.push(dropzones.push(el));
2942 } else {
2943 result.push(undefined);
2944 }
2945 }
2946 return result;
2947 }();
2948 };
2949 checkElements(document.getElementsByTagName("div"));
2950 checkElements(document.getElementsByTagName("form"));
2951 }
2952
2953 return function () {
2954 var result = [];
2955 for (var _iterator34 = dropzones, _isArray34 = true, _i36 = 0, _iterator34 = _isArray34 ? _iterator34 : _iterator34[Symbol.iterator]();;) {
2956 var _ref33;
2957
2958 if (_isArray34) {
2959 if (_i36 >= _iterator34.length) break;
2960 _ref33 = _iterator34[_i36++];
2961 } else {
2962 _i36 = _iterator34.next();
2963 if (_i36.done) break;
2964 _ref33 = _i36.value;
2965 }
2966
2967 var dropzone = _ref33;
2968
2969 // Create a dropzone unless auto discover has been disabled for specific element
2970 if (Dropzone.optionsForElement(dropzone) !== false) {
2971 result.push(new Dropzone(dropzone));
2972 } else {
2973 result.push(undefined);
2974 }
2975 }
2976 return result;
2977 }();
2978 };
2979
2980 // Since the whole Drag'n'Drop API is pretty new, some browsers implement it,
2981 // but not correctly.
2982 // So I created a blacklist of userAgents. Yes, yes. Browser sniffing, I know.
2983 // But what to do when browsers *theoretically* support an API, but crash
2984 // when using it.
2985 //
2986 // This is a list of regular expressions tested against navigator.userAgent
2987 //
2988 // ** It should only be used on browser that *do* support the API, but
2989 // incorrectly **
2990 //
2991 Dropzone.blacklistedBrowsers = [
2992 // The mac os and windows phone version of opera 12 seems to have a problem with the File drag'n'drop API.
2993 /opera.*(Macintosh|Windows Phone).*version\/12/i];
2994
2995 // Checks if the browser is supported
2996 Dropzone.isBrowserSupported = function () {
2997 var capableBrowser = true;
2998
2999 if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
3000 if (!("classList" in document.createElement("a"))) {
3001 capableBrowser = false;
3002 } else {
3003 // The browser supports the API, but may be blacklisted.
3004 for (var _iterator35 = Dropzone.blacklistedBrowsers, _isArray35 = true, _i37 = 0, _iterator35 = _isArray35 ? _iterator35 : _iterator35[Symbol.iterator]();;) {
3005 var _ref34;
3006
3007 if (_isArray35) {
3008 if (_i37 >= _iterator35.length) break;
3009 _ref34 = _iterator35[_i37++];
3010 } else {
3011 _i37 = _iterator35.next();
3012 if (_i37.done) break;
3013 _ref34 = _i37.value;
3014 }
3015
3016 var regex = _ref34;
3017
3018 if (regex.test(navigator.userAgent)) {
3019 capableBrowser = false;
3020 continue;
3021 }
3022 }
3023 }
3024 } else {
3025 capableBrowser = false;
3026 }
3027
3028 return capableBrowser;
3029 };
3030
3031 Dropzone.dataURItoBlob = function (dataURI) {
3032 // convert base64 to raw binary data held in a string
3033 // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
3034 var byteString = atob(dataURI.split(',')[1]);
3035
3036 // separate out the mime component
3037 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
3038
3039 // write the bytes of the string to an ArrayBuffer
3040 var ab = new ArrayBuffer(byteString.length);
3041 var ia = new Uint8Array(ab);
3042 for (var i = 0, end = byteString.length, asc = 0 <= end; asc ? i <= end : i >= end; asc ? i++ : i--) {
3043 ia[i] = byteString.charCodeAt(i);
3044 }
3045
3046 // write the ArrayBuffer to a blob
3047 return new Blob([ab], { type: mimeString });
3048 };
3049
3050 // Returns an array without the rejected item
3051 var without = function without(list, rejectedItem) {
3052 return list.filter(function (item) {
3053 return item !== rejectedItem;
3054 }).map(function (item) {
3055 return item;
3056 });
3057 };
3058
3059 // abc-def_ghi -> abcDefGhi
3060 var camelize = function camelize(str) {
3061 return str.replace(/[\-_](\w)/g, function (match) {
3062 return match.charAt(1).toUpperCase();
3063 });
3064 };
3065
3066 // Creates an element from string
3067 Dropzone.createElement = function (string) {
3068 var div = document.createElement("div");
3069 div.innerHTML = string;
3070 return div.childNodes[0];
3071 };
3072
3073 // Tests if given element is inside (or simply is) the container
3074 Dropzone.elementInside = function (element, container) {
3075 if (element === container) {
3076 return true;
3077 } // Coffeescript doesn't support do/while loops
3078 while (element = element.parentNode) {
3079 if (element === container) {
3080 return true;
3081 }
3082 }
3083 return false;
3084 };
3085
3086 Dropzone.getElement = function (el, name) {
3087 var element = void 0;
3088 if (typeof el === "string") {
3089 element = document.querySelector(el);
3090 } else if (el.nodeType != null) {
3091 element = el;
3092 }
3093 if (element == null) {
3094 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
3095 }
3096 return element;
3097 };
3098
3099 Dropzone.getElements = function (els, name) {
3100 var el = void 0,
3101 elements = void 0;
3102 if (els instanceof Array) {
3103 elements = [];
3104 try {
3105 for (var _iterator36 = els, _isArray36 = true, _i38 = 0, _iterator36 = _isArray36 ? _iterator36 : _iterator36[Symbol.iterator]();;) {
3106 if (_isArray36) {
3107 if (_i38 >= _iterator36.length) break;
3108 el = _iterator36[_i38++];
3109 } else {
3110 _i38 = _iterator36.next();
3111 if (_i38.done) break;
3112 el = _i38.value;
3113 }
3114
3115 elements.push(this.getElement(el, name));
3116 }
3117 } catch (e) {
3118 elements = null;
3119 }
3120 } else if (typeof els === "string") {
3121 elements = [];
3122 for (var _iterator37 = document.querySelectorAll(els), _isArray37 = true, _i39 = 0, _iterator37 = _isArray37 ? _iterator37 : _iterator37[Symbol.iterator]();;) {
3123 if (_isArray37) {
3124 if (_i39 >= _iterator37.length) break;
3125 el = _iterator37[_i39++];
3126 } else {
3127 _i39 = _iterator37.next();
3128 if (_i39.done) break;
3129 el = _i39.value;
3130 }
3131
3132 elements.push(el);
3133 }
3134 } else if (els.nodeType != null) {
3135 elements = [els];
3136 }
3137
3138 if (elements == null || !elements.length) {
3139 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
3140 }
3141
3142 return elements;
3143 };
3144
3145 // Asks the user the question and calls accepted or rejected accordingly
3146 //
3147 // The default implementation just uses `window.confirm` and then calls the
3148 // appropriate callback.
3149 Dropzone.confirm = function (question, accepted, rejected) {
3150 if (window.confirm(question)) {
3151 return accepted();
3152 } else if (rejected != null) {
3153 return rejected();
3154 }
3155 };
3156
3157 // Validates the mime type like this:
3158 //
3159 // https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept
3160 Dropzone.isValidFile = function (file, acceptedFiles) {
3161 if (!acceptedFiles) {
3162 return true;
3163 } // If there are no accepted mime types, it's OK
3164 acceptedFiles = acceptedFiles.split(",");
3165
3166 var mimeType = file.type;
3167 var baseMimeType = mimeType.replace(/\/.*$/, "");
3168
3169 for (var _iterator38 = acceptedFiles, _isArray38 = true, _i40 = 0, _iterator38 = _isArray38 ? _iterator38 : _iterator38[Symbol.iterator]();;) {
3170 var _ref35;
3171
3172 if (_isArray38) {
3173 if (_i40 >= _iterator38.length) break;
3174 _ref35 = _iterator38[_i40++];
3175 } else {
3176 _i40 = _iterator38.next();
3177 if (_i40.done) break;
3178 _ref35 = _i40.value;
3179 }
3180
3181 var validType = _ref35;
3182
3183 validType = validType.trim();
3184 if (validType.charAt(0) === ".") {
3185 if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
3186 return true;
3187 }
3188 } else if (/\/\*$/.test(validType)) {
3189 // This is something like a image/* mime type
3190 if (baseMimeType === validType.replace(/\/.*$/, "")) {
3191 return true;
3192 }
3193 } else {
3194 if (mimeType === validType) {
3195 return true;
3196 }
3197 }
3198 }
3199
3200 return false;
3201 };
3202
3203 // Augment jQuery
3204 if (typeof jQuery !== 'undefined' && jQuery !== null) {
3205 jQuery.fn.dropzone = function (options) {
3206 return this.each(function () {
3207 return new Dropzone(this, options);
3208 });
3209 };
3210 }
3211
3212 if (typeof module !== 'undefined' && module !== null) {
3213 module.exports = Dropzone;
3214 } else {
3215 window.Dropzone = Dropzone;
3216 }
3217
3218 // Dropzone file status codes
3219 Dropzone.ADDED = "added";
3220
3221 Dropzone.QUEUED = "queued";
3222 // For backwards compatibility. Now, if a file is accepted, it's either queued
3223 // or uploading.
3224 Dropzone.ACCEPTED = Dropzone.QUEUED;
3225
3226 Dropzone.UPLOADING = "uploading";
3227 Dropzone.PROCESSING = Dropzone.UPLOADING; // alias
3228
3229 Dropzone.CANCELED = "canceled";
3230 Dropzone.ERROR = "error";
3231 Dropzone.SUCCESS = "success";
3232
3233 /*
3234
3235 Bugfix for iOS 6 and 7
3236 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
3237 based on the work of https://github.com/stomita/ios-imagefile-megapixel
3238
3239 */
3240
3241 // Detecting vertical squash in loaded image.
3242 // Fixes a bug which squash image vertically while drawing into canvas for some images.
3243 // This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel
3244 var detectVerticalSquash = function detectVerticalSquash(img) {
3245 var iw = img.naturalWidth;
3246 var ih = img.naturalHeight;
3247 var canvas = document.createElement("canvas");
3248 canvas.width = 1;
3249 canvas.height = ih;
3250 var ctx = canvas.getContext("2d");
3251 ctx.drawImage(img, 0, 0);
3252
3253 var _ctx$getImageData = ctx.getImageData(1, 0, 1, ih),
3254 data = _ctx$getImageData.data;
3255
3256 // search image edge pixel position in case it is squashed vertically.
3257
3258
3259 var sy = 0;
3260 var ey = ih;
3261 var py = ih;
3262 while (py > sy) {
3263 var alpha = data[(py - 1) * 4 + 3];
3264
3265 if (alpha === 0) {
3266 ey = py;
3267 } else {
3268 sy = py;
3269 }
3270
3271 py = ey + sy >> 1;
3272 }
3273 var ratio = py / ih;
3274
3275 if (ratio === 0) {
3276 return 1;
3277 } else {
3278 return ratio;
3279 }
3280 };
3281
3282 // A replacement for context.drawImage
3283 // (args are for source and destination).
3284 var drawImageIOSFix = function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
3285 var vertSquashRatio = detectVerticalSquash(img);
3286 return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
3287 };
3288
3289 // Based on MinifyJpeg
3290 // Source: http://www.perry.cz/files/ExifRestorer.js
3291 // http://elicon.blog57.fc2.com/blog-entry-206.html
3292
3293 var ExifRestore = function () {
3294 function ExifRestore() {
3295 _classCallCheck(this, ExifRestore);
3296 }
3297
3298 _createClass(ExifRestore, null, [{
3299 key: "initClass",
3300 value: function initClass() {
3301 this.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
3302 }
3303 }, {
3304 key: "encode64",
3305 value: function encode64(input) {
3306 var output = '';
3307 var chr1 = undefined;
3308 var chr2 = undefined;
3309 var chr3 = '';
3310 var enc1 = undefined;
3311 var enc2 = undefined;
3312 var enc3 = undefined;
3313 var enc4 = '';
3314 var i = 0;
3315 while (true) {
3316 chr1 = input[i++];
3317 chr2 = input[i++];
3318 chr3 = input[i++];
3319 enc1 = chr1 >> 2;
3320 enc2 = (chr1 & 3) << 4 | chr2 >> 4;
3321 enc3 = (chr2 & 15) << 2 | chr3 >> 6;
3322 enc4 = chr3 & 63;
3323 if (isNaN(chr2)) {
3324 enc3 = enc4 = 64;
3325 } else if (isNaN(chr3)) {
3326 enc4 = 64;
3327 }
3328 output = output + this.KEY_STR.charAt(enc1) + this.KEY_STR.charAt(enc2) + this.KEY_STR.charAt(enc3) + this.KEY_STR.charAt(enc4);
3329 chr1 = chr2 = chr3 = '';
3330 enc1 = enc2 = enc3 = enc4 = '';
3331 if (!(i < input.length)) {
3332 break;
3333 }
3334 }
3335 return output;
3336 }
3337 }, {
3338 key: "restore",
3339 value: function restore(origFileBase64, resizedFileBase64) {
3340 if (!origFileBase64.match('data:image/jpeg;base64,')) {
3341 return resizedFileBase64;
3342 }
3343 var rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', ''));
3344 var segments = this.slice2Segments(rawImage);
3345 var image = this.exifManipulation(resizedFileBase64, segments);
3346 return "data:image/jpeg;base64," + this.encode64(image);
3347 }
3348 }, {
3349 key: "exifManipulation",
3350 value: function exifManipulation(resizedFileBase64, segments) {
3351 var exifArray = this.getExifArray(segments);
3352 var newImageArray = this.insertExif(resizedFileBase64, exifArray);
3353 var aBuffer = new Uint8Array(newImageArray);
3354 return aBuffer;
3355 }
3356 }, {
3357 key: "getExifArray",
3358 value: function getExifArray(segments) {
3359 var seg = undefined;
3360 var x = 0;
3361 while (x < segments.length) {
3362 seg = segments[x];
3363 if (seg[0] === 255 & seg[1] === 225) {
3364 return seg;
3365 }
3366 x++;
3367 }
3368 return [];
3369 }
3370 }, {
3371 key: "insertExif",
3372 value: function insertExif(resizedFileBase64, exifArray) {
3373 var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', '');
3374 var buf = this.decode64(imageData);
3375 var separatePoint = buf.indexOf(255, 3);
3376 var mae = buf.slice(0, separatePoint);
3377 var ato = buf.slice(separatePoint);
3378 var array = mae;
3379 array = array.concat(exifArray);
3380 array = array.concat(ato);
3381 return array;
3382 }
3383 }, {
3384 key: "slice2Segments",
3385 value: function slice2Segments(rawImageArray) {
3386 var head = 0;
3387 var segments = [];
3388 while (true) {
3389 var length;
3390 if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
3391 break;
3392 }
3393 if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
3394 head += 2;
3395 } else {
3396 length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3];
3397 var endPoint = head + length + 2;
3398 var seg = rawImageArray.slice(head, endPoint);
3399 segments.push(seg);
3400 head = endPoint;
3401 }
3402 if (head > rawImageArray.length) {
3403 break;
3404 }
3405 }
3406 return segments;
3407 }
3408 }, {
3409 key: "decode64",
3410 value: function decode64(input) {
3411 var output = '';
3412 var chr1 = undefined;
3413 var chr2 = undefined;
3414 var chr3 = '';
3415 var enc1 = undefined;
3416 var enc2 = undefined;
3417 var enc3 = undefined;
3418 var enc4 = '';
3419 var i = 0;
3420 var buf = [];
3421 // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
3422 var base64test = /[^A-Za-z0-9\+\/\=]/g;
3423 if (base64test.exec(input)) {
3424 console.warn('There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, \'+\', \'/\',and \'=\'\nExpect errors in decoding.');
3425 }
3426 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
3427 while (true) {
3428 enc1 = this.KEY_STR.indexOf(input.charAt(i++));
3429 enc2 = this.KEY_STR.indexOf(input.charAt(i++));
3430 enc3 = this.KEY_STR.indexOf(input.charAt(i++));
3431 enc4 = this.KEY_STR.indexOf(input.charAt(i++));
3432 chr1 = enc1 << 2 | enc2 >> 4;
3433 chr2 = (enc2 & 15) << 4 | enc3 >> 2;
3434 chr3 = (enc3 & 3) << 6 | enc4;
3435 buf.push(chr1);
3436 if (enc3 !== 64) {
3437 buf.push(chr2);
3438 }
3439 if (enc4 !== 64) {
3440 buf.push(chr3);
3441 }
3442 chr1 = chr2 = chr3 = '';
3443 enc1 = enc2 = enc3 = enc4 = '';
3444 if (!(i < input.length)) {
3445 break;
3446 }
3447 }
3448 return buf;
3449 }
3450 }]);
3451
3452 return ExifRestore;
3453 }();
3454
3455 ExifRestore.initClass();
3456
3457 /*
3458 * contentloaded.js
3459 *
3460 * Author: Diego Perini (diego.perini at gmail.com)
3461 * Summary: cross-browser wrapper for DOMContentLoaded
3462 * Updated: 20101020
3463 * License: MIT
3464 * Version: 1.2
3465 *
3466 * URL:
3467 * http://javascript.nwbox.com/ContentLoaded/
3468 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
3469 */
3470
3471 // @win window reference
3472 // @fn function reference
3473 var contentLoaded = function contentLoaded(win, fn) {
3474 var done = false;
3475 var top = true;
3476 var doc = win.document;
3477 var root = doc.documentElement;
3478 var add = doc.addEventListener ? "addEventListener" : "attachEvent";
3479 var rem = doc.addEventListener ? "removeEventListener" : "detachEvent";
3480 var pre = doc.addEventListener ? "" : "on";
3481 var init = function init(e) {
3482 if (e.type === "readystatechange" && doc.readyState !== "complete") {
3483 return;
3484 }
3485 (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
3486 if (!done && (done = true)) {
3487 return fn.call(win, e.type || e);
3488 }
3489 };
3490
3491 var poll = function poll() {
3492 try {
3493 root.doScroll("left");
3494 } catch (e) {
3495 setTimeout(poll, 50);
3496 return;
3497 }
3498 return init("poll");
3499 };
3500
3501 if (doc.readyState !== "complete") {
3502 if (doc.createEventObject && root.doScroll) {
3503 try {
3504 top = !win.frameElement;
3505 } catch (error) {}
3506 if (top) {
3507 poll();
3508 }
3509 }
3510 doc[add](pre + "DOMContentLoaded", init, false);
3511 doc[add](pre + "readystatechange", init, false);
3512 return win[add](pre + "load", init, false);
3513 }
3514 };
3515
3516 // As a single function to be able to write tests.
3517 Dropzone._autoDiscoverFunction = function () {
3518 if (Dropzone.autoDiscover) {
3519 return Dropzone.discover();
3520 }
3521 };
3522 contentLoaded(window, Dropzone._autoDiscoverFunction);
3523
3524 function __guard__(value, transform) {
3525 return typeof value !== 'undefined' && value !== null ? transform(value) : undefined;
3526 }
3527 function __guardMethod__(obj, methodName, transform) {
3528 if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') {
3529 return transform(obj, methodName);
3530 } else {
3531 return undefined;
3532 }
3533 }
3534