Open Source Web Application Framework for ASP.NET Core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

42133 lines
1.3 MiB

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Uppy = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// Adapted from https://github.com/Flet/prettier-bytes/
// Changing 1000 bytes to 1024, so we can keep uppercase KB vs kB
// ISC License (c) Dan Flettre https://github.com/Flet/prettier-bytes/blob/master/LICENSE
module.exports = function prettierBytes (num) {
if (typeof num !== 'number' || isNaN(num)) {
throw new TypeError('Expected a number, got ' + typeof num)
}
var neg = num < 0
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
if (neg) {
num = -num
}
if (num < 1) {
return (neg ? '-' : '') + num + ' B'
}
var exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1)
num = Number(num / Math.pow(1024, exponent))
var unit = units[exponent]
if (num >= 10 || num % 1 === 0) {
// Do not show decimals when the number is two-digit, or if the number has no
// decimal component.
return (neg ? '-' : '') + num.toFixed(0) + ' ' + unit
} else {
return (neg ? '-' : '') + num.toFixed(1) + ' ' + unit
}
}
},{}],2:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get(target, property, receiver) {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get;
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(receiver);
}
return desc.value;
};
}
return _get(target, property, receiver || target);
}
var Emitter = /*#__PURE__*/function () {
function Emitter() {
_classCallCheck(this, Emitter);
Object.defineProperty(this, 'listeners', {
value: {},
writable: true,
configurable: true
});
}
_createClass(Emitter, [{
key: "addEventListener",
value: function addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({
callback: callback,
options: options
});
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
var stackToCall = stack.slice();
for (var i = 0, l = stackToCall.length; i < l; i++) {
var listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(function () {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}]);
return Emitter;
}();
var AbortSignal = /*#__PURE__*/function (_Emitter) {
_inherits(AbortSignal, _Emitter);
var _super = _createSuper(AbortSignal);
function AbortSignal() {
var _this;
_classCallCheck(this, AbortSignal);
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!_this.listeners) {
Emitter.call(_assertThisInitialized(_this));
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(_assertThisInitialized(_this), 'aborted', {
value: false,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'onabort', {
value: null,
writable: true,
configurable: true
});
return _this;
}
_createClass(AbortSignal, [{
key: "toString",
value: function toString() {
return '[object AbortSignal]';
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event);
}
}]);
return AbortSignal;
}(Emitter);
var AbortController = /*#__PURE__*/function () {
function AbortController() {
_classCallCheck(this, AbortController);
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', {
value: new AbortSignal(),
writable: true,
configurable: true
});
}
_createClass(AbortController, [{
key: "abort",
value: function abort() {
var event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false
};
}
}
this.signal.dispatchEvent(event);
}
}, {
key: "toString",
value: function toString() {
return '[object AbortController]';
}
}]);
return AbortController;
}();
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}
exports.AbortController = AbortController;
exports.AbortSignal = AbortSignal;
exports.default = AbortController;
},{}],3:[function(require,module,exports){
module.exports = after
function after(count, callback, err_cb) {
var bail = false
err_cb = err_cb || noop
proxy.count = count
return (count === 0) ? callback() : proxy
function proxy(err, result) {
if (proxy.count <= 0) {
throw new Error('after called too many times')
}
--proxy.count
// after first error, rest are passed to err_cb
if (err) {
bail = true
callback(err)
// future error callbacks will go to error handler
callback = err_cb
} else if (proxy.count === 0 && !bail) {
callback(null, result)
}
}
}
function noop() {}
},{}],4:[function(require,module,exports){
/**
* An abstraction for slicing an arraybuffer even when
* ArrayBuffer.prototype.slice is not supported
*
* @api public
*/
module.exports = function(arraybuffer, start, end) {
var bytes = arraybuffer.byteLength;
start = start || 0;
end = end || bytes;
if (arraybuffer.slice) { return arraybuffer.slice(start, end); }
if (start < 0) { start += bytes; }
if (end < 0) { end += bytes; }
if (end > bytes) { end = bytes; }
if (start >= bytes || start >= end || bytes === 0) {
return new ArrayBuffer(0);
}
var abv = new Uint8Array(arraybuffer);
var result = new Uint8Array(end - start);
for (var i = start, ii = 0; i < end; i++, ii++) {
result[ii] = abv[i];
}
return result.buffer;
};
},{}],5:[function(require,module,exports){
/**
* Expose `Backoff`.
*/
module.exports = Backoff;
/**
* Initialize backoff timer with `opts`.
*
* - `min` initial timeout in milliseconds [100]
* - `max` max timeout [10000]
* - `jitter` [0]
* - `factor` [2]
*
* @param {Object} opts
* @api public
*/
function Backoff(opts) {
opts = opts || {};
this.ms = opts.min || 100;
this.max = opts.max || 10000;
this.factor = opts.factor || 2;
this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
this.attempts = 0;
}
/**
* Return the backoff duration.
*
* @return {Number}
* @api public
*/
Backoff.prototype.duration = function(){
var ms = this.ms * Math.pow(this.factor, this.attempts++);
if (this.jitter) {
var rand = Math.random();
var deviation = Math.floor(rand * this.jitter * ms);
ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
}
return Math.min(ms, this.max) | 0;
};
/**
* Reset the number of attempts.
*
* @api public
*/
Backoff.prototype.reset = function(){
this.attempts = 0;
};
/**
* Set the minimum duration
*
* @api public
*/
Backoff.prototype.setMin = function(min){
this.ms = min;
};
/**
* Set the maximum duration
*
* @api public
*/
Backoff.prototype.setMax = function(max){
this.max = max;
};
/**
* Set the jitter
*
* @api public
*/
Backoff.prototype.setJitter = function(jitter){
this.jitter = jitter;
};
},{}],6:[function(require,module,exports){
/*
* base64-arraybuffer
* https://github.com/niklasvh/base64-arraybuffer
*
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*/
(function(){
"use strict";
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Use a lookup table to find the index.
var lookup = new Uint8Array(256);
for (var i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
exports.encode = function(arraybuffer) {
var bytes = new Uint8Array(arraybuffer),
i, len = bytes.length, base64 = "";
for (i = 0; i < len; i+=3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64 += chars[bytes[i + 2] & 63];
}
if ((len % 3) === 2) {
base64 = base64.substring(0, base64.length - 1) + "=";
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2) + "==";
}
return base64;
};
exports.decode = function(base64) {
var bufferLength = base64.length * 0.75,
len = base64.length, i, p = 0,
encoded1, encoded2, encoded3, encoded4;
if (base64[base64.length - 1] === "=") {
bufferLength--;
if (base64[base64.length - 2] === "=") {
bufferLength--;
}
}
var arraybuffer = new ArrayBuffer(bufferLength),
bytes = new Uint8Array(arraybuffer);
for (i = 0; i < len; i+=4) {
encoded1 = lookup[base64.charCodeAt(i)];
encoded2 = lookup[base64.charCodeAt(i+1)];
encoded3 = lookup[base64.charCodeAt(i+2)];
encoded4 = lookup[base64.charCodeAt(i+3)];
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return arraybuffer;
};
})();
},{}],7:[function(require,module,exports){
'use strict'
exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
function getLens (b64) {
var len = b64.length
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=')
if (validLen === -1) validLen = len
var placeHoldersLen = validLen === len
? 0
: 4 - (validLen % 4)
return [validLen, placeHoldersLen]
}
// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function _byteLength (b64, validLen, placeHoldersLen) {
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function toByteArray (b64) {
var tmp
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
var curByte = 0
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0
? validLen - 4
: validLen
var i
for (i = 0; i < len; i += 4) {
tmp =
(revLookup[b64.charCodeAt(i)] << 18) |
(revLookup[b64.charCodeAt(i + 1)] << 12) |
(revLookup[b64.charCodeAt(i + 2)] << 6) |
revLookup[b64.charCodeAt(i + 3)]
arr[curByte++] = (tmp >> 16) & 0xFF
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 2) {
tmp =
(revLookup[b64.charCodeAt(i)] << 2) |
(revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 1) {
tmp =
(revLookup[b64.charCodeAt(i)] << 10) |
(revLookup[b64.charCodeAt(i + 1)] << 4) |
(revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] +
lookup[num >> 12 & 0x3F] +
lookup[num >> 6 & 0x3F] +
lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp =
((uint8[i] << 16) & 0xFF0000) +
((uint8[i + 1] << 8) & 0xFF00) +
(uint8[i + 2] & 0xFF)
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
parts.push(
lookup[tmp >> 2] +
lookup[(tmp << 4) & 0x3F] +
'=='
)
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
parts.push(
lookup[tmp >> 10] +
lookup[(tmp >> 4) & 0x3F] +
lookup[(tmp << 2) & 0x3F] +
'='
)
}
return parts.join('')
}
},{}],8:[function(require,module,exports){
/**
* Create a blob builder even when vendor prefixes exist
*/
var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder :
typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
false;
/**
* Check if Blob constructor is supported
*/
var blobSupported = (function() {
try {
var a = new Blob(['hi']);
return a.size === 2;
} catch(e) {
return false;
}
})();
/**
* Check if Blob constructor supports ArrayBufferViews
* Fails in Safari 6, so we need to map to ArrayBuffers there.
*/
var blobSupportsArrayBufferView = blobSupported && (function() {
try {
var b = new Blob([new Uint8Array([1,2])]);
return b.size === 2;
} catch(e) {
return false;
}
})();
/**
* Check if BlobBuilder is supported
*/
var blobBuilderSupported = BlobBuilder
&& BlobBuilder.prototype.append
&& BlobBuilder.prototype.getBlob;
/**
* Helper function that maps ArrayBufferViews to ArrayBuffers
* Used by BlobBuilder constructor and old browsers that didn't
* support it in the Blob constructor.
*/
function mapArrayBufferViews(ary) {
return ary.map(function(chunk) {
if (chunk.buffer instanceof ArrayBuffer) {
var buf = chunk.buffer;
// if this is a subarray, make a copy so we only
// include the subarray region from the underlying buffer
if (chunk.byteLength !== buf.byteLength) {
var copy = new Uint8Array(chunk.byteLength);
copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));
buf = copy.buffer;
}
return buf;
}
return chunk;
});
}
function BlobBuilderConstructor(ary, options) {
options = options || {};
var bb = new BlobBuilder();
mapArrayBufferViews(ary).forEach(function(part) {
bb.append(part);
});
return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
};
function BlobConstructor(ary, options) {
return new Blob(mapArrayBufferViews(ary), options || {});
};
if (typeof Blob !== 'undefined') {
BlobBuilderConstructor.prototype = Blob.prototype;
BlobConstructor.prototype = Blob.prototype;
}
module.exports = (function() {
if (blobSupported) {
return blobSupportsArrayBufferView ? Blob : BlobConstructor;
} else if (blobBuilderSupported) {
return BlobBuilderConstructor;
} else {
return undefined;
}
})();
},{}],9:[function(require,module,exports){
},{}],10:[function(require,module,exports){
(function (Buffer){(function (){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
var K_MAX_LENGTH = 0x7fffffff
exports.kMaxLength = K_MAX_LENGTH
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Print warning and recommend using `buffer` v4.x which has an Object
* implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* We report that the browser does not support typed arrays if the are not subclassable
* using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
* (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
* for __proto__ and has a buggy typed array implementation.
*/
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
typeof console.error === 'function') {
console.error(
'This browser lacks typed array (Uint8Array) support which is required by ' +
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
)
}
function typedArraySupport () {
// Can typed array instances can be augmented?
try {
var arr = new Uint8Array(1)
arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
return arr.foo() === 42
} catch (e) {
return false
}
}
Object.defineProperty(Buffer.prototype, 'parent', {
enumerable: true,
get: function () {
if (!Buffer.isBuffer(this)) return undefined
return this.buffer
}
})
Object.defineProperty(Buffer.prototype, 'offset', {
enumerable: true,
get: function () {
if (!Buffer.isBuffer(this)) return undefined
return this.byteOffset
}
})
function createBuffer (length) {
if (length > K_MAX_LENGTH) {
throw new RangeError('The value "' + length + '" is invalid for option "size"')
}
// Return an augmented `Uint8Array` instance
var buf = new Uint8Array(length)
buf.__proto__ = Buffer.prototype
return buf
}
/**
* The Buffer constructor returns instances of `Uint8Array` that have their
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
* returns a single octet.
*
* The `Uint8Array` prototype remains unmodified.
*/
function Buffer (arg, encodingOrOffset, length) {
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new TypeError(
'The "string" argument must be of type string. Received type number'
)
}
return allocUnsafe(arg)
}
return from(arg, encodingOrOffset, length)
}
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
Buffer[Symbol.species] === Buffer) {
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true,
enumerable: false,
writable: false
})
}
Buffer.poolSize = 8192 // not used by this implementation
function from (value, encodingOrOffset, length) {
if (typeof value === 'string') {
return fromString(value, encodingOrOffset)
}
if (ArrayBuffer.isView(value)) {
return fromArrayLike(value)
}
if (value == null) {
throw TypeError(
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
'or Array-like Object. Received type ' + (typeof value)
)
}
if (isInstance(value, ArrayBuffer) ||
(value && isInstance(value.buffer, ArrayBuffer))) {
return fromArrayBuffer(value, encodingOrOffset, length)
}
if (typeof value === 'number') {
throw new TypeError(
'The "value" argument must not be of type number. Received type number'
)
}
var valueOf = value.valueOf && value.valueOf()
if (valueOf != null && valueOf !== value) {
return Buffer.from(valueOf, encodingOrOffset, length)
}
var b = fromObject(value)
if (b) return b
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
typeof value[Symbol.toPrimitive] === 'function') {
return Buffer.from(
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
)
}
throw new TypeError(
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
'or Array-like Object. Received type ' + (typeof value)
)
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/
Buffer.from = function (value, encodingOrOffset, length) {
return from(value, encodingOrOffset, length)
}
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
// https://github.com/feross/buffer/pull/148
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
function assertSize (size) {
if (typeof size !== 'number') {
throw new TypeError('"size" argument must be of type number')
} else if (size < 0) {
throw new RangeError('The value "' + size + '" is invalid for option "size"')
}
}
function alloc (size, fill, encoding) {
assertSize(size)
if (size <= 0) {
return createBuffer(size)
}
if (fill !== undefined) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
return typeof encoding === 'string'
? createBuffer(size).fill(fill, encoding)
: createBuffer(size).fill(fill)
}
return createBuffer(size)
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/
Buffer.alloc = function (size, fill, encoding) {
return alloc(size, fill, encoding)
}
function allocUnsafe (size) {
assertSize(size)
return createBuffer(size < 0 ? 0 : checked(size) | 0)
}
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
* */
Buffer.allocUnsafe = function (size) {
return allocUnsafe(size)
}
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
*/
Buffer.allocUnsafeSlow = function (size) {
return allocUnsafe(size)
}
function fromString (string, encoding) {
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8'
}
if (!Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
var length = byteLength(string, encoding) | 0
var buf = createBuffer(length)
var actual = buf.write(string, encoding)
if (actual !== length) {
// Writing a hex string, for example, that contains invalid characters will
// cause everything after the first invalid character to be ignored. (e.g.
// 'abxxcd' will be treated as 'ab')
buf = buf.slice(0, actual)
}
return buf
}
function fromArrayLike (array) {
var length = array.length < 0 ? 0 : checked(array.length) | 0
var buf = createBuffer(length)
for (var i = 0; i < length; i += 1) {
buf[i] = array[i] & 255
}
return buf
}
function fromArrayBuffer (array, byteOffset, length) {
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('"offset" is outside of buffer bounds')
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('"length" is outside of buffer bounds')
}
var buf
if (byteOffset === undefined && length === undefined) {
buf = new Uint8Array(array)
} else if (length === undefined) {
buf = new Uint8Array(array, byteOffset)
} else {
buf = new Uint8Array(array, byteOffset, length)
}
// Return an augmented `Uint8Array` instance
buf.__proto__ = Buffer.prototype
return buf
}
function fromObject (obj) {
if (Buffer.isBuffer(obj)) {
var len = checked(obj.length) | 0
var buf = createBuffer(len)
if (buf.length === 0) {
return buf
}
obj.copy(buf, 0, 0, len)
return buf
}
if (obj.length !== undefined) {
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
return createBuffer(0)
}
return fromArrayLike(obj)
}
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
return fromArrayLike(obj.data)
}
}
function checked (length) {
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= K_MAX_LENGTH) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (length) {
if (+length != length) { // eslint-disable-line eqeqeq
length = 0
}
return Buffer.alloc(+length)
}
Buffer.isBuffer = function isBuffer (b) {
return b != null && b._isBuffer === true &&
b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
}
Buffer.compare = function compare (a, b) {
if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError(
'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
)
}
if (a === b) return 0
var x = a.length
var y = b.length
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
if (a[i] !== b[i]) {
x = a[i]
y = b[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'latin1':
case 'binary':
case 'base64':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!Array.isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
if (list.length === 0) {
return Buffer.alloc(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; ++i) {
length += list[i].length
}
}
var buffer = Buffer.allocUnsafe(length)
var pos = 0
for (i = 0; i < list.length; ++i) {
var buf = list[i]
if (isInstance(buf, Uint8Array)) {
buf = Buffer.from(buf)
}
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
buf.copy(buffer, pos)
pos += buf.length
}
return buffer
}
function byteLength (string, encoding) {
if (Buffer.isBuffer(string)) {
return string.length
}
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
return string.byteLength
}
if (typeof string !== 'string') {
throw new TypeError(
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
'Received type ' + typeof string
)
}
var len = string.length
var mustMatch = (arguments.length > 2 && arguments[2] === true)
if (!mustMatch && len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'latin1':
case 'binary':
return len
case 'utf8':
case 'utf-8':
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) {
return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
}
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0) {
start = 0
}
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length) {
return ''
}
if (end === undefined || end > this.length) {
end = this.length
}
if (end <= 0) {
return ''
}
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0
start >>>= 0
if (end <= start) {
return ''
}
if (!encoding) encoding = 'utf8'
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'latin1':
case 'binary':
return latin1Slice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
// reliably in a browserify context because there could be multiple different
// copies of the 'buffer' package in use. This method works even for Buffer
// instances that were created from another copy of the `buffer` package.
// See: https://github.com/feross/buffer/issues/154
Buffer.prototype._isBuffer = true
function swap (b, n, m) {
var i = b[n]
b[n] = b[m]
b[m] = i
}
Buffer.prototype.swap16 = function swap16 () {
var len = this.length
if (len % 2 !== 0) {
throw new RangeError('Buffer size must be a multiple of 16-bits')
}
for (var i = 0; i < len; i += 2) {
swap(this, i, i + 1)
}
return this
}
Buffer.prototype.swap32 = function swap32 () {
var len = this.length
if (len % 4 !== 0) {
throw new RangeError('Buffer size must be a multiple of 32-bits')
}
for (var i = 0; i < len; i += 4) {
swap(this, i, i + 3)
swap(this, i + 1, i + 2)
}
return this
}
Buffer.prototype.swap64 = function swap64 () {
var len = this.length
if (len % 8 !== 0) {
throw new RangeError('Buffer size must be a multiple of 64-bits')
}
for (var i = 0; i < len; i += 8) {
swap(this, i, i + 7)
swap(this, i + 1, i + 6)
swap(this, i + 2, i + 5)
swap(this, i + 3, i + 4)
}
return this
}
Buffer.prototype.toString = function toString () {
var length = this.length
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.toLocaleString = Buffer.prototype.toString
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
if (this.length > max) str += ' ... '
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
if (isInstance(target, Uint8Array)) {
target = Buffer.from(target, target.offset, target.byteLength)
}
if (!Buffer.isBuffer(target)) {
throw new TypeError(
'The "target" argument must be one of type Buffer or Uint8Array. ' +
'Received type ' + (typeof target)
)
}
if (start === undefined) {
start = 0
}
if (end === undefined) {
end = target ? target.length : 0
}
if (thisStart === undefined) {
thisStart = 0
}
if (thisEnd === undefined) {
thisEnd = this.length
}
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
throw new RangeError('out of range index')
}
if (thisStart >= thisEnd && start >= end) {
return 0
}
if (thisStart >= thisEnd) {
return -1
}
if (start >= end) {
return 1
}
start >>>= 0
end >>>= 0
thisStart >>>= 0
thisEnd >>>= 0
if (this === target) return 0
var x = thisEnd - thisStart
var y = end - start
var len = Math.min(x, y)
var thisCopy = this.slice(thisStart, thisEnd)
var targetCopy = target.slice(start, end)
for (var i = 0; i < len; ++i) {
if (thisCopy[i] !== targetCopy[i]) {
x = thisCopy[i]
y = targetCopy[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
// Empty buffer means no match
if (buffer.length === 0) return -1
// Normalize byteOffset
if (typeof byteOffset === 'string') {
encoding = byteOffset
byteOffset = 0
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000
}
byteOffset = +byteOffset // Coerce to Number.
if (numberIsNaN(byteOffset)) {
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
byteOffset = dir ? 0 : (buffer.length - 1)
}
// Normalize byteOffset: negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
if (byteOffset >= buffer.length) {
if (dir) return -1
else byteOffset = buffer.length - 1
} else if (byteOffset < 0) {
if (dir) byteOffset = 0
else return -1
}
// Normalize val
if (typeof val === 'string') {
val = Buffer.from(val, encoding)
}
// Finally, search either indexOf (if dir is true) or lastIndexOf
if (Buffer.isBuffer(val)) {
// Special case: looking for empty string/buffer always fails
if (val.length === 0) {
return -1
}
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
} else if (typeof val === 'number') {
val = val & 0xFF // Search for a byte value [0-255]
if (typeof Uint8Array.prototype.indexOf === 'function') {
if (dir) {
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
} else {
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
}
}
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
}
throw new TypeError('val must be string, number or Buffer')
}
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
var indexSize = 1
var arrLength = arr.length
var valLength = val.length
if (encoding !== undefined) {
encoding = String(encoding).toLowerCase()
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
encoding === 'utf16le' || encoding === 'utf-16le') {
if (arr.length < 2 || val.length < 2) {
return -1
}
indexSize = 2
arrLength /= 2
valLength /= 2
byteOffset /= 2
}
}
function read (buf, i) {
if (indexSize === 1) {
return buf[i]
} else {
return buf.readUInt16BE(i * indexSize)
}
}
var i
if (dir) {
var foundIndex = -1
for (i = byteOffset; i < arrLength; i++) {
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
} else {
if (foundIndex !== -1) i -= i - foundIndex
foundIndex = -1
}
}
} else {
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
for (i = byteOffset; i >= 0; i--) {
var found = true
for (var j = 0; j < valLength; j++) {
if (read(arr, i + j) !== read(val, j)) {
found = false
break
}
}
if (found) return i
}
}
return -1
}
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
}
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
var strLen = string.length
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; ++i) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (numberIsNaN(parsed)) return i
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function latin1Write (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset >>> 0
if (isFinite(length)) {
length = length >>> 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
} else {
throw new Error(
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
)
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'latin1':
case 'binary':
return latin1Write(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function latin1Slice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; ++i) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf = this.subarray(start, end)
// Return an augmented `Uint8Array` instance
newBuf.__proto__ = Buffer.prototype
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset >>> 0
byteLength = byteLength >>> 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset >>> 0
byteLength = byteLength >>> 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset >>> 0
byteLength = byteLength >>> 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset >>> 0
byteLength = byteLength >>> 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
if (offset + ext > buf.length) throw new RangeError('Index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset >>> 0
byteLength = byteLength >>> 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset >>> 0
byteLength = byteLength >>> 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
return offset + 2
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) {
var limit = Math.pow(2, (8 * byteLength) - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) {
var limit = Math.pow(2, (8 * byteLength) - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (offset + ext > buf.length) throw new RangeError('Index out of range')
if (offset < 0) throw new RangeError('Index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
value = +value
offset = offset >>> 0
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
// Use built-in when available, missing from IE11
this.copyWithin(targetStart, start, end)
} else if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (var i = len - 1; i >= 0; --i) {
target[i + targetStart] = this[i + start]
}
} else {
Uint8Array.prototype.set.call(
target,
this.subarray(start, end),
targetStart
)
}
return len
}
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start
start = 0
end = this.length
} else if (typeof end === 'string') {
encoding = end
end = this.length
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string')
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
if (val.length === 1) {
var code = val.charCodeAt(0)
if ((encoding === 'utf8' && code < 128) ||
encoding === 'latin1') {
// Fast path: If `val` fits into a single byte, use that numeric value.
val = code
}
}
} else if (typeof val === 'number') {
val = val & 255
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index')
}
if (end <= start) {
return this
}
start = start >>> 0
end = end === undefined ? this.length : end >>> 0
if (!val) val = 0
var i
if (typeof val === 'number') {
for (i = start; i < end; ++i) {
this[i] = val
}
} else {
var bytes = Buffer.isBuffer(val)
? val
: Buffer.from(val, encoding)
var len = bytes.length
if (len === 0) {
throw new TypeError('The value "' + val +
'" is invalid for argument "value"')
}
for (i = 0; i < end - start; ++i) {
this[i + start] = bytes[i % len]
}
}
return this
}
// HELPER FUNCTIONS
// ================
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
function base64clean (str) {
// Node takes equal signs as end of the Base64 encoding
str = str.split('=')[0]
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = str.trim().replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; ++i) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; ++i) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; ++i) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; ++i) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
// the `instanceof` check but they should be treated as of that type.
// See: https://github.com/feross/buffer/issues/166
function isInstance (obj, type) {
return obj instanceof type ||
(obj != null && obj.constructor != null && obj.constructor.name != null &&
obj.constructor.name === type.name)
}
function numberIsNaN (obj) {
// For IE11 support
return obj !== obj // eslint-disable-line no-self-compare
}
}).call(this)}).call(this,require("buffer").Buffer)
},{"base64-js":7,"buffer":10,"ieee754":29}],11:[function(require,module,exports){
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
(function () {
'use strict';
var hasOwn = {}.hasOwnProperty;
function classNames() {
var classes = [];
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes.push(arg);
} else if (Array.isArray(arg)) {
if (arg.length) {
var inner = classNames.apply(null, arg);
if (inner) {
classes.push(inner);
}
}
} else if (argType === 'object') {
if (arg.toString === Object.prototype.toString) {
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes.push(key);
}
}
} else {
classes.push(arg.toString());
}
}
}
return classes.join(' ');
}
if (typeof module !== 'undefined' && module.exports) {
classNames.default = classNames;
module.exports = classNames;
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
// register as 'classnames', consistent with npm package name
define('classnames', [], function () {
return classNames;
});
} else {
window.classNames = classNames;
}
}());
},{}],12:[function(require,module,exports){
/**
* Slice reference.
*/
var slice = [].slice;
/**
* Bind `obj` to `fn`.
*
* @param {Object} obj
* @param {Function|String} fn or string
* @return {Function}
* @api public
*/
module.exports = function(obj, fn){
if ('string' == typeof fn) fn = obj[fn];
if ('function' != typeof fn) throw new Error('bind() requires a function');
var args = slice.call(arguments, 2);
return function(){
return fn.apply(obj, args.concat(slice.call(arguments)));
}
};
},{}],13:[function(require,module,exports){
module.exports = function(a, b){
var fn = function(){};
fn.prototype = b.prototype;
a.prototype = new fn;
a.prototype.constructor = a;
};
},{}],14:[function(require,module,exports){
/*!
* Cropper.js v1.5.7
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2020-05-23T05:23:00.081Z
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.Cropper = factory());
}(this, (function () { 'use strict';
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
var WINDOW = IS_BROWSER ? window : {};
var IS_TOUCH_DEVICE = IS_BROWSER && WINDOW.document.documentElement ? 'ontouchstart' in WINDOW.document.documentElement : false;
var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
var NAMESPACE = 'cropper'; // Actions
var ACTION_ALL = 'all';
var ACTION_CROP = 'crop';
var ACTION_MOVE = 'move';
var ACTION_ZOOM = 'zoom';
var ACTION_EAST = 'e';
var ACTION_WEST = 'w';
var ACTION_SOUTH = 's';
var ACTION_NORTH = 'n';
var ACTION_NORTH_EAST = 'ne';
var ACTION_NORTH_WEST = 'nw';
var ACTION_SOUTH_EAST = 'se';
var ACTION_SOUTH_WEST = 'sw'; // Classes
var CLASS_CROP = "".concat(NAMESPACE, "-crop");
var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
var CLASS_MOVE = "".concat(NAMESPACE, "-move"); // Data keys
var DATA_ACTION = "".concat(NAMESPACE, "Action");
var DATA_PREVIEW = "".concat(NAMESPACE, "Preview"); // Drag modes
var DRAG_MODE_CROP = 'crop';
var DRAG_MODE_MOVE = 'move';
var DRAG_MODE_NONE = 'none'; // Events
var EVENT_CROP = 'crop';
var EVENT_CROP_END = 'cropend';
var EVENT_CROP_MOVE = 'cropmove';
var EVENT_CROP_START = 'cropstart';
var EVENT_DBLCLICK = 'dblclick';
var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;
var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
var EVENT_READY = 'ready';
var EVENT_RESIZE = 'resize';
var EVENT_WHEEL = 'wheel';
var EVENT_ZOOM = 'zoom'; // Mime types
var MIME_TYPE_JPEG = 'image/jpeg'; // RegExps
var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
var REGEXP_DATA_URL = /^data:/;
var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
var REGEXP_TAG_NAME = /^img|canvas$/i; // Misc
var DEFAULTS = {
// Define the view mode of the cropper
viewMode: 0,
// 0, 1, 2, 3
// Define the dragging mode of the cropper
dragMode: DRAG_MODE_CROP,
// 'crop', 'move' or 'none'
// Define the initial aspect ratio of the crop box
initialAspectRatio: NaN,
// Define the aspect ratio of the crop box
aspectRatio: NaN,
// An object with the previous cropping result data
data: null,
// A selector for adding extra containers to preview
preview: '',
// Re-render the cropper when resize the window
responsive: true,
// Restore the cropped area after resize the window
restore: true,
// Check if the current image is a cross-origin image
checkCrossOrigin: true,
// Check the current image's Exif Orientation information
checkOrientation: true,
// Show the black modal
modal: true,
// Show the dashed lines for guiding
guides: true,
// Show the center indicator for guiding
center: true,
// Show the white modal to highlight the crop box
highlight: true,
// Show the grid background
background: true,
// Enable to crop the image automatically when initialize
autoCrop: true,
// Define the percentage of automatic cropping area when initializes
autoCropArea: 0.8,
// Enable to move the image
movable: true,
// Enable to rotate the image
rotatable: true,
// Enable to scale the image
scalable: true,
// Enable to zoom the image
zoomable: true,
// Enable to zoom the image by dragging touch
zoomOnTouch: true,
// Enable to zoom the image by wheeling mouse
zoomOnWheel: true,
// Define zoom ratio when zoom the image by wheeling mouse
wheelZoomRatio: 0.1,
// Enable to move the crop box
cropBoxMovable: true,
// Enable to resize the crop box
cropBoxResizable: true,
// Toggle drag mode between "crop" and "move" when click twice on the cropper
toggleDragModeOnDblclick: true,
// Size limitation
minCanvasWidth: 0,
minCanvasHeight: 0,
minCropBoxWidth: 0,
minCropBoxHeight: 0,
minContainerWidth: 200,
minContainerHeight: 100,
// Shortcuts of events
ready: null,
cropstart: null,
cropmove: null,
cropend: null,
crop: null,
zoom: null
};
var TEMPLATE = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';
/**
* Check if the given value is not a number.
*/
var isNaN = Number.isNaN || WINDOW.isNaN;
/**
* Check if the given value is a number.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a number, else `false`.
*/
function isNumber(value) {
return typeof value === 'number' && !isNaN(value);
}
/**
* Check if the given value is a positive number.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
*/
var isPositiveNumber = function isPositiveNumber(value) {
return value > 0 && value < Infinity;
};
/**
* Check if the given value is undefined.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is undefined, else `false`.
*/
function isUndefined(value) {
return typeof value === 'undefined';
}
/**
* Check if the given value is an object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is an object, else `false`.
*/
function isObject(value) {
return _typeof(value) === 'object' && value !== null;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Check if the given value is a plain object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
*/
function isPlainObject(value) {
if (!isObject(value)) {
return false;
}
try {
var _constructor = value.constructor;
var prototype = _constructor.prototype;
return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
} catch (error) {
return false;
}
}
/**
* Check if the given value is a function.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a function, else `false`.
*/
function isFunction(value) {
return typeof value === 'function';
}
var slice = Array.prototype.slice;
/**
* Convert array-like or iterable object to an array.
* @param {*} value - The value to convert.
* @returns {Array} Returns a new array.
*/
function toArray(value) {
return Array.from ? Array.from(value) : slice.call(value);
}
/**
* Iterate the given data.
* @param {*} data - The data to iterate.
* @param {Function} callback - The process function for each element.
* @returns {*} The original data.
*/
function forEach(data, callback) {
if (data && isFunction(callback)) {
if (Array.isArray(data) || isNumber(data.length)
/* array-like */
) {
toArray(data).forEach(function (value, key) {
callback.call(data, value, key, data);
});
} else if (isObject(data)) {
Object.keys(data).forEach(function (key) {
callback.call(data, data[key], key, data);
});
}
}
return data;
}
/**
* Extend the given object.
* @param {*} target - The target object to extend.
* @param {*} args - The rest objects for merging to the target object.
* @returns {Object} The extended object.
*/
var assign = Object.assign || function assign(target) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
if (isObject(target) && args.length > 0) {
args.forEach(function (arg) {
if (isObject(arg)) {
Object.keys(arg).forEach(function (key) {
target[key] = arg[key];
});
}
});
}
return target;
};
var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
/**
* Normalize decimal number.
* Check out {@link https://0.30000000000000004.com/}
* @param {number} value - The value to normalize.
* @param {number} [times=100000000000] - The times for normalizing.
* @returns {number} Returns the normalized number.
*/
function normalizeDecimalNumber(value) {
var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
}
var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
/**
* Apply styles to the given element.
* @param {Element} element - The target element.
* @param {Object} styles - The styles for applying.
*/
function setStyle(element, styles) {
var style = element.style;
forEach(styles, function (value, property) {
if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
value = "".concat(value, "px");
}
style[property] = value;
});
}
/**
* Check if the given element has a special class.
* @param {Element} element - The element to check.
* @param {string} value - The class to search.
* @returns {boolean} Returns `true` if the special class was found.
*/
function hasClass(element, value) {
return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
}
/**
* Add classes to the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be added.
*/
function addClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
addClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.add(value);
return;
}
var className = element.className.trim();
if (!className) {
element.className = value;
} else if (className.indexOf(value) < 0) {
element.className = "".concat(className, " ").concat(value);
}
}
/**
* Remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be removed.
*/
function removeClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
removeClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.remove(value);
return;
}
if (element.className.indexOf(value) >= 0) {
element.className = element.className.replace(value, '');
}
}
/**
* Add or remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be toggled.
* @param {boolean} added - Add only.
*/
function toggleClass(element, value, added) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
toggleClass(elem, value, added);
});
return;
} // IE10-11 doesn't support the second parameter of `classList.toggle`
if (added) {
addClass(element, value);
} else {
removeClass(element, value);
}
}
var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
/**
* Transform the given string from camelCase to kebab-case
* @param {string} value - The value to transform.
* @returns {string} The transformed value.
*/
function toParamCase(value) {
return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
}
/**
* Get data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to get.
* @returns {string} The data value.
*/
function getData(element, name) {
if (isObject(element[name])) {
return element[name];
}
if (element.dataset) {
return element.dataset[name];
}
return element.getAttribute("data-".concat(toParamCase(name)));
}
/**
* Set data to the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to set.
* @param {string} data - The data value.
*/
function setData(element, name, data) {
if (isObject(data)) {
element[name] = data;
} else if (element.dataset) {
element.dataset[name] = data;
} else {
element.setAttribute("data-".concat(toParamCase(name)), data);
}
}
/**
* Remove data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to remove.
*/
function removeData(element, name) {
if (isObject(element[name])) {
try {
delete element[name];
} catch (error) {
element[name] = undefined;
}
} else if (element.dataset) {
// #128 Safari not allows to delete dataset property
try {
delete element.dataset[name];
} catch (error) {
element.dataset[name] = undefined;
}
} else {
element.removeAttribute("data-".concat(toParamCase(name)));
}
}
var REGEXP_SPACES = /\s\s*/;
var onceSupported = function () {
var supported = false;
if (IS_BROWSER) {
var once = false;
var listener = function listener() {};
var options = Object.defineProperty({}, 'once', {
get: function get() {
supported = true;
return once;
},
/**
* This setter can fix a `TypeError` in strict mode
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
* @param {boolean} value - The value to set
*/
set: function set(value) {
once = value;
}
});
WINDOW.addEventListener('test', listener, options);
WINDOW.removeEventListener('test', listener, options);
}
return supported;
}();
/**
* Remove event listener from the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function removeListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (!onceSupported) {
var listeners = element.listeners;
if (listeners && listeners[event] && listeners[event][listener]) {
handler = listeners[event][listener];
delete listeners[event][listener];
if (Object.keys(listeners[event]).length === 0) {
delete listeners[event];
}
if (Object.keys(listeners).length === 0) {
delete element.listeners;
}
}
}
element.removeEventListener(event, handler, options);
});
}
/**
* Add event listener to the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function addListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (options.once && !onceSupported) {
var _element$listeners = element.listeners,
listeners = _element$listeners === void 0 ? {} : _element$listeners;
_handler = function handler() {
delete listeners[event][listener];
element.removeEventListener(event, _handler, options);
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
listener.apply(element, args);
};
if (!listeners[event]) {
listeners[event] = {};
}
if (listeners[event][listener]) {
element.removeEventListener(event, listeners[event][listener], options);
}
listeners[event][listener] = _handler;
element.listeners = listeners;
}
element.addEventListener(event, _handler, options);
});
}
/**
* Dispatch event on the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Object} data - The additional event data.
* @returns {boolean} Indicate if the event is default prevented or not.
*/
function dispatchEvent(element, type, data) {
var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
if (isFunction(Event) && isFunction(CustomEvent)) {
event = new CustomEvent(type, {
detail: data,
bubbles: true,
cancelable: true
});
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, data);
}
return element.dispatchEvent(event);
}
/**
* Get the offset base on the document.
* @param {Element} element - The target element.
* @returns {Object} The offset data.
*/
function getOffset(element) {
var box = element.getBoundingClientRect();
return {
left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
top: box.top + (window.pageYOffset - document.documentElement.clientTop)
};
}
var location = WINDOW.location;
var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
/**
* Check if the given URL is a cross origin URL.
* @param {string} url - The target URL.
* @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
*/
function isCrossOriginURL(url) {
var parts = url.match(REGEXP_ORIGINS);
return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
}
/**
* Add timestamp to the given URL.
* @param {string} url - The target URL.
* @returns {string} The result URL.
*/
function addTimestamp(url) {
var timestamp = "timestamp=".concat(new Date().getTime());
return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
}
/**
* Get transforms base on the given object.
* @param {Object} obj - The target object.
* @returns {string} A string contains transform values.
*/
function getTransforms(_ref) {
var rotate = _ref.rotate,
scaleX = _ref.scaleX,
scaleY = _ref.scaleY,
translateX = _ref.translateX,
translateY = _ref.translateY;
var values = [];
if (isNumber(translateX) && translateX !== 0) {
values.push("translateX(".concat(translateX, "px)"));
}
if (isNumber(translateY) && translateY !== 0) {
values.push("translateY(".concat(translateY, "px)"));
} // Rotate should come first before scale to match orientation transform
if (isNumber(rotate) && rotate !== 0) {
values.push("rotate(".concat(rotate, "deg)"));
}
if (isNumber(scaleX) && scaleX !== 1) {
values.push("scaleX(".concat(scaleX, ")"));
}
if (isNumber(scaleY) && scaleY !== 1) {
values.push("scaleY(".concat(scaleY, ")"));
}
var transform = values.length ? values.join(' ') : 'none';
return {
WebkitTransform: transform,
msTransform: transform,
transform: transform
};
}
/**
* Get the max ratio of a group of pointers.
* @param {string} pointers - The target pointers.
* @returns {number} The result ratio.
*/
function getMaxZoomRatio(pointers) {
var pointers2 = _objectSpread2({}, pointers);
var ratios = [];
forEach(pointers, function (pointer, pointerId) {
delete pointers2[pointerId];
forEach(pointers2, function (pointer2) {
var x1 = Math.abs(pointer.startX - pointer2.startX);
var y1 = Math.abs(pointer.startY - pointer2.startY);
var x2 = Math.abs(pointer.endX - pointer2.endX);
var y2 = Math.abs(pointer.endY - pointer2.endY);
var z1 = Math.sqrt(x1 * x1 + y1 * y1);
var z2 = Math.sqrt(x2 * x2 + y2 * y2);
var ratio = (z2 - z1) / z1;
ratios.push(ratio);
});
});
ratios.sort(function (a, b) {
return Math.abs(a) < Math.abs(b);
});
return ratios[0];
}
/**
* Get a pointer from an event object.
* @param {Object} event - The target event object.
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
* @returns {Object} The result pointer contains start and/or end point coordinates.
*/
function getPointer(_ref2, endOnly) {
var pageX = _ref2.pageX,
pageY = _ref2.pageY;
var end = {
endX: pageX,
endY: pageY
};
return endOnly ? end : _objectSpread2({
startX: pageX,
startY: pageY
}, end);
}
/**
* Get the center point coordinate of a group of pointers.
* @param {Object} pointers - The target pointers.
* @returns {Object} The center point coordinate.
*/
function getPointersCenter(pointers) {
var pageX = 0;
var pageY = 0;
var count = 0;
forEach(pointers, function (_ref3) {
var startX = _ref3.startX,
startY = _ref3.startY;
pageX += startX;
pageY += startY;
count += 1;
});
pageX /= count;
pageY /= count;
return {
pageX: pageX,
pageY: pageY
};
}
/**
* Get the max sizes in a rectangle under the given aspect ratio.
* @param {Object} data - The original sizes.
* @param {string} [type='contain'] - The adjust type.
* @returns {Object} The result sizes.
*/
function getAdjustedSizes(_ref4) // or 'cover'
{
var aspectRatio = _ref4.aspectRatio,
height = _ref4.height,
width = _ref4.width;
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
var isValidWidth = isPositiveNumber(width);
var isValidHeight = isPositiveNumber(height);
if (isValidWidth && isValidHeight) {
var adjustedWidth = height * aspectRatio;
if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
height = width / aspectRatio;
} else {
width = height * aspectRatio;
}
} else if (isValidWidth) {
height = width / aspectRatio;
} else if (isValidHeight) {
width = height * aspectRatio;
}
return {
width: width,
height: height
};
}
/**
* Get the new sizes of a rectangle after rotated.
* @param {Object} data - The original sizes.
* @returns {Object} The result sizes.
*/
function getRotatedSizes(_ref5) {
var width = _ref5.width,
height = _ref5.height,
degree = _ref5.degree;
degree = Math.abs(degree) % 180;
if (degree === 90) {
return {
width: height,
height: width
};
}
var arc = degree % 90 * Math.PI / 180;
var sinArc = Math.sin(arc);
var cosArc = Math.cos(arc);
var newWidth = width * cosArc + height * sinArc;
var newHeight = width * sinArc + height * cosArc;
return degree > 90 ? {
width: newHeight,
height: newWidth
} : {
width: newWidth,
height: newHeight
};
}
/**
* Get a canvas which drew the given image.
* @param {HTMLImageElement} image - The image for drawing.
* @param {Object} imageData - The image data.
* @param {Object} canvasData - The canvas data.
* @param {Object} options - The options.
* @returns {HTMLCanvasElement} The result canvas.
*/
function getSourceCanvas(image, _ref6, _ref7, _ref8) {
var imageAspectRatio = _ref6.aspectRatio,
imageNaturalWidth = _ref6.naturalWidth,
imageNaturalHeight = _ref6.naturalHeight,
_ref6$rotate = _ref6.rotate,
rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
_ref6$scaleX = _ref6.scaleX,
scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
_ref6$scaleY = _ref6.scaleY,
scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
var aspectRatio = _ref7.aspectRatio,
naturalWidth = _ref7.naturalWidth,
naturalHeight = _ref7.naturalHeight;
var _ref8$fillColor = _ref8.fillColor,
fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
_ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
_ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
_ref8$maxWidth = _ref8.maxWidth,
maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
_ref8$maxHeight = _ref8.maxHeight,
maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
_ref8$minWidth = _ref8.minWidth,
minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
_ref8$minHeight = _ref8.minHeight,
minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var maxSizes = getAdjustedSizes({
aspectRatio: aspectRatio,
width: maxWidth,
height: maxHeight
});
var minSizes = getAdjustedSizes({
aspectRatio: aspectRatio,
width: minWidth,
height: minHeight
}, 'cover');
var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); // Note: should always use image's natural sizes for drawing as
// imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
var destMaxSizes = getAdjustedSizes({
aspectRatio: imageAspectRatio,
width: maxWidth,
height: maxHeight
});
var destMinSizes = getAdjustedSizes({
aspectRatio: imageAspectRatio,
width: minWidth,
height: minHeight
}, 'cover');
var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));
var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));
var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];
canvas.width = normalizeDecimalNumber(width);
canvas.height = normalizeDecimalNumber(height);
context.fillStyle = fillColor;
context.fillRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.rotate(rotate * Math.PI / 180);
context.scale(scaleX, scaleY);
context.imageSmoothingEnabled = imageSmoothingEnabled;
context.imageSmoothingQuality = imageSmoothingQuality;
context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {
return Math.floor(normalizeDecimalNumber(param));
}))));
context.restore();
return canvas;
}
var fromCharCode = String.fromCharCode;
/**
* Get string from char code in data view.
* @param {DataView} dataView - The data view for read.
* @param {number} start - The start index.
* @param {number} length - The read length.
* @returns {string} The read result.
*/
function getStringFromCharCode(dataView, start, length) {
var str = '';
length += start;
for (var i = start; i < length; i += 1) {
str += fromCharCode(dataView.getUint8(i));
}
return str;
}
var REGEXP_DATA_URL_HEAD = /^data:.*,/;
/**
* Transform Data URL to array buffer.
* @param {string} dataURL - The Data URL to transform.
* @returns {ArrayBuffer} The result array buffer.
*/
function dataURLToArrayBuffer(dataURL) {
var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
var binary = atob(base64);
var arrayBuffer = new ArrayBuffer(binary.length);
var uint8 = new Uint8Array(arrayBuffer);
forEach(uint8, function (value, i) {
uint8[i] = binary.charCodeAt(i);
});
return arrayBuffer;
}
/**
* Transform array buffer to Data URL.
* @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
* @param {string} mimeType - The mime type of the Data URL.
* @returns {string} The result Data URL.
*/
function arrayBufferToDataURL(arrayBuffer, mimeType) {
var chunks = []; // Chunk Typed Array for better performance (#435)
var chunkSize = 8192;
var uint8 = new Uint8Array(arrayBuffer);
while (uint8.length > 0) {
// XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
// eslint-disable-next-line prefer-spread
chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
uint8 = uint8.subarray(chunkSize);
}
return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
}
/**
* Get orientation value from given array buffer.
* @param {ArrayBuffer} arrayBuffer - The array buffer to read.
* @returns {number} The read orientation value.
*/
function resetAndGetOrientation(arrayBuffer) {
var dataView = new DataView(arrayBuffer);
var orientation; // Ignores range error when the image does not have correct Exif information
try {
var littleEndian;
var app1Start;
var ifdStart; // Only handle JPEG image (start by 0xFFD8)
if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
var length = dataView.byteLength;
var offset = 2;
while (offset + 1 < length) {
if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
app1Start = offset;
break;
}
offset += 1;
}
}
if (app1Start) {
var exifIDCode = app1Start + 4;
var tiffOffset = app1Start + 10;
if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
var endianness = dataView.getUint16(tiffOffset);
littleEndian = endianness === 0x4949;
if (littleEndian || endianness === 0x4D4D
/* bigEndian */
) {
if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
if (firstIFDOffset >= 0x00000008) {
ifdStart = tiffOffset + firstIFDOffset;
}
}
}
}
}
if (ifdStart) {
var _length = dataView.getUint16(ifdStart, littleEndian);
var _offset;
var i;
for (i = 0; i < _length; i += 1) {
_offset = ifdStart + i * 12 + 2;
if (dataView.getUint16(_offset, littleEndian) === 0x0112
/* Orientation */
) {
// 8 is the offset of the current tag's value
_offset += 8; // Get the original orientation value
orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value
dataView.setUint16(_offset, 1, littleEndian);
break;
}
}
}
} catch (error) {
orientation = 1;
}
return orientation;
}
/**
* Parse Exif Orientation value.
* @param {number} orientation - The orientation to parse.
* @returns {Object} The parsed result.
*/
function parseOrientation(orientation) {
var rotate = 0;
var scaleX = 1;
var scaleY = 1;
switch (orientation) {
// Flip horizontal
case 2:
scaleX = -1;
break;
// Rotate left 180°
case 3:
rotate = -180;
break;
// Flip vertical
case 4:
scaleY = -1;
break;
// Flip vertical and rotate right 90°
case 5:
rotate = 90;
scaleY = -1;
break;
// Rotate right 90°
case 6:
rotate = 90;
break;
// Flip horizontal and rotate right 90°
case 7:
rotate = 90;
scaleX = -1;
break;
// Rotate left 90°
case 8:
rotate = -90;
break;
}
return {
rotate: rotate,
scaleX: scaleX,
scaleY: scaleY
};
}
var render = {
render: function render() {
this.initContainer();
this.initCanvas();
this.initCropBox();
this.renderCanvas();
if (this.cropped) {
this.renderCropBox();
}
},
initContainer: function initContainer() {
var element = this.element,
options = this.options,
container = this.container,
cropper = this.cropper;
addClass(cropper, CLASS_HIDDEN);
removeClass(element, CLASS_HIDDEN);
var containerData = {
width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200),
height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100)
};
this.containerData = containerData;
setStyle(cropper, {
width: containerData.width,
height: containerData.height
});
addClass(element, CLASS_HIDDEN);
removeClass(cropper, CLASS_HIDDEN);
},
// Canvas (image wrapper)
initCanvas: function initCanvas() {
var containerData = this.containerData,
imageData = this.imageData;
var viewMode = this.options.viewMode;
var rotated = Math.abs(imageData.rotate) % 180 === 90;
var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
var aspectRatio = naturalWidth / naturalHeight;
var canvasWidth = containerData.width;
var canvasHeight = containerData.height;
if (containerData.height * aspectRatio > containerData.width) {
if (viewMode === 3) {
canvasWidth = containerData.height * aspectRatio;
} else {
canvasHeight = containerData.width / aspectRatio;
}
} else if (viewMode === 3) {
canvasHeight = containerData.width / aspectRatio;
} else {
canvasWidth = containerData.height * aspectRatio;
}
var canvasData = {
aspectRatio: aspectRatio,
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
width: canvasWidth,
height: canvasHeight
};
canvasData.left = (containerData.width - canvasWidth) / 2;
canvasData.top = (containerData.height - canvasHeight) / 2;
canvasData.oldLeft = canvasData.left;
canvasData.oldTop = canvasData.top;
this.canvasData = canvasData;
this.limited = viewMode === 1 || viewMode === 2;
this.limitCanvas(true, true);
this.initialImageData = assign({}, imageData);
this.initialCanvasData = assign({}, canvasData);
},
limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
var options = this.options,
containerData = this.containerData,
canvasData = this.canvasData,
cropBoxData = this.cropBoxData;
var viewMode = options.viewMode;
var aspectRatio = canvasData.aspectRatio;
var cropped = this.cropped && cropBoxData;
if (sizeLimited) {
var minCanvasWidth = Number(options.minCanvasWidth) || 0;
var minCanvasHeight = Number(options.minCanvasHeight) || 0;
if (viewMode > 1) {
minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
if (viewMode === 3) {
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
minCanvasWidth = minCanvasHeight * aspectRatio;
} else {
minCanvasHeight = minCanvasWidth / aspectRatio;
}
}
} else if (viewMode > 0) {
if (minCanvasWidth) {
minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
} else if (minCanvasHeight) {
minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
} else if (cropped) {
minCanvasWidth = cropBoxData.width;
minCanvasHeight = cropBoxData.height;
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
minCanvasWidth = minCanvasHeight * aspectRatio;
} else {
minCanvasHeight = minCanvasWidth / aspectRatio;
}
}
}
var _getAdjustedSizes = getAdjustedSizes({
aspectRatio: aspectRatio,
width: minCanvasWidth,
height: minCanvasHeight
});
minCanvasWidth = _getAdjustedSizes.width;
minCanvasHeight = _getAdjustedSizes.height;
canvasData.minWidth = minCanvasWidth;
canvasData.minHeight = minCanvasHeight;
canvasData.maxWidth = Infinity;
canvasData.maxHeight = Infinity;
}
if (positionLimited) {
if (viewMode > (cropped ? 0 : 1)) {
var newCanvasLeft = containerData.width - canvasData.width;
var newCanvasTop = containerData.height - canvasData.height;
canvasData.minLeft = Math.min(0, newCanvasLeft);
canvasData.minTop = Math.min(0, newCanvasTop);
canvasData.maxLeft = Math.max(0, newCanvasLeft);
canvasData.maxTop = Math.max(0, newCanvasTop);
if (cropped && this.limited) {
canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
canvasData.maxLeft = cropBoxData.left;
canvasData.maxTop = cropBoxData.top;
if (viewMode === 2) {
if (canvasData.width >= containerData.width) {
canvasData.minLeft = Math.min(0, newCanvasLeft);
canvasData.maxLeft = Math.max(0, newCanvasLeft);
}
if (canvasData.height >= containerData.height) {
canvasData.minTop = Math.min(0, newCanvasTop);
canvasData.maxTop = Math.max(0, newCanvasTop);
}
}
}
} else {
canvasData.minLeft = -canvasData.width;
canvasData.minTop = -canvasData.height;
canvasData.maxLeft = containerData.width;
canvasData.maxTop = containerData.height;
}
}
},
renderCanvas: function renderCanvas(changed, transformed) {
var canvasData = this.canvasData,
imageData = this.imageData;
if (transformed) {
var _getRotatedSizes = getRotatedSizes({
width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
degree: imageData.rotate || 0
}),
naturalWidth = _getRotatedSizes.width,
naturalHeight = _getRotatedSizes.height;
var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
canvasData.left -= (width - canvasData.width) / 2;
canvasData.top -= (height - canvasData.height) / 2;
canvasData.width = width;
canvasData.height = height;
canvasData.aspectRatio = naturalWidth / naturalHeight;
canvasData.naturalWidth = naturalWidth;
canvasData.naturalHeight = naturalHeight;
this.limitCanvas(true, false);
}
if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
canvasData.left = canvasData.oldLeft;
}
if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
canvasData.top = canvasData.oldTop;
}
canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
this.limitCanvas(false, true);
canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
canvasData.oldLeft = canvasData.left;
canvasData.oldTop = canvasData.top;
setStyle(this.canvas, assign({
width: canvasData.width,
height: canvasData.height
}, getTransforms({
translateX: canvasData.left,
translateY: canvasData.top
})));
this.renderImage(changed);
if (this.cropped && this.limited) {
this.limitCropBox(true, true);
}
},
renderImage: function renderImage(changed) {
var canvasData = this.canvasData,
imageData = this.imageData;
var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
assign(imageData, {
width: width,
height: height,
left: (canvasData.width - width) / 2,
top: (canvasData.height - height) / 2
});
setStyle(this.image, assign({
width: imageData.width,
height: imageData.height
}, getTransforms(assign({
translateX: imageData.left,
translateY: imageData.top
}, imageData))));
if (changed) {
this.output();
}
},
initCropBox: function initCropBox() {
var options = this.options,
canvasData = this.canvasData;
var aspectRatio = options.aspectRatio || options.initialAspectRatio;
var autoCropArea = Number(options.autoCropArea) || 0.8;
var cropBoxData = {
width: canvasData.width,
height: canvasData.height
};
if (aspectRatio) {
if (canvasData.height * aspectRatio > canvasData.width) {
cropBoxData.height = cropBoxData.width / aspectRatio;
} else {
cropBoxData.width = cropBoxData.height * aspectRatio;
}
}
this.cropBoxData = cropBoxData;
this.limitCropBox(true, true); // Initialize auto crop area
cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); // The width/height of auto crop area must large than "minWidth/Height"
cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
cropBoxData.oldLeft = cropBoxData.left;
cropBoxData.oldTop = cropBoxData.top;
this.initialCropBoxData = assign({}, cropBoxData);
},
limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
var options = this.options,
containerData = this.containerData,
canvasData = this.canvasData,
cropBoxData = this.cropBoxData,
limited = this.limited;
var aspectRatio = options.aspectRatio;
if (sizeLimited) {
var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height; // The min/maxCropBoxWidth/Height must be less than container's width/height
minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
if (aspectRatio) {
if (minCropBoxWidth && minCropBoxHeight) {
if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
minCropBoxHeight = minCropBoxWidth / aspectRatio;
} else {
minCropBoxWidth = minCropBoxHeight * aspectRatio;
}
} else if (minCropBoxWidth) {
minCropBoxHeight = minCropBoxWidth / aspectRatio;
} else if (minCropBoxHeight) {
minCropBoxWidth = minCropBoxHeight * aspectRatio;
}
if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
} else {
maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
}
} // The minWidth/Height must be less than maxWidth/Height
cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
cropBoxData.maxWidth = maxCropBoxWidth;
cropBoxData.maxHeight = maxCropBoxHeight;
}
if (positionLimited) {
if (limited) {
cropBoxData.minLeft = Math.max(0, canvasData.left);
cropBoxData.minTop = Math.max(0, canvasData.top);
cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
} else {
cropBoxData.minLeft = 0;
cropBoxData.minTop = 0;
cropBoxData.maxLeft = containerData.width - cropBoxData.width;
cropBoxData.maxTop = containerData.height - cropBoxData.height;
}
}
},
renderCropBox: function renderCropBox() {
var options = this.options,
containerData = this.containerData,
cropBoxData = this.cropBoxData;
if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
cropBoxData.left = cropBoxData.oldLeft;
}
if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
cropBoxData.top = cropBoxData.oldTop;
}
cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
this.limitCropBox(false, true);
cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
cropBoxData.oldLeft = cropBoxData.left;
cropBoxData.oldTop = cropBoxData.top;
if (options.movable && options.cropBoxMovable) {
// Turn to move the canvas when the crop box is equal to the container
setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
}
setStyle(this.cropBox, assign({
width: cropBoxData.width,
height: cropBoxData.height
}, getTransforms({
translateX: cropBoxData.left,
translateY: cropBoxData.top
})));
if (this.cropped && this.limited) {
this.limitCanvas(true, true);
}
if (!this.disabled) {
this.output();
}
},
output: function output() {
this.preview();
dispatchEvent(this.element, EVENT_CROP, this.getData());
}
};
var preview = {
initPreview: function initPreview() {
var element = this.element,
crossOrigin = this.crossOrigin;
var preview = this.options.preview;
var url = crossOrigin ? this.crossOriginUrl : this.url;
var alt = element.alt || 'The image to preview';
var image = document.createElement('img');
if (crossOrigin) {
image.crossOrigin = crossOrigin;
}
image.src = url;
image.alt = alt;
this.viewBox.appendChild(image);
this.viewBoxImage = image;
if (!preview) {
return;
}
var previews = preview;
if (typeof preview === 'string') {
previews = element.ownerDocument.querySelectorAll(preview);
} else if (preview.querySelector) {
previews = [preview];
}
this.previews = previews;
forEach(previews, function (el) {
var img = document.createElement('img'); // Save the original size for recover
setData(el, DATA_PREVIEW, {
width: el.offsetWidth,
height: el.offsetHeight,
html: el.innerHTML
});
if (crossOrigin) {
img.crossOrigin = crossOrigin;
}
img.src = url;
img.alt = alt;
/**
* Override img element styles
* Add `display:block` to avoid margin top issue
* Add `height:auto` to override `height` attribute on IE8
* (Occur only when margin-top <= -height)
*/
img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
el.innerHTML = '';
el.appendChild(img);
});
},
resetPreview: function resetPreview() {
forEach(this.previews, function (element) {
var data = getData(element, DATA_PREVIEW);
setStyle(element, {
width: data.width,
height: data.height
});
element.innerHTML = data.html;
removeData(element, DATA_PREVIEW);
});
},
preview: function preview() {
var imageData = this.imageData,
canvasData = this.canvasData,
cropBoxData = this.cropBoxData;
var cropBoxWidth = cropBoxData.width,
cropBoxHeight = cropBoxData.height;
var width = imageData.width,
height = imageData.height;
var left = cropBoxData.left - canvasData.left - imageData.left;
var top = cropBoxData.top - canvasData.top - imageData.top;
if (!this.cropped || this.disabled) {
return;
}
setStyle(this.viewBoxImage, assign({
width: width,
height: height
}, getTransforms(assign({
translateX: -left,
translateY: -top
}, imageData))));
forEach(this.previews, function (element) {
var data = getData(element, DATA_PREVIEW);
var originalWidth = data.width;
var originalHeight = data.height;
var newWidth = originalWidth;
var newHeight = originalHeight;
var ratio = 1;
if (cropBoxWidth) {
ratio = originalWidth / cropBoxWidth;
newHeight = cropBoxHeight * ratio;
}
if (cropBoxHeight && newHeight > originalHeight) {
ratio = originalHeight / cropBoxHeight;
newWidth = cropBoxWidth * ratio;
newHeight = originalHeight;
}
setStyle(element, {
width: newWidth,
height: newHeight
});
setStyle(element.getElementsByTagName('img')[0], assign({
width: width * ratio,
height: height * ratio
}, getTransforms(assign({
translateX: -left * ratio,
translateY: -top * ratio
}, imageData))));
});
}
};
var events = {
bind: function bind() {
var element = this.element,
options = this.options,
cropper = this.cropper;
if (isFunction(options.cropstart)) {
addListener(element, EVENT_CROP_START, options.cropstart);
}
if (isFunction(options.cropmove)) {
addListener(element, EVENT_CROP_MOVE, options.cropmove);
}
if (isFunction(options.cropend)) {
addListener(element, EVENT_CROP_END, options.cropend);
}
if (isFunction(options.crop)) {
addListener(element, EVENT_CROP, options.crop);
}
if (isFunction(options.zoom)) {
addListener(element, EVENT_ZOOM, options.zoom);
}
addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
if (options.zoomable && options.zoomOnWheel) {
addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
passive: false,
capture: true
});
}
if (options.toggleDragModeOnDblclick) {
addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
}
addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
if (options.responsive) {
addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
}
},
unbind: function unbind() {
var element = this.element,
options = this.options,
cropper = this.cropper;
if (isFunction(options.cropstart)) {
removeListener(element, EVENT_CROP_START, options.cropstart);
}
if (isFunction(options.cropmove)) {
removeListener(element, EVENT_CROP_MOVE, options.cropmove);
}
if (isFunction(options.cropend)) {
removeListener(element, EVENT_CROP_END, options.cropend);
}
if (isFunction(options.crop)) {
removeListener(element, EVENT_CROP, options.crop);
}
if (isFunction(options.zoom)) {
removeListener(element, EVENT_ZOOM, options.zoom);
}
removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
if (options.zoomable && options.zoomOnWheel) {
removeListener(cropper, EVENT_WHEEL, this.onWheel, {
passive: false,
capture: true
});
}
if (options.toggleDragModeOnDblclick) {
removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
}
removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
if (options.responsive) {
removeListener(window, EVENT_RESIZE, this.onResize);
}
}
};
var handlers = {
resize: function resize() {
if (this.disabled) {
return;
}
var options = this.options,
container = this.container,
containerData = this.containerData;
var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed
if (ratio !== 1 || container.offsetHeight !== containerData.height) {
var canvasData;
var cropBoxData;
if (options.restore) {
canvasData = this.getCanvasData();
cropBoxData = this.getCropBoxData();
}
this.render();
if (options.restore) {
this.setCanvasData(forEach(canvasData, function (n, i) {
canvasData[i] = n * ratio;
}));
this.setCropBoxData(forEach(cropBoxData, function (n, i) {
cropBoxData[i] = n * ratio;
}));
}
}
},
dblclick: function dblclick() {
if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
return;
}
this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
},
wheel: function wheel(event) {
var _this = this;
var ratio = Number(this.options.wheelZoomRatio) || 0.1;
var delta = 1;
if (this.disabled) {
return;
}
event.preventDefault(); // Limit wheel speed to prevent zoom too fast (#21)
if (this.wheeling) {
return;
}
this.wheeling = true;
setTimeout(function () {
_this.wheeling = false;
}, 50);
if (event.deltaY) {
delta = event.deltaY > 0 ? 1 : -1;
} else if (event.wheelDelta) {
delta = -event.wheelDelta / 120;
} else if (event.detail) {
delta = event.detail > 0 ? 1 : -1;
}
this.zoom(-delta * ratio, event);
},
cropStart: function cropStart(event) {
var buttons = event.buttons,
button = event.button;
if (this.disabled // Handle mouse event and pointer event and ignore touch event
|| (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && ( // No primary button (Usually the left button)
isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu
|| event.ctrlKey)) {
return;
}
var options = this.options,
pointers = this.pointers;
var action;
if (event.changedTouches) {
// Handle touch event
forEach(event.changedTouches, function (touch) {
pointers[touch.identifier] = getPointer(touch);
});
} else {
// Handle mouse event and pointer event
pointers[event.pointerId || 0] = getPointer(event);
}
if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
action = ACTION_ZOOM;
} else {
action = getData(event.target, DATA_ACTION);
}
if (!REGEXP_ACTIONS.test(action)) {
return;
}
if (dispatchEvent(this.element, EVENT_CROP_START, {
originalEvent: event,
action: action
}) === false) {
return;
} // This line is required for preventing page zooming in iOS browsers
event.preventDefault();
this.action = action;
this.cropping = false;
if (action === ACTION_CROP) {
this.cropping = true;
addClass(this.dragBox, CLASS_MODAL);
}
},
cropMove: function cropMove(event) {
var action = this.action;
if (this.disabled || !action) {
return;
}
var pointers = this.pointers;
event.preventDefault();
if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
originalEvent: event,
action: action
}) === false) {
return;
}
if (event.changedTouches) {
forEach(event.changedTouches, function (touch) {
// The first parameter should not be undefined (#432)
assign(pointers[touch.identifier] || {}, getPointer(touch, true));
});
} else {
assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
}
this.change(event);
},
cropEnd: function cropEnd(event) {
if (this.disabled) {
return;
}
var action = this.action,
pointers = this.pointers;
if (event.changedTouches) {
forEach(event.changedTouches, function (touch) {
delete pointers[touch.identifier];
});
} else {
delete pointers[event.pointerId || 0];
}
if (!action) {
return;
}
event.preventDefault();
if (!Object.keys(pointers).length) {
this.action = '';
}
if (this.cropping) {
this.cropping = false;
toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
}
dispatchEvent(this.element, EVENT_CROP_END, {
originalEvent: event,
action: action
});
}
};
var change = {
change: function change(event) {
var options = this.options,
canvasData = this.canvasData,
containerData = this.containerData,
cropBoxData = this.cropBoxData,
pointers = this.pointers;
var action = this.action;
var aspectRatio = options.aspectRatio;
var left = cropBoxData.left,
top = cropBoxData.top,
width = cropBoxData.width,
height = cropBoxData.height;
var right = left + width;
var bottom = top + height;
var minLeft = 0;
var minTop = 0;
var maxWidth = containerData.width;
var maxHeight = containerData.height;
var renderable = true;
var offset; // Locking aspect ratio in "free mode" by holding shift key
if (!aspectRatio && event.shiftKey) {
aspectRatio = width && height ? width / height : 1;
}
if (this.limited) {
minLeft = cropBoxData.minLeft;
minTop = cropBoxData.minTop;
maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
}
var pointer = pointers[Object.keys(pointers)[0]];
var range = {
x: pointer.endX - pointer.startX,
y: pointer.endY - pointer.startY
};
var check = function check(side) {
switch (side) {
case ACTION_EAST:
if (right + range.x > maxWidth) {
range.x = maxWidth - right;
}
break;
case ACTION_WEST:
if (left + range.x < minLeft) {
range.x = minLeft - left;
}
break;
case ACTION_NORTH:
if (top + range.y < minTop) {
range.y = minTop - top;
}
break;
case ACTION_SOUTH:
if (bottom + range.y > maxHeight) {
range.y = maxHeight - bottom;
}
break;
}
};
switch (action) {
// Move crop box
case ACTION_ALL:
left += range.x;
top += range.y;
break;
// Resize crop box
case ACTION_EAST:
if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
renderable = false;
break;
}
check(ACTION_EAST);
width += range.x;
if (width < 0) {
action = ACTION_WEST;
width = -width;
left -= width;
}
if (aspectRatio) {
height = width / aspectRatio;
top += (cropBoxData.height - height) / 2;
}
break;
case ACTION_NORTH:
if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
renderable = false;
break;
}
check(ACTION_NORTH);
height -= range.y;
top += range.y;
if (height < 0) {
action = ACTION_SOUTH;
height = -height;
top -= height;
}
if (aspectRatio) {
width = height * aspectRatio;
left += (cropBoxData.width - width) / 2;
}
break;
case ACTION_WEST:
if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
renderable = false;
break;
}
check(ACTION_WEST);
width -= range.x;
left += range.x;
if (width < 0) {
action = ACTION_EAST;
width = -width;
left -= width;
}
if (aspectRatio) {
height = width / aspectRatio;
top += (cropBoxData.height - height) / 2;
}
break;
case ACTION_SOUTH:
if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
renderable = false;
break;
}
check(ACTION_SOUTH);
height += range.y;
if (height < 0) {
action = ACTION_NORTH;
height = -height;
top -= height;
}
if (aspectRatio) {
width = height * aspectRatio;
left += (cropBoxData.width - width) / 2;
}
break;
case ACTION_NORTH_EAST:
if (aspectRatio) {
if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
renderable = false;
break;
}
check(ACTION_NORTH);
height -= range.y;
top += range.y;
width = height * aspectRatio;
} else {
check(ACTION_NORTH);
check(ACTION_EAST);
if (range.x >= 0) {
if (right < maxWidth) {
width += range.x;
} else if (range.y <= 0 && top <= minTop) {
renderable = false;
}
} else {
width += range.x;
}
if (range.y <= 0) {
if (top > minTop) {
height -= range.y;
top += range.y;
}
} else {
height -= range.y;
top += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_SOUTH_WEST;
height = -height;
width = -width;
top -= height;
left -= width;
} else if (width < 0) {
action = ACTION_NORTH_WEST;
width = -width;
left -= width;
} else if (height < 0) {
action = ACTION_SOUTH_EAST;
height = -height;
top -= height;
}
break;
case ACTION_NORTH_WEST:
if (aspectRatio) {
if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
renderable = false;
break;
}
check(ACTION_NORTH);
height -= range.y;
top += range.y;
width = height * aspectRatio;
left += cropBoxData.width - width;
} else {
check(ACTION_NORTH);
check(ACTION_WEST);
if (range.x <= 0) {
if (left > minLeft) {
width -= range.x;
left += range.x;
} else if (range.y <= 0 && top <= minTop) {
renderable = false;
}
} else {
width -= range.x;
left += range.x;
}
if (range.y <= 0) {
if (top > minTop) {
height -= range.y;
top += range.y;
}
} else {
height -= range.y;
top += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_SOUTH_EAST;
height = -height;
width = -width;
top -= height;
left -= width;
} else if (width < 0) {
action = ACTION_NORTH_EAST;
width = -width;
left -= width;
} else if (height < 0) {
action = ACTION_SOUTH_WEST;
height = -height;
top -= height;
}
break;
case ACTION_SOUTH_WEST:
if (aspectRatio) {
if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
renderable = false;
break;
}
check(ACTION_WEST);
width -= range.x;
left += range.x;
height = width / aspectRatio;
} else {
check(ACTION_SOUTH);
check(ACTION_WEST);
if (range.x <= 0) {
if (left > minLeft) {
width -= range.x;
left += range.x;
} else if (range.y >= 0 && bottom >= maxHeight) {
renderable = false;
}
} else {
width -= range.x;
left += range.x;
}
if (range.y >= 0) {
if (bottom < maxHeight) {
height += range.y;
}
} else {
height += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_NORTH_EAST;
height = -height;
width = -width;
top -= height;
left -= width;
} else if (width < 0) {
action = ACTION_SOUTH_EAST;
width = -width;
left -= width;
} else if (height < 0) {
action = ACTION_NORTH_WEST;
height = -height;
top -= height;
}
break;
case ACTION_SOUTH_EAST:
if (aspectRatio) {
if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
renderable = false;
break;
}
check(ACTION_EAST);
width += range.x;
height = width / aspectRatio;
} else {
check(ACTION_SOUTH);
check(ACTION_EAST);
if (range.x >= 0) {
if (right < maxWidth) {
width += range.x;
} else if (range.y >= 0 && bottom >= maxHeight) {
renderable = false;
}
} else {
width += range.x;
}
if (range.y >= 0) {
if (bottom < maxHeight) {
height += range.y;
}
} else {
height += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_NORTH_WEST;
height = -height;
width = -width;
top -= height;
left -= width;
} else if (width < 0) {
action = ACTION_SOUTH_WEST;
width = -width;
left -= width;
} else if (height < 0) {
action = ACTION_NORTH_EAST;
height = -height;
top -= height;
}
break;
// Move canvas
case ACTION_MOVE:
this.move(range.x, range.y);
renderable = false;
break;
// Zoom canvas
case ACTION_ZOOM:
this.zoom(getMaxZoomRatio(pointers), event);
renderable = false;
break;
// Create crop box
case ACTION_CROP:
if (!range.x || !range.y) {
renderable = false;
break;
}
offset = getOffset(this.cropper);
left = pointer.startX - offset.left;
top = pointer.startY - offset.top;
width = cropBoxData.minWidth;
height = cropBoxData.minHeight;
if (range.x > 0) {
action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
} else if (range.x < 0) {
left -= width;
action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
}
if (range.y < 0) {
top -= height;
} // Show the crop box if is hidden
if (!this.cropped) {
removeClass(this.cropBox, CLASS_HIDDEN);
this.cropped = true;
if (this.limited) {
this.limitCropBox(true, true);
}
}
break;
}
if (renderable) {
cropBoxData.width = width;
cropBoxData.height = height;
cropBoxData.left = left;
cropBoxData.top = top;
this.action = action;
this.renderCropBox();
} // Override
forEach(pointers, function (p) {
p.startX = p.endX;
p.startY = p.endY;
});
}
};
var methods = {
// Show the crop box manually
crop: function crop() {
if (this.ready && !this.cropped && !this.disabled) {
this.cropped = true;
this.limitCropBox(true, true);
if (this.options.modal) {
addClass(this.dragBox, CLASS_MODAL);
}
removeClass(this.cropBox, CLASS_HIDDEN);
this.setCropBoxData(this.initialCropBoxData);
}
return this;
},
// Reset the image and crop box to their initial states
reset: function reset() {
if (this.ready && !this.disabled) {
this.imageData = assign({}, this.initialImageData);
this.canvasData = assign({}, this.initialCanvasData);
this.cropBoxData = assign({}, this.initialCropBoxData);
this.renderCanvas();
if (this.cropped) {
this.renderCropBox();
}
}
return this;
},
// Clear the crop box
clear: function clear() {
if (this.cropped && !this.disabled) {
assign(this.cropBoxData, {
left: 0,
top: 0,
width: 0,
height: 0
});
this.cropped = false;
this.renderCropBox();
this.limitCanvas(true, true); // Render canvas after crop box rendered
this.renderCanvas();
removeClass(this.dragBox, CLASS_MODAL);
addClass(this.cropBox, CLASS_HIDDEN);
}
return this;
},
/**
* Replace the image's src and rebuild the cropper
* @param {string} url - The new URL.
* @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.
* @returns {Cropper} this
*/
replace: function replace(url) {
var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (!this.disabled && url) {
if (this.isImg) {
this.element.src = url;
}
if (hasSameSize) {
this.url = url;
this.image.src = url;
if (this.ready) {
this.viewBoxImage.src = url;
forEach(this.previews, function (element) {
element.getElementsByTagName('img')[0].src = url;
});
}
} else {
if (this.isImg) {
this.replaced = true;
}
this.options.data = null;
this.uncreate();
this.load(url);
}
}
return this;
},
// Enable (unfreeze) the cropper
enable: function enable() {
if (this.ready && this.disabled) {
this.disabled = false;
removeClass(this.cropper, CLASS_DISABLED);
}
return this;
},
// Disable (freeze) the cropper
disable: function disable() {
if (this.ready && !this.disabled) {
this.disabled = true;
addClass(this.cropper, CLASS_DISABLED);
}
return this;
},
/**
* Destroy the cropper and remove the instance from the image
* @returns {Cropper} this
*/
destroy: function destroy() {
var element = this.element;
if (!element[NAMESPACE]) {
return this;
}
element[NAMESPACE] = undefined;
if (this.isImg && this.replaced) {
element.src = this.originalUrl;
}
this.uncreate();
return this;
},
/**
* Move the canvas with relative offsets
* @param {number} offsetX - The relative offset distance on the x-axis.
* @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.
* @returns {Cropper} this
*/
move: function move(offsetX) {
var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
var _this$canvasData = this.canvasData,
left = _this$canvasData.left,
top = _this$canvasData.top;
return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
},
/**
* Move the canvas to an absolute point
* @param {number} x - The x-axis coordinate.
* @param {number} [y=x] - The y-axis coordinate.
* @returns {Cropper} this
*/
moveTo: function moveTo(x) {
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
var canvasData = this.canvasData;
var changed = false;
x = Number(x);
y = Number(y);
if (this.ready && !this.disabled && this.options.movable) {
if (isNumber(x)) {
canvasData.left = x;
changed = true;
}
if (isNumber(y)) {
canvasData.top = y;
changed = true;
}
if (changed) {
this.renderCanvas(true);
}
}
return this;
},
/**
* Zoom the canvas with a relative ratio
* @param {number} ratio - The target ratio.
* @param {Event} _originalEvent - The original event if any.
* @returns {Cropper} this
*/
zoom: function zoom(ratio, _originalEvent) {
var canvasData = this.canvasData;
ratio = Number(ratio);
if (ratio < 0) {
ratio = 1 / (1 - ratio);
} else {
ratio = 1 + ratio;
}
return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
},
/**
* Zoom the canvas to an absolute ratio
* @param {number} ratio - The target ratio.
* @param {Object} pivot - The zoom pivot point coordinate.
* @param {Event} _originalEvent - The original event if any.
* @returns {Cropper} this
*/
zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
var options = this.options,
canvasData = this.canvasData;
var width = canvasData.width,
height = canvasData.height,
naturalWidth = canvasData.naturalWidth,
naturalHeight = canvasData.naturalHeight;
ratio = Number(ratio);
if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
var newWidth = naturalWidth * ratio;
var newHeight = naturalHeight * ratio;
if (dispatchEvent(this.element, EVENT_ZOOM, {
ratio: ratio,
oldRatio: width / naturalWidth,
originalEvent: _originalEvent
}) === false) {
return this;
}
if (_originalEvent) {
var pointers = this.pointers;
var offset = getOffset(this.cropper);
var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
pageX: _originalEvent.pageX,
pageY: _originalEvent.pageY
}; // Zoom from the triggering point of the event
canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
} else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
} else {
// Zoom from the center of the canvas
canvasData.left -= (newWidth - width) / 2;
canvasData.top -= (newHeight - height) / 2;
}
canvasData.width = newWidth;
canvasData.height = newHeight;
this.renderCanvas(true);
}
return this;
},
/**
* Rotate the canvas with a relative degree
* @param {number} degree - The rotate degree.
* @returns {Cropper} this
*/
rotate: function rotate(degree) {
return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
},
/**
* Rotate the canvas to an absolute degree
* @param {number} degree - The rotate degree.
* @returns {Cropper} this
*/
rotateTo: function rotateTo(degree) {
degree = Number(degree);
if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
this.imageData.rotate = degree % 360;
this.renderCanvas(true, true);
}
return this;
},
/**
* Scale the image on the x-axis.
* @param {number} scaleX - The scale ratio on the x-axis.
* @returns {Cropper} this
*/
scaleX: function scaleX(_scaleX) {
var scaleY = this.imageData.scaleY;
return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
},
/**
* Scale the image on the y-axis.
* @param {number} scaleY - The scale ratio on the y-axis.
* @returns {Cropper} this
*/
scaleY: function scaleY(_scaleY) {
var scaleX = this.imageData.scaleX;
return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
},
/**
* Scale the image
* @param {number} scaleX - The scale ratio on the x-axis.
* @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
* @returns {Cropper} this
*/
scale: function scale(scaleX) {
var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
var imageData = this.imageData;
var transformed = false;
scaleX = Number(scaleX);
scaleY = Number(scaleY);
if (this.ready && !this.disabled && this.options.scalable) {
if (isNumber(scaleX)) {
imageData.scaleX = scaleX;
transformed = true;
}
if (isNumber(scaleY)) {
imageData.scaleY = scaleY;
transformed = true;
}
if (transformed) {
this.renderCanvas(true, true);
}
}
return this;
},
/**
* Get the cropped area position and size data (base on the original image)
* @param {boolean} [rounded=false] - Indicate if round the data values or not.
* @returns {Object} The result cropped data.
*/
getData: function getData() {
var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var options = this.options,
imageData = this.imageData,
canvasData = this.canvasData,
cropBoxData = this.cropBoxData;
var data;
if (this.ready && this.cropped) {
data = {
x: cropBoxData.left - canvasData.left,
y: cropBoxData.top - canvasData.top,
width: cropBoxData.width,
height: cropBoxData.height
};
var ratio = imageData.width / imageData.naturalWidth;
forEach(data, function (n, i) {
data[i] = n / ratio;
});
if (rounded) {
// In case rounding off leads to extra 1px in right or bottom border
// we should round the top-left corner and the dimension (#343).
var bottom = Math.round(data.y + data.height);
var right = Math.round(data.x + data.width);
data.x = Math.round(data.x);
data.y = Math.round(data.y);
data.width = right - data.x;
data.height = bottom - data.y;
}
} else {
data = {
x: 0,
y: 0,
width: 0,
height: 0
};
}
if (options.rotatable) {
data.rotate = imageData.rotate || 0;
}
if (options.scalable) {
data.scaleX = imageData.scaleX || 1;
data.scaleY = imageData.scaleY || 1;
}
return data;
},
/**
* Set the cropped area position and size with new data
* @param {Object} data - The new data.
* @returns {Cropper} this
*/
setData: function setData(data) {
var options = this.options,
imageData = this.imageData,
canvasData = this.canvasData;
var cropBoxData = {};
if (this.ready && !this.disabled && isPlainObject(data)) {
var transformed = false;
if (options.rotatable) {
if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
imageData.rotate = data.rotate;
transformed = true;
}
}
if (options.scalable) {
if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
imageData.scaleX = data.scaleX;
transformed = true;
}
if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
imageData.scaleY = data.scaleY;
transformed = true;
}
}
if (transformed) {
this.renderCanvas(true, true);
}
var ratio = imageData.width / imageData.naturalWidth;
if (isNumber(data.x)) {
cropBoxData.left = data.x * ratio + canvasData.left;
}
if (isNumber(data.y)) {
cropBoxData.top = data.y * ratio + canvasData.top;
}
if (isNumber(data.width)) {
cropBoxData.width = data.width * ratio;
}
if (isNumber(data.height)) {
cropBoxData.height = data.height * ratio;
}
this.setCropBoxData(cropBoxData);
}
return this;
},
/**
* Get the container size data.
* @returns {Object} The result container data.
*/
getContainerData: function getContainerData() {
return this.ready ? assign({}, this.containerData) : {};
},
/**
* Get the image position and size data.
* @returns {Object} The result image data.
*/
getImageData: function getImageData() {
return this.sized ? assign({}, this.imageData) : {};
},
/**
* Get the canvas position and size data.
* @returns {Object} The result canvas data.
*/
getCanvasData: function getCanvasData() {
var canvasData = this.canvasData;
var data = {};
if (this.ready) {
forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
data[n] = canvasData[n];
});
}
return data;
},
/**
* Set the canvas position and size with new data.
* @param {Object} data - The new canvas data.
* @returns {Cropper} this
*/
setCanvasData: function setCanvasData(data) {
var canvasData = this.canvasData;
var aspectRatio = canvasData.aspectRatio;
if (this.ready && !this.disabled && isPlainObject(data)) {
if (isNumber(data.left)) {
canvasData.left = data.left;
}
if (isNumber(data.top)) {
canvasData.top = data.top;
}
if (isNumber(data.width)) {
canvasData.width = data.width;
canvasData.height = data.width / aspectRatio;
} else if (isNumber(data.height)) {
canvasData.height = data.height;
canvasData.width = data.height * aspectRatio;
}
this.renderCanvas(true);
}
return this;
},
/**
* Get the crop box position and size data.
* @returns {Object} The result crop box data.
*/
getCropBoxData: function getCropBoxData() {
var cropBoxData = this.cropBoxData;
var data;
if (this.ready && this.cropped) {
data = {
left: cropBoxData.left,
top: cropBoxData.top,
width: cropBoxData.width,
height: cropBoxData.height
};
}
return data || {};
},
/**
* Set the crop box position and size with new data.
* @param {Object} data - The new crop box data.
* @returns {Cropper} this
*/
setCropBoxData: function setCropBoxData(data) {
var cropBoxData = this.cropBoxData;
var aspectRatio = this.options.aspectRatio;
var widthChanged;
var heightChanged;
if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
if (isNumber(data.left)) {
cropBoxData.left = data.left;
}
if (isNumber(data.top)) {
cropBoxData.top = data.top;
}
if (isNumber(data.width) && data.width !== cropBoxData.width) {
widthChanged = true;
cropBoxData.width = data.width;
}
if (isNumber(data.height) && data.height !== cropBoxData.height) {
heightChanged = true;
cropBoxData.height = data.height;
}
if (aspectRatio) {
if (widthChanged) {
cropBoxData.height = cropBoxData.width / aspectRatio;
} else if (heightChanged) {
cropBoxData.width = cropBoxData.height * aspectRatio;
}
}
this.renderCropBox();
}
return this;
},
/**
* Get a canvas drawn the cropped image.
* @param {Object} [options={}] - The config options.
* @returns {HTMLCanvasElement} - The result canvas.
*/
getCroppedCanvas: function getCroppedCanvas() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!this.ready || !window.HTMLCanvasElement) {
return null;
}
var canvasData = this.canvasData;
var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped.
if (!this.cropped) {
return source;
}
var _this$getData = this.getData(),
initialX = _this$getData.x,
initialY = _this$getData.y,
initialWidth = _this$getData.width,
initialHeight = _this$getData.height;
var ratio = source.width / Math.floor(canvasData.naturalWidth);
if (ratio !== 1) {
initialX *= ratio;
initialY *= ratio;
initialWidth *= ratio;
initialHeight *= ratio;
}
var aspectRatio = initialWidth / initialHeight;
var maxSizes = getAdjustedSizes({
aspectRatio: aspectRatio,
width: options.maxWidth || Infinity,
height: options.maxHeight || Infinity
});
var minSizes = getAdjustedSizes({
aspectRatio: aspectRatio,
width: options.minWidth || 0,
height: options.minHeight || 0
}, 'cover');
var _getAdjustedSizes = getAdjustedSizes({
aspectRatio: aspectRatio,
width: options.width || (ratio !== 1 ? source.width : initialWidth),
height: options.height || (ratio !== 1 ? source.height : initialHeight)
}),
width = _getAdjustedSizes.width,
height = _getAdjustedSizes.height;
width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = normalizeDecimalNumber(width);
canvas.height = normalizeDecimalNumber(height);
context.fillStyle = options.fillColor || 'transparent';
context.fillRect(0, 0, width, height);
var _options$imageSmoothi = options.imageSmoothingEnabled,
imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
imageSmoothingQuality = options.imageSmoothingQuality;
context.imageSmoothingEnabled = imageSmoothingEnabled;
if (imageSmoothingQuality) {
context.imageSmoothingQuality = imageSmoothingQuality;
} // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
var sourceWidth = source.width;
var sourceHeight = source.height; // Source canvas parameters
var srcX = initialX;
var srcY = initialY;
var srcWidth;
var srcHeight; // Destination canvas parameters
var dstX;
var dstY;
var dstWidth;
var dstHeight;
if (srcX <= -initialWidth || srcX > sourceWidth) {
srcX = 0;
srcWidth = 0;
dstX = 0;
dstWidth = 0;
} else if (srcX <= 0) {
dstX = -srcX;
srcX = 0;
srcWidth = Math.min(sourceWidth, initialWidth + srcX);
dstWidth = srcWidth;
} else if (srcX <= sourceWidth) {
dstX = 0;
srcWidth = Math.min(initialWidth, sourceWidth - srcX);
dstWidth = srcWidth;
}
if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
srcY = 0;
srcHeight = 0;
dstY = 0;
dstHeight = 0;
} else if (srcY <= 0) {
dstY = -srcY;
srcY = 0;
srcHeight = Math.min(sourceHeight, initialHeight + srcY);
dstHeight = srcHeight;
} else if (srcY <= sourceHeight) {
dstY = 0;
srcHeight = Math.min(initialHeight, sourceHeight - srcY);
dstHeight = srcHeight;
}
var params = [srcX, srcY, srcWidth, srcHeight]; // Avoid "IndexSizeError"
if (dstWidth > 0 && dstHeight > 0) {
var scale = width / initialWidth;
params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
} // All the numerical parameters should be integer for `drawImage`
// https://github.com/fengyuanchen/cropper/issues/476
context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
return Math.floor(normalizeDecimalNumber(param));
}))));
return canvas;
},
/**
* Change the aspect ratio of the crop box.
* @param {number} aspectRatio - The new aspect ratio.
* @returns {Cropper} this
*/
setAspectRatio: function setAspectRatio(aspectRatio) {
var options = this.options;
if (!this.disabled && !isUndefined(aspectRatio)) {
// 0 -> NaN
options.aspectRatio = Math.max(0, aspectRatio) || NaN;
if (this.ready) {
this.initCropBox();
if (this.cropped) {
this.renderCropBox();
}
}
}
return this;
},
/**
* Change the drag mode.
* @param {string} mode - The new drag mode.
* @returns {Cropper} this
*/
setDragMode: function setDragMode(mode) {
var options = this.options,
dragBox = this.dragBox,
face = this.face;
if (this.ready && !this.disabled) {
var croppable = mode === DRAG_MODE_CROP;
var movable = options.movable && mode === DRAG_MODE_MOVE;
mode = croppable || movable ? mode : DRAG_MODE_NONE;
options.dragMode = mode;
setData(dragBox, DATA_ACTION, mode);
toggleClass(dragBox, CLASS_CROP, croppable);
toggleClass(dragBox, CLASS_MOVE, movable);
if (!options.cropBoxMovable) {
// Sync drag mode to crop box when it is not movable
setData(face, DATA_ACTION, mode);
toggleClass(face, CLASS_CROP, croppable);
toggleClass(face, CLASS_MOVE, movable);
}
}
return this;
}
};
var AnotherCropper = WINDOW.Cropper;
var Cropper = /*#__PURE__*/function () {
/**
* Create a new Cropper.
* @param {Element} element - The target element for cropping.
* @param {Object} [options={}] - The configuration options.
*/
function Cropper(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Cropper);
if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
throw new Error('The first argument is required and must be an <img> or <canvas> element.');
}
this.element = element;
this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
this.cropped = false;
this.disabled = false;
this.pointers = {};
this.ready = false;
this.reloading = false;
this.replaced = false;
this.sized = false;
this.sizing = false;
this.init();
}
_createClass(Cropper, [{
key: "init",
value: function init() {
var element = this.element;
var tagName = element.tagName.toLowerCase();
var url;
if (element[NAMESPACE]) {
return;
}
element[NAMESPACE] = this;
if (tagName === 'img') {
this.isImg = true; // e.g.: "img/picture.jpg"
url = element.getAttribute('src') || '';
this.originalUrl = url; // Stop when it's a blank image
if (!url) {
return;
} // e.g.: "https://example.com/img/picture.jpg"
url = element.src;
} else if (tagName === 'canvas' && window.HTMLCanvasElement) {
url = element.toDataURL();
}
this.load(url);
}
}, {
key: "load",
value: function load(url) {
var _this = this;
if (!url) {
return;
}
this.url = url;
this.imageData = {};
var element = this.element,
options = this.options;
if (!options.rotatable && !options.scalable) {
options.checkOrientation = false;
} // Only IE10+ supports Typed Arrays
if (!options.checkOrientation || !window.ArrayBuffer) {
this.clone();
return;
} // Detect the mime type of the image directly if it is a Data URL
if (REGEXP_DATA_URL.test(url)) {
// Read ArrayBuffer from Data URL of JPEG images directly for better performance
if (REGEXP_DATA_URL_JPEG.test(url)) {
this.read(dataURLToArrayBuffer(url));
} else {
// Only a JPEG image may contains Exif Orientation information,
// the rest types of Data URLs are not necessary to check orientation at all.
this.clone();
}
return;
} // 1. Detect the mime type of the image by a XMLHttpRequest.
// 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.
var xhr = new XMLHttpRequest();
var clone = this.clone.bind(this);
this.reloading = true;
this.xhr = xhr; // 1. Cross origin requests are only supported for protocol schemes:
// http, https, data, chrome, chrome-extension.
// 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
// in some browsers as IE11 and Safari.
xhr.onabort = clone;
xhr.onerror = clone;
xhr.ontimeout = clone;
xhr.onprogress = function () {
// Abort the request directly if it not a JPEG image for better performance
if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
xhr.abort();
}
};
xhr.onload = function () {
_this.read(xhr.response);
};
xhr.onloadend = function () {
_this.reloading = false;
_this.xhr = null;
}; // Bust cache when there is a "crossOrigin" property to avoid browser cache error
if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
url = addTimestamp(url);
}
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.withCredentials = element.crossOrigin === 'use-credentials';
xhr.send();
}
}, {
key: "read",
value: function read(arrayBuffer) {
var options = this.options,
imageData = this.imageData; // Reset the orientation value to its default value 1
// as some iOS browsers will render image with its orientation
var orientation = resetAndGetOrientation(arrayBuffer);
var rotate = 0;
var scaleX = 1;
var scaleY = 1;
if (orientation > 1) {
// Generate a new URL which has the default orientation value
this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
var _parseOrientation = parseOrientation(orientation);
rotate = _parseOrientation.rotate;
scaleX = _parseOrientation.scaleX;
scaleY = _parseOrientation.scaleY;
}
if (options.rotatable) {
imageData.rotate = rotate;
}
if (options.scalable) {
imageData.scaleX = scaleX;
imageData.scaleY = scaleY;
}
this.clone();
}
}, {
key: "clone",
value: function clone() {
var element = this.element,
url = this.url;
var crossOrigin = element.crossOrigin;
var crossOriginUrl = url;
if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
if (!crossOrigin) {
crossOrigin = 'anonymous';
} // Bust cache when there is not a "crossOrigin" property (#519)
crossOriginUrl = addTimestamp(url);
}
this.crossOrigin = crossOrigin;
this.crossOriginUrl = crossOriginUrl;
var image = document.createElement('img');
if (crossOrigin) {
image.crossOrigin = crossOrigin;
}
image.src = crossOriginUrl || url;
image.alt = element.alt || 'The image to crop';
this.image = image;
image.onload = this.start.bind(this);
image.onerror = this.stop.bind(this);
addClass(image, CLASS_HIDE);
element.parentNode.insertBefore(image, element.nextSibling);
}
}, {
key: "start",
value: function start() {
var _this2 = this;
var image = this.image;
image.onload = null;
image.onerror = null;
this.sizing = true; // Match all browsers that use WebKit as the layout engine in iOS devices,
// such as Safari for iOS, Chrome for iOS, and in-app browsers.
var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
var done = function done(naturalWidth, naturalHeight) {
assign(_this2.imageData, {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
aspectRatio: naturalWidth / naturalHeight
});
_this2.sizing = false;
_this2.sized = true;
_this2.build();
}; // Most modern browsers (excepts iOS WebKit)
if (image.naturalWidth && !isIOSWebKit) {
done(image.naturalWidth, image.naturalHeight);
return;
}
var sizingImage = document.createElement('img');
var body = document.body || document.documentElement;
this.sizingImage = sizingImage;
sizingImage.onload = function () {
done(sizingImage.width, sizingImage.height);
if (!isIOSWebKit) {
body.removeChild(sizingImage);
}
};
sizingImage.src = image.src; // iOS WebKit will convert the image automatically
// with its orientation once append it into DOM (#279)
if (!isIOSWebKit) {
sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
body.appendChild(sizingImage);
}
}
}, {
key: "stop",
value: function stop() {
var image = this.image;
image.onload = null;
image.onerror = null;
image.parentNode.removeChild(image);
this.image = null;
}
}, {
key: "build",
value: function build() {
if (!this.sized || this.ready) {
return;
}
var element = this.element,
options = this.options,
image = this.image; // Create cropper elements
var container = element.parentNode;
var template = document.createElement('div');
template.innerHTML = TEMPLATE;
var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));
var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));
var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));
var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));
var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));
this.container = container;
this.cropper = cropper;
this.canvas = canvas;
this.dragBox = dragBox;
this.cropBox = cropBox;
this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
this.face = face;
canvas.appendChild(image); // Hide the original image
addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image
container.insertBefore(cropper, element.nextSibling); // Show the image if is hidden
if (!this.isImg) {
removeClass(image, CLASS_HIDE);
}
this.initPreview();
this.bind();
options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
addClass(cropBox, CLASS_HIDDEN);
if (!options.guides) {
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
}
if (!options.center) {
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
}
if (options.background) {
addClass(cropper, "".concat(NAMESPACE, "-bg"));
}
if (!options.highlight) {
addClass(face, CLASS_INVISIBLE);
}
if (options.cropBoxMovable) {
addClass(face, CLASS_MOVE);
setData(face, DATA_ACTION, ACTION_ALL);
}
if (!options.cropBoxResizable) {
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
}
this.render();
this.ready = true;
this.setDragMode(options.dragMode);
if (options.autoCrop) {
this.crop();
}
this.setData(options.data);
if (isFunction(options.ready)) {
addListener(element, EVENT_READY, options.ready, {
once: true
});
}
dispatchEvent(element, EVENT_READY);
}
}, {
key: "unbuild",
value: function unbuild() {
if (!this.ready) {
return;
}
this.ready = false;
this.unbind();
this.resetPreview();
this.cropper.parentNode.removeChild(this.cropper);
removeClass(this.element, CLASS_HIDDEN);
}
}, {
key: "uncreate",
value: function uncreate() {
if (this.ready) {
this.unbuild();
this.ready = false;
this.cropped = false;
} else if (this.sizing) {
this.sizingImage.onload = null;
this.sizing = false;
this.sized = false;
} else if (this.reloading) {
this.xhr.onabort = null;
this.xhr.abort();
} else if (this.image) {
this.stop();
}
}
/**
* Get the no conflict cropper class.
* @returns {Cropper} The cropper class.
*/
}], [{
key: "noConflict",
value: function noConflict() {
window.Cropper = AnotherCropper;
return Cropper;
}
/**
* Change the default options.
* @param {Object} options - The new default options.
*/
}, {
key: "setDefaults",
value: function setDefaults(options) {
assign(DEFAULTS, isPlainObject(options) && options);
}
}]);
return Cropper;
}();
assign(Cropper.prototype, render, preview, events, handlers, change, methods);
return Cropper;
})));
},{}],15:[function(require,module,exports){
/**
* cuid.js
* Collision-resistant UID generator for browsers and node.
* Sequential for fast db lookups and recency sorting.
* Safe for element IDs and server-side lookups.
*
* Extracted from CLCTR
*
* Copyright (c) Eric Elliott 2012
* MIT License
*/
var fingerprint = require('./lib/fingerprint.js');
var pad = require('./lib/pad.js');
var getRandomValue = require('./lib/getRandomValue.js');
var c = 0,
blockSize = 4,
base = 36,
discreteValues = Math.pow(base, blockSize);
function randomBlock () {
return pad((getRandomValue() *
discreteValues << 0)
.toString(base), blockSize);
}
function safeCounter () {
c = c < discreteValues ? c : 0;
c++; // this is not subliminal
return c - 1;
}
function cuid () {
// Starting with a lowercase letter makes
// it HTML element ID friendly.
var letter = 'c', // hard-coded allows for sequential access
// timestamp
// warning: this exposes the exact date and time
// that the uid was created.
timestamp = (new Date().getTime()).toString(base),
// Prevent same-machine collisions.
counter = pad(safeCounter().toString(base), blockSize),
// A few chars to generate distinct ids for different
// clients (so different computers are far less
// likely to generate the same id)
print = fingerprint(),
// Grab some more chars from Math.random()
random = randomBlock() + randomBlock();
return letter + timestamp + counter + print + random;
}
cuid.slug = function slug () {
var date = new Date().getTime().toString(36),
counter = safeCounter().toString(36).slice(-4),
print = fingerprint().slice(0, 1) +
fingerprint().slice(-1),
random = randomBlock().slice(-2);
return date.slice(-2) +
counter + print + random;
};
cuid.isCuid = function isCuid (stringToCheck) {
if (typeof stringToCheck !== 'string') return false;
if (stringToCheck.startsWith('c')) return true;
return false;
};
cuid.isSlug = function isSlug (stringToCheck) {
if (typeof stringToCheck !== 'string') return false;
var stringLength = stringToCheck.length;
if (stringLength >= 7 && stringLength <= 10) return true;
return false;
};
cuid.fingerprint = fingerprint;
module.exports = cuid;
},{"./lib/fingerprint.js":16,"./lib/getRandomValue.js":17,"./lib/pad.js":18}],16:[function(require,module,exports){
var pad = require('./pad.js');
var env = typeof window === 'object' ? window : self;
var globalCount = Object.keys(env).length;
var mimeTypesLength = navigator.mimeTypes ? navigator.mimeTypes.length : 0;
var clientId = pad((mimeTypesLength +
navigator.userAgent.length).toString(36) +
globalCount.toString(36), 4);
module.exports = function fingerprint () {
return clientId;
};
},{"./pad.js":18}],17:[function(require,module,exports){
var getRandomValue;
var crypto = typeof window !== 'undefined' &&
(window.crypto || window.msCrypto) ||
typeof self !== 'undefined' &&
self.crypto;
if (crypto) {
var lim = Math.pow(2, 32) - 1;
getRandomValue = function () {
return Math.abs(crypto.getRandomValues(new Uint32Array(1))[0] / lim);
};
} else {
getRandomValue = Math.random;
}
module.exports = getRandomValue;
},{}],18:[function(require,module,exports){
module.exports = function pad (num, size) {
var s = '000000000' + num;
return s.substr(s.length - size);
};
},{}],19:[function(require,module,exports){
/**
* Module dependencies.
*/
var keys = require('./keys');
var hasBinary = require('has-binary2');
var sliceBuffer = require('arraybuffer.slice');
var after = require('after');
var utf8 = require('./utf8');
var base64encoder;
if (typeof ArrayBuffer !== 'undefined') {
base64encoder = require('base64-arraybuffer');
}
/**
* Check if we are running an android browser. That requires us to use
* ArrayBuffer with polling transports...
*
* http://ghinda.net/jpeg-blob-ajax-android/
*/
var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);
/**
* Check if we are running in PhantomJS.
* Uploading a Blob with PhantomJS does not work correctly, as reported here:
* https://github.com/ariya/phantomjs/issues/11395
* @type boolean
*/
var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);
/**
* When true, avoids using Blobs to encode payloads.
* @type boolean
*/
var dontSendBlobs = isAndroid || isPhantomJS;
/**
* Current protocol version.
*/
exports.protocol = 3;
/**
* Packet types.
*/
var packets = exports.packets = {
open: 0 // non-ws
, close: 1 // non-ws
, ping: 2
, pong: 3
, message: 4
, upgrade: 5
, noop: 6
};
var packetslist = keys(packets);
/**
* Premade error packet.
*/
var err = { type: 'error', data: 'parser error' };
/**
* Create a blob api even for blob builder when vendor prefixes exist
*/
var Blob = require('blob');
/**
* Encodes a packet.
*
* <packet type id> [ <data> ]
*
* Example:
*
* 5hello world
* 3
* 4
*
* Binary is encoded in an identical principle
*
* @api private
*/
exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
if (typeof supportsBinary === 'function') {
callback = supportsBinary;
supportsBinary = false;
}
if (typeof utf8encode === 'function') {
callback = utf8encode;
utf8encode = null;
}
var data = (packet.data === undefined)
? undefined
: packet.data.buffer || packet.data;
if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) {
return encodeArrayBuffer(packet, supportsBinary, callback);
} else if (typeof Blob !== 'undefined' && data instanceof Blob) {
return encodeBlob(packet, supportsBinary, callback);
}
// might be an object with { base64: true, data: dataAsBase64String }
if (data && data.base64) {
return encodeBase64Object(packet, callback);
}
// Sending data as a utf-8 string
var encoded = packets[packet.type];
// data fragment is optional
if (undefined !== packet.data) {
encoded += utf8encode ? utf8.encode(String(packet.data), { strict: false }) : String(packet.data);
}
return callback('' + encoded);
};
function encodeBase64Object(packet, callback) {
// packet data is an object { base64: true, data: dataAsBase64String }
var message = 'b' + exports.packets[packet.type] + packet.data.data;
return callback(message);
}
/**
* Encode packet helpers for binary types
*/
function encodeArrayBuffer(packet, supportsBinary, callback) {
if (!supportsBinary) {
return exports.encodeBase64Packet(packet, callback);
}
var data = packet.data;
var contentArray = new Uint8Array(data);
var resultBuffer = new Uint8Array(1 + data.byteLength);
resultBuffer[0] = packets[packet.type];
for (var i = 0; i < contentArray.length; i++) {
resultBuffer[i+1] = contentArray[i];
}
return callback(resultBuffer.buffer);
}
function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
if (!supportsBinary) {
return exports.encodeBase64Packet(packet, callback);
}
var fr = new FileReader();
fr.onload = function() {
exports.encodePacket({ type: packet.type, data: fr.result }, supportsBinary, true, callback);
};
return fr.readAsArrayBuffer(packet.data);
}
function encodeBlob(packet, supportsBinary, callback) {
if (!supportsBinary) {
return exports.encodeBase64Packet(packet, callback);
}
if (dontSendBlobs) {
return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
}
var length = new Uint8Array(1);
length[0] = packets[packet.type];
var blob = new Blob([length.buffer, packet.data]);
return callback(blob);
}
/**
* Encodes a packet with binary data in a base64 string
*
* @param {Object} packet, has `type` and `data`
* @return {String} base64 encoded message
*/
exports.encodeBase64Packet = function(packet, callback) {
var message = 'b' + exports.packets[packet.type];
if (typeof Blob !== 'undefined' && packet.data instanceof Blob) {
var fr = new FileReader();
fr.onload = function() {
var b64 = fr.result.split(',')[1];
callback(message + b64);
};
return fr.readAsDataURL(packet.data);
}
var b64data;
try {
b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
} catch (e) {
// iPhone Safari doesn't let you apply with typed arrays
var typed = new Uint8Array(packet.data);
var basic = new Array(typed.length);
for (var i = 0; i < typed.length; i++) {
basic[i] = typed[i];
}
b64data = String.fromCharCode.apply(null, basic);
}
message += btoa(b64data);
return callback(message);
};
/**
* Decodes a packet. Changes format to Blob if requested.
*
* @return {Object} with `type` and `data` (if any)
* @api private
*/
exports.decodePacket = function (data, binaryType, utf8decode) {
if (data === undefined) {
return err;
}
// String data
if (typeof data === 'string') {
if (data.charAt(0) === 'b') {
return exports.decodeBase64Packet(data.substr(1), binaryType);
}
if (utf8decode) {
data = tryDecode(data);
if (data === false) {
return err;
}
}
var type = data.charAt(0);
if (Number(type) != type || !packetslist[type]) {
return err;
}
if (data.length > 1) {
return { type: packetslist[type], data: data.substring(1) };
} else {
return { type: packetslist[type] };
}
}
var asArray = new Uint8Array(data);
var type = asArray[0];
var rest = sliceBuffer(data, 1);
if (Blob && binaryType === 'blob') {
rest = new Blob([rest]);
}
return { type: packetslist[type], data: rest };
};
function tryDecode(data) {
try {
data = utf8.decode(data, { strict: false });
} catch (e) {
return false;
}
return data;
}
/**
* Decodes a packet encoded in a base64 string
*
* @param {String} base64 encoded message
* @return {Object} with `type` and `data` (if any)
*/
exports.decodeBase64Packet = function(msg, binaryType) {
var type = packetslist[msg.charAt(0)];
if (!base64encoder) {
return { type: type, data: { base64: true, data: msg.substr(1) } };
}
var data = base64encoder.decode(msg.substr(1));
if (binaryType === 'blob' && Blob) {
data = new Blob([data]);
}
return { type: type, data: data };
};
/**
* Encodes multiple messages (payload).
*
* <length>:data
*
* Example:
*
* 11:hello world2:hi
*
* If any contents are binary, they will be encoded as base64 strings. Base64
* encoded strings are marked with a b before the length specifier
*
* @param {Array} packets
* @api private
*/
exports.encodePayload = function (packets, supportsBinary, callback) {
if (typeof supportsBinary === 'function') {
callback = supportsBinary;
supportsBinary = null;
}
var isBinary = hasBinary(packets);
if (supportsBinary && isBinary) {
if (Blob && !dontSendBlobs) {
return exports.encodePayloadAsBlob(packets, callback);
}
return exports.encodePayloadAsArrayBuffer(packets, callback);
}
if (!packets.length) {
return callback('0:');
}
function setLengthHeader(message) {
return message.length + ':' + message;
}
function encodeOne(packet, doneCallback) {
exports.encodePacket(packet, !isBinary ? false : supportsBinary, false, function(message) {
doneCallback(null, setLengthHeader(message));
});
}
map(packets, encodeOne, function(err, results) {
return callback(results.join(''));
});
};
/**
* Async array map using after
*/
function map(ary, each, done) {
var result = new Array(ary.length);
var next = after(ary.length, done);
var eachWithIndex = function(i, el, cb) {
each(el, function(error, msg) {
result[i] = msg;
cb(error, result);
});
};
for (var i = 0; i < ary.length; i++) {
eachWithIndex(i, ary[i], next);
}
}
/*
* Decodes data when a payload is maybe expected. Possible binary contents are
* decoded from their base64 representation
*
* @param {String} data, callback method
* @api public
*/
exports.decodePayload = function (data, binaryType, callback) {
if (typeof data !== 'string') {
return exports.decodePayloadAsBinary(data, binaryType, callback);
}
if (typeof binaryType === 'function') {
callback = binaryType;
binaryType = null;
}
var packet;
if (data === '') {
// parser error - ignoring payload
return callback(err, 0, 1);
}
var length = '', n, msg;
for (var i = 0, l = data.length; i < l; i++) {
var chr = data.charAt(i);
if (chr !== ':') {
length += chr;
continue;
}
if (length === '' || (length != (n = Number(length)))) {
// parser error - ignoring payload
return callback(err, 0, 1);
}
msg = data.substr(i + 1, n);
if (length != msg.length) {
// parser error - ignoring payload
return callback(err, 0, 1);
}
if (msg.length) {
packet = exports.decodePacket(msg, binaryType, false);
if (err.type === packet.type && err.data === packet.data) {
// parser error in individual packet - ignoring payload
return callback(err, 0, 1);
}
var ret = callback(packet, i + n, l);
if (false === ret) return;
}
// advance cursor
i += n;
length = '';
}
if (length !== '') {
// parser error - ignoring payload
return callback(err, 0, 1);
}
};
/**
* Encodes multiple messages (payload) as binary.
*
* <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
* 255><data>
*
* Example:
* 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
*
* @param {Array} packets
* @return {ArrayBuffer} encoded payload
* @api private
*/
exports.encodePayloadAsArrayBuffer = function(packets, callback) {
if (!packets.length) {
return callback(new ArrayBuffer(0));
}
function encodeOne(packet, doneCallback) {
exports.encodePacket(packet, true, true, function(data) {
return doneCallback(null, data);
});
}
map(packets, encodeOne, function(err, encodedPackets) {
var totalLength = encodedPackets.reduce(function(acc, p) {
var len;
if (typeof p === 'string'){
len = p.length;
} else {
len = p.byteLength;
}
return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
}, 0);
var resultArray = new Uint8Array(totalLength);
var bufferIndex = 0;
encodedPackets.forEach(function(p) {
var isString = typeof p === 'string';
var ab = p;
if (isString) {
var view = new Uint8Array(p.length);
for (var i = 0; i < p.length; i++) {
view[i] = p.charCodeAt(i);
}
ab = view.buffer;
}
if (isString) { // not true binary
resultArray[bufferIndex++] = 0;
} else { // true binary
resultArray[bufferIndex++] = 1;
}
var lenStr = ab.byteLength.toString();
for (var i = 0; i < lenStr.length; i++) {
resultArray[bufferIndex++] = parseInt(lenStr[i]);
}
resultArray[bufferIndex++] = 255;
var view = new Uint8Array(ab);
for (var i = 0; i < view.length; i++) {
resultArray[bufferIndex++] = view[i];
}
});
return callback(resultArray.buffer);
});
};
/**
* Encode as Blob
*/
exports.encodePayloadAsBlob = function(packets, callback) {
function encodeOne(packet, doneCallback) {
exports.encodePacket(packet, true, true, function(encoded) {
var binaryIdentifier = new Uint8Array(1);
binaryIdentifier[0] = 1;
if (typeof encoded === 'string') {
var view = new Uint8Array(encoded.length);
for (var i = 0; i < encoded.length; i++) {
view[i] = encoded.charCodeAt(i);
}
encoded = view.buffer;
binaryIdentifier[0] = 0;
}
var len = (encoded instanceof ArrayBuffer)
? encoded.byteLength
: encoded.size;
var lenStr = len.toString();
var lengthAry = new Uint8Array(lenStr.length + 1);
for (var i = 0; i < lenStr.length; i++) {
lengthAry[i] = parseInt(lenStr[i]);
}
lengthAry[lenStr.length] = 255;
if (Blob) {
var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
doneCallback(null, blob);
}
});
}
map(packets, encodeOne, function(err, results) {
return callback(new Blob(results));
});
};
/*
* Decodes data when a payload is maybe expected. Strings are decoded by
* interpreting each byte as a key code for entries marked to start with 0. See
* description of encodePayloadAsBinary
*
* @param {ArrayBuffer} data, callback method
* @api public
*/
exports.decodePayloadAsBinary = function (data, binaryType, callback) {
if (typeof binaryType === 'function') {
callback = binaryType;
binaryType = null;
}
var bufferTail = data;
var buffers = [];
while (bufferTail.byteLength > 0) {
var tailArray = new Uint8Array(bufferTail);
var isString = tailArray[0] === 0;
var msgLength = '';
for (var i = 1; ; i++) {
if (tailArray[i] === 255) break;
// 310 = char length of Number.MAX_VALUE
if (msgLength.length > 310) {
return callback(err, 0, 1);
}
msgLength += tailArray[i];
}
bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
msgLength = parseInt(msgLength);
var msg = sliceBuffer(bufferTail, 0, msgLength);
if (isString) {
try {
msg = String.fromCharCode.apply(null, new Uint8Array(msg));
} catch (e) {
// iPhone Safari doesn't let you apply to typed arrays
var typed = new Uint8Array(msg);
msg = '';
for (var i = 0; i < typed.length; i++) {
msg += String.fromCharCode(typed[i]);
}
}
}
buffers.push(msg);
bufferTail = sliceBuffer(bufferTail, msgLength);
}
var total = buffers.length;
buffers.forEach(function(buffer, i) {
callback(exports.decodePacket(buffer, binaryType, true), i, total);
});
};
},{"./keys":20,"./utf8":21,"after":3,"arraybuffer.slice":4,"base64-arraybuffer":6,"blob":8,"has-binary2":26}],20:[function(require,module,exports){
/**
* Gets the keys for an object.
*
* @return {Array} keys
* @api private
*/
module.exports = Object.keys || function keys (obj){
var arr = [];
var has = Object.prototype.hasOwnProperty;
for (var i in obj) {
if (has.call(obj, i)) {
arr.push(i);
}
}
return arr;
};
},{}],21:[function(require,module,exports){
/*! https://mths.be/utf8js v2.1.2 by @mathias */
var stringFromCharCode = String.fromCharCode;
// Taken from https://mths.be/punycode
function ucs2decode(string) {
var output = [];
var counter = 0;
var length = string.length;
var value;
var extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
// high surrogate, and there is a next character
extra = string.charCodeAt(counter++);
if ((extra & 0xFC00) == 0xDC00) { // low surrogate
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
} else {
// unmatched surrogate; only append this code unit, in case the next
// code unit is the high surrogate of a surrogate pair
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
// Taken from https://mths.be/punycode
function ucs2encode(array) {
var length = array.length;
var index = -1;
var value;
var output = '';
while (++index < length) {
value = array[index];
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
}
return output;
}
function checkScalarValue(codePoint, strict) {
if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
if (strict) {
throw Error(
'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
' is not a scalar value'
);
}
return false;
}
return true;
}
/*--------------------------------------------------------------------------*/
function createByte(codePoint, shift) {
return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
}
function encodeCodePoint(codePoint, strict) {
if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
return stringFromCharCode(codePoint);
}
var symbol = '';
if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
}
else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
if (!checkScalarValue(codePoint, strict)) {
codePoint = 0xFFFD;
}
symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
symbol += createByte(codePoint, 6);
}
else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
symbol += createByte(codePoint, 12);
symbol += createByte(codePoint, 6);
}
symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
return symbol;
}
function utf8encode(string, opts) {
opts = opts || {};
var strict = false !== opts.strict;
var codePoints = ucs2decode(string);
var length = codePoints.length;
var index = -1;
var codePoint;
var byteString = '';
while (++index < length) {
codePoint = codePoints[index];
byteString += encodeCodePoint(codePoint, strict);
}
return byteString;
}
/*--------------------------------------------------------------------------*/
function readContinuationByte() {
if (byteIndex >= byteCount) {
throw Error('Invalid byte index');
}
var continuationByte = byteArray[byteIndex] & 0xFF;
byteIndex++;
if ((continuationByte & 0xC0) == 0x80) {
return continuationByte & 0x3F;
}
// If we end up here, it’s not a continuation byte
throw Error('Invalid continuation byte');
}
function decodeSymbol(strict) {
var byte1;
var byte2;
var byte3;
var byte4;
var codePoint;
if (byteIndex > byteCount) {
throw Error('Invalid byte index');
}
if (byteIndex == byteCount) {
return false;
}
// Read first byte
byte1 = byteArray[byteIndex] & 0xFF;
byteIndex++;
// 1-byte sequence (no continuation bytes)
if ((byte1 & 0x80) == 0) {
return byte1;
}
// 2-byte sequence
if ((byte1 & 0xE0) == 0xC0) {
byte2 = readContinuationByte();
codePoint = ((byte1 & 0x1F) << 6) | byte2;
if (codePoint >= 0x80) {
return codePoint;
} else {
throw Error('Invalid continuation byte');
}
}
// 3-byte sequence (may include unpaired surrogates)
if ((byte1 & 0xF0) == 0xE0) {
byte2 = readContinuationByte();
byte3 = readContinuationByte();
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
if (codePoint >= 0x0800) {
return checkScalarValue(codePoint, strict) ? codePoint : 0xFFFD;
} else {
throw Error('Invalid continuation byte');
}
}
// 4-byte sequence
if ((byte1 & 0xF8) == 0xF0) {
byte2 = readContinuationByte();
byte3 = readContinuationByte();
byte4 = readContinuationByte();
codePoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0C) |
(byte3 << 0x06) | byte4;
if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
return codePoint;
}
}
throw Error('Invalid UTF-8 detected');
}
var byteArray;
var byteCount;
var byteIndex;
function utf8decode(byteString, opts) {
opts = opts || {};
var strict = false !== opts.strict;
byteArray = ucs2decode(byteString);
byteCount = byteArray.length;
byteIndex = 0;
var codePoints = [];
var tmp;
while ((tmp = decodeSymbol(strict)) !== false) {
codePoints.push(tmp);
}
return ucs2encode(codePoints);
}
module.exports = {
version: '2.1.2',
encode: utf8encode,
decode: utf8decode
};
},{}],22:[function(require,module,exports){
// This file can be required in Browserify and Node.js for automatic polyfill
// To use it: require('es6-promise/auto');
'use strict';
module.exports = require('./').polyfill();
},{"./":23}],23:[function(require,module,exports){
(function (process,global){(function (){
/*!
* @overview es6-promise - a tiny implementation of Promises/A+.
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
* @license Licensed under MIT license
* See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
* @version v4.2.8+1e68dce6
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.ES6Promise = factory());
}(this, (function () { 'use strict';
function objectOrFunction(x) {
var type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
function isFunction(x) {
return typeof x === 'function';
}
var _isArray = void 0;
if (Array.isArray) {
_isArray = Array.isArray;
} else {
_isArray = function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
};
}
var isArray = _isArray;
var len = 0;
var vertxNext = void 0;
var customSchedulerFn = void 0;
var asap = function asap(callback, arg) {
queue[len] = callback;
queue[len + 1] = arg;
len += 2;
if (len === 2) {
// If len is 2, that means that we need to schedule an async flush.
// If additional callbacks are queued before the queue is flushed, they
// will be processed by this flush that we are scheduling.
if (customSchedulerFn) {
customSchedulerFn(flush);
} else {
scheduleFlush();
}
}
};
function setScheduler(scheduleFn) {
customSchedulerFn = scheduleFn;
}
function setAsap(asapFn) {
asap = asapFn;
}
var browserWindow = typeof window !== 'undefined' ? window : undefined;
var browserGlobal = browserWindow || {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
// node
function useNextTick() {
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
// see https://github.com/cujojs/when/issues/410 for details
return function () {
return process.nextTick(flush);
};
}
// vertx
function useVertxTimer() {
if (typeof vertxNext !== 'undefined') {
return function () {
vertxNext(flush);
};
}
return useSetTimeout();
}
function useMutationObserver() {
var iterations = 0;
var observer = new BrowserMutationObserver(flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function () {
node.data = iterations = ++iterations % 2;
};
}
// web worker
function useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = flush;
return function () {
return channel.port2.postMessage(0);
};
}
function useSetTimeout() {
// Store setTimeout reference so es6-promise will be unaffected by
// other code modifying setTimeout (like sinon.useFakeTimers())
var globalSetTimeout = setTimeout;
return function () {
return globalSetTimeout(flush, 1);
};
}
var queue = new Array(1000);
function flush() {
for (var i = 0; i < len; i += 2) {
var callback = queue[i];
var arg = queue[i + 1];
callback(arg);
queue[i] = undefined;
queue[i + 1] = undefined;
}
len = 0;
}
function attemptVertx() {
try {
var vertx = Function('return this')().require('vertx');
vertxNext = vertx.runOnLoop || vertx.runOnContext;
return useVertxTimer();
} catch (e) {
return useSetTimeout();
}
}
var scheduleFlush = void 0;
// Decide what async method to use to triggering processing of queued callbacks:
if (isNode) {
scheduleFlush = useNextTick();
} else if (BrowserMutationObserver) {
scheduleFlush = useMutationObserver();
} else if (isWorker) {
scheduleFlush = useMessageChannel();
} else if (browserWindow === undefined && typeof require === 'function') {
scheduleFlush = attemptVertx();
} else {
scheduleFlush = useSetTimeout();
}
function then(onFulfillment, onRejection) {
var parent = this;
var child = new this.constructor(noop);
if (child[PROMISE_ID] === undefined) {
makePromise(child);
}
var _state = parent._state;
if (_state) {
var callback = arguments[_state - 1];
asap(function () {
return invokeCallback(_state, child, callback, parent._result);
});
} else {
subscribe(parent, child, onFulfillment, onRejection);
}
return child;
}
/**
`Promise.resolve` returns a promise that will become resolved with the
passed `value`. It is shorthand for the following:
```javascript
let promise = new Promise(function(resolve, reject){
resolve(1);
});
promise.then(function(value){
// value === 1
});
```
Instead of writing the above, your code now simply becomes the following:
```javascript
let promise = Promise.resolve(1);
promise.then(function(value){
// value === 1
});
```
@method resolve
@static
@param {Any} value value that the returned promise will be resolved with
Useful for tooling.
@return {Promise} a promise that will become fulfilled with the given
`value`
*/
function resolve$1(object) {
/*jshint validthis:true */
var Constructor = this;
if (object && typeof object === 'object' && object.constructor === Constructor) {
return object;
}
var promise = new Constructor(noop);
resolve(promise, object);
return promise;
}
var PROMISE_ID = Math.random().toString(36).substring(2);
function noop() {}
var PENDING = void 0;
var FULFILLED = 1;
var REJECTED = 2;
function selfFulfillment() {
return new TypeError("You cannot resolve a promise with itself");
}
function cannotReturnOwn() {
return new TypeError('A promises callback cannot return that same promise.');
}
function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
try {
then$$1.call(value, fulfillmentHandler, rejectionHandler);
} catch (e) {
return e;
}
}
function handleForeignThenable(promise, thenable, then$$1) {
asap(function (promise) {
var sealed = false;
var error = tryThen(then$$1, thenable, function (value) {
if (sealed) {
return;
}
sealed = true;
if (thenable !== value) {
resolve(promise, value);
} else {
fulfill(promise, value);
}
}, function (reason) {
if (sealed) {
return;
}
sealed = true;
reject(promise, reason);
}, 'Settle: ' + (promise._label || ' unknown promise'));
if (!sealed && error) {
sealed = true;
reject(promise, error);
}
}, promise);
}
function handleOwnThenable(promise, thenable) {
if (thenable._state === FULFILLED) {
fulfill(promise, thenable._result);
} else if (thenable._state === REJECTED) {
reject(promise, thenable._result);
} else {
subscribe(thenable, undefined, function (value) {
return resolve(promise, value);
}, function (reason) {
return reject(promise, reason);
});
}
}
function handleMaybeThenable(promise, maybeThenable, then$$1) {
if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
handleOwnThenable(promise, maybeThenable);
} else {
if (then$$1 === undefined) {
fulfill(promise, maybeThenable);
} else if (isFunction(then$$1)) {
handleForeignThenable(promise, maybeThenable, then$$1);
} else {
fulfill(promise, maybeThenable);
}
}
}
function resolve(promise, value) {
if (promise === value) {
reject(promise, selfFulfillment());
} else if (objectOrFunction(value)) {
var then$$1 = void 0;
try {
then$$1 = value.then;
} catch (error) {
reject(promise, error);
return;
}
handleMaybeThenable(promise, value, then$$1);
} else {
fulfill(promise, value);
}
}
function publishRejection(promise) {
if (promise._onerror) {
promise._onerror(promise._result);
}
publish(promise);
}
function fulfill(promise, value) {
if (promise._state !== PENDING) {
return;
}
promise._result = value;
promise._state = FULFILLED;
if (promise._subscribers.length !== 0) {
asap(publish, promise);
}
}
function reject(promise, reason) {
if (promise._state !== PENDING) {
return;
}
promise._state = REJECTED;
promise._result = reason;
asap(publishRejection, promise);
}
function subscribe(parent, child, onFulfillment, onRejection) {
var _subscribers = parent._subscribers;
var length = _subscribers.length;
parent._onerror = null;
_subscribers[length] = child;
_subscribers[length + FULFILLED] = onFulfillment;
_subscribers[length + REJECTED] = onRejection;
if (length === 0 && parent._state) {
asap(publish, parent);
}
}
function publish(promise) {
var subscribers = promise._subscribers;
var settled = promise._state;
if (subscribers.length === 0) {
return;
}
var child = void 0,
callback = void 0,
detail = promise._result;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
if (child) {
invokeCallback(settled, child, callback, detail);
} else {
callback(detail);
}
}
promise._subscribers.length = 0;
}
function invokeCallback(settled, promise, callback, detail) {
var hasCallback = isFunction(callback),
value = void 0,
error = void 0,
succeeded = true;
if (hasCallback) {
try {
value = callback(detail);
} catch (e) {
succeeded = false;
error = e;
}
if (promise === value) {
reject(promise, cannotReturnOwn());
return;
}
} else {
value = detail;
}
if (promise._state !== PENDING) {
// noop
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (succeeded === false) {
reject(promise, error);
} else if (settled === FULFILLED) {
fulfill(promise, value);
} else if (settled === REJECTED) {
reject(promise, value);
}
}
function initializePromise(promise, resolver) {
try {
resolver(function resolvePromise(value) {
resolve(promise, value);
}, function rejectPromise(reason) {
reject(promise, reason);
});
} catch (e) {
reject(promise, e);
}
}
var id = 0;
function nextId() {
return id++;
}
function makePromise(promise) {
promise[PROMISE_ID] = id++;
promise._state = undefined;
promise._result = undefined;
promise._subscribers = [];
}
function validationError() {
return new Error('Array Methods must be provided an Array');
}
var Enumerator = function () {
function Enumerator(Constructor, input) {
this._instanceConstructor = Constructor;
this.promise = new Constructor(noop);
if (!this.promise[PROMISE_ID]) {
makePromise(this.promise);
}
if (isArray(input)) {
this.length = input.length;
this._remaining = input.length;
this._result = new Array(this.length);
if (this.length === 0) {
fulfill(this.promise, this._result);
} else {
this.length = this.length || 0;
this._enumerate(input);
if (this._remaining === 0) {
fulfill(this.promise, this._result);
}
}
} else {
reject(this.promise, validationError());
}
}
Enumerator.prototype._enumerate = function _enumerate(input) {
for (var i = 0; this._state === PENDING && i < input.length; i++) {
this._eachEntry(input[i], i);
}
};
Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
var c = this._instanceConstructor;
var resolve$$1 = c.resolve;
if (resolve$$1 === resolve$1) {
var _then = void 0;
var error = void 0;
var didError = false;
try {
_then = entry.then;
} catch (e) {
didError = true;
error = e;
}
if (_then === then && entry._state !== PENDING) {
this._settledAt(entry._state, i, entry._result);
} else if (typeof _then !== 'function') {
this._remaining--;
this._result[i] = entry;
} else if (c === Promise$1) {
var promise = new c(noop);
if (didError) {
reject(promise, error);
} else {
handleMaybeThenable(promise, entry, _then);
}
this._willSettleAt(promise, i);
} else {
this._willSettleAt(new c(function (resolve$$1) {
return resolve$$1(entry);
}), i);
}
} else {
this._willSettleAt(resolve$$1(entry), i);
}
};
Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
var promise = this.promise;
if (promise._state === PENDING) {
this._remaining--;
if (state === REJECTED) {
reject(promise, value);
} else {
this._result[i] = value;
}
}
if (this._remaining === 0) {
fulfill(promise, this._result);
}
};
Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
var enumerator = this;
subscribe(promise, undefined, function (value) {
return enumerator._settledAt(FULFILLED, i, value);
}, function (reason) {
return enumerator._settledAt(REJECTED, i, reason);
});
};
return Enumerator;
}();
/**
`Promise.all` accepts an array of promises, and returns a new promise which
is fulfilled with an array of fulfillment values for the passed promises, or
rejected with the reason of the first passed promise to be rejected. It casts all
elements of the passed iterable to promises as it runs this algorithm.
Example:
```javascript
let promise1 = resolve(1);
let promise2 = resolve(2);
let promise3 = resolve(3);
let promises = [ promise1, promise2, promise3 ];
Promise.all(promises).then(function(array){
// The array here would be [ 1, 2, 3 ];
});
```
If any of the `promises` given to `all` are rejected, the first promise
that is rejected will be given as an argument to the returned promises's
rejection handler. For example:
Example:
```javascript
let promise1 = resolve(1);
let promise2 = reject(new Error("2"));
let promise3 = reject(new Error("3"));
let promises = [ promise1, promise2, promise3 ];
Promise.all(promises).then(function(array){
// Code here never runs because there are rejected promises!
}, function(error) {
// error.message === "2"
});
```
@method all
@static
@param {Array} entries array of promises
@param {String} label optional string for labeling the promise.
Useful for tooling.
@return {Promise} promise that is fulfilled when all `promises` have been
fulfilled, or rejected if any of them become rejected.
@static
*/
function all(entries) {
return new Enumerator(this, entries).promise;
}
/**
`Promise.race` returns a new promise which is settled in the same way as the
first passed promise to settle.
Example:
```javascript
let promise1 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('promise 1');
}, 200);
});
let promise2 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('promise 2');
}, 100);
});
Promise.race([promise1, promise2]).then(function(result){
// result === 'promise 2' because it was resolved before promise1
// was resolved.
});
```
`Promise.race` is deterministic in that only the state of the first
settled promise matters. For example, even if other promises given to the
`promises` array argument are resolved, but the first settled promise has
become rejected before the other promises became fulfilled, the returned
promise will become rejected:
```javascript
let promise1 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('promise 1');
}, 200);
});
let promise2 = new Promise(function(resolve, reject){
setTimeout(function(){
reject(new Error('promise 2'));
}, 100);
});
Promise.race([promise1, promise2]).then(function(result){
// Code here never runs
}, function(reason){
// reason.message === 'promise 2' because promise 2 became rejected before
// promise 1 became fulfilled
});
```
An example real-world use case is implementing timeouts:
```javascript
Promise.race([ajax('foo.json'), timeout(5000)])
```
@method race
@static
@param {Array} promises array of promises to observe
Useful for tooling.
@return {Promise} a promise which settles in the same way as the first passed
promise to settle.
*/
function race(entries) {
/*jshint validthis:true */
var Constructor = this;
if (!isArray(entries)) {
return new Constructor(function (_, reject) {
return reject(new TypeError('You must pass an array to race.'));
});
} else {
return new Constructor(function (resolve, reject) {
var length = entries.length;
for (var i = 0; i < length; i++) {
Constructor.resolve(entries[i]).then(resolve, reject);
}
});
}
}
/**
`Promise.reject` returns a promise rejected with the passed `reason`.
It is shorthand for the following:
```javascript
let promise = new Promise(function(resolve, reject){
reject(new Error('WHOOPS'));
});
promise.then(function(value){
// Code here doesn't run because the promise is rejected!
}, function(reason){
// reason.message === 'WHOOPS'
});
```
Instead of writing the above, your code now simply becomes the following:
```javascript
let promise = Promise.reject(new Error('WHOOPS'));
promise.then(function(value){
// Code here doesn't run because the promise is rejected!
}, function(reason){
// reason.message === 'WHOOPS'
});
```
@method reject
@static
@param {Any} reason value that the returned promise will be rejected with.
Useful for tooling.
@return {Promise} a promise rejected with the given `reason`.
*/
function reject$1(reason) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(noop);
reject(promise, reason);
return promise;
}
function needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
function needsNew() {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
/**
Promise objects represent the eventual result of an asynchronous operation. The
primary way of interacting with a promise is through its `then` method, which
registers callbacks to receive either a promise's eventual value or the reason
why the promise cannot be fulfilled.
Terminology
-----------
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- `thenable` is an object or function that defines a `then` method.
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- `exception` is a value that is thrown using the throw statement.
- `reason` is a value that indicates why a promise was rejected.
- `settled` the final resting state of a promise, fulfilled or rejected.
A promise can be in one of three states: pending, fulfilled, or rejected.
Promises that are fulfilled have a fulfillment value and are in the fulfilled
state. Promises that are rejected have a rejection reason and are in the
rejected state. A fulfillment value is never a thenable.
Promises can also be said to *resolve* a value. If this value is also a
promise, then the original promise's settled state will match the value's
settled state. So a promise that *resolves* a promise that rejects will
itself reject, and a promise that *resolves* a promise that fulfills will
itself fulfill.
Basic Usage:
------------
```js
let promise = new Promise(function(resolve, reject) {
// on success
resolve(value);
// on failure
reject(reason);
});
promise.then(function(value) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Advanced Usage:
---------------
Promises shine when abstracting away asynchronous interactions such as
`XMLHttpRequest`s.
```js
function getJSON(url) {
return new Promise(function(resolve, reject){
let xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
}
}
};
});
}
getJSON('/posts.json').then(function(json) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
});
```
@class Promise
@param {Function} resolver
Useful for tooling.
@constructor
*/
var Promise$1 = function () {
function Promise(resolver) {
this[PROMISE_ID] = nextId();
this._result = this._state = undefined;
this._subscribers = [];
if (noop !== resolver) {
typeof resolver !== 'function' && needsResolver();
this instanceof Promise ? initializePromise(this, resolver) : needsNew();
}
}
/**
The primary way of interacting with a promise is through its `then` method,
which registers callbacks to receive either a promise's eventual value or the
reason why the promise cannot be fulfilled.
```js
findUser().then(function(user){
// user is available
}, function(reason){
// user is unavailable, and you are given the reason why
});
```
Chaining
--------
The return value of `then` is itself a promise. This second, 'downstream'
promise is resolved with the return value of the first promise's fulfillment
or rejection handler, or rejected if the handler throws an exception.
```js
findUser().then(function (user) {
return user.name;
}, function (reason) {
return 'default name';
}).then(function (userName) {
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
// will be `'default name'`
});
findUser().then(function (user) {
throw new Error('Found user, but still unhappy');
}, function (reason) {
throw new Error('`findUser` rejected and we're unhappy');
}).then(function (value) {
// never reached
}, function (reason) {
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
});
```
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
```js
findUser().then(function (user) {
throw new PedagogicalException('Upstream error');
}).then(function (value) {
// never reached
}).then(function (value) {
// never reached
}, function (reason) {
// The `PedgagocialException` is propagated all the way down to here
});
```
Assimilation
------------
Sometimes the value you want to propagate to a downstream promise can only be
retrieved asynchronously. This can be achieved by returning a promise in the
fulfillment or rejection handler. The downstream promise will then be pending
until the returned promise is settled. This is called *assimilation*.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// The user's comments are now available
});
```
If the assimliated promise rejects, then the downstream promise will also reject.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// If `findCommentsByAuthor` fulfills, we'll have the value here
}, function (reason) {
// If `findCommentsByAuthor` rejects, we'll have the reason here
});
```
Simple Example
--------------
Synchronous Example
```javascript
let result;
try {
result = findResult();
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
findResult(function(result, err){
if (err) {
// failure
} else {
// success
}
});
```
Promise Example;
```javascript
findResult().then(function(result){
// success
}, function(reason){
// failure
});
```
Advanced Example
--------------
Synchronous Example
```javascript
let author, books;
try {
author = findAuthor();
books = findBooksByAuthor(author);
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
function foundBooks(books) {
}
function failure(reason) {
}
findAuthor(function(author, err){
if (err) {
failure(err);
// failure
} else {
try {
findBoooksByAuthor(author, function(books, err) {
if (err) {
failure(err);
} else {
try {
foundBooks(books);
} catch(reason) {
failure(reason);
}
}
});
} catch(error) {
failure(err);
}
// success
}
});
```
Promise Example;
```javascript
findAuthor().
then(findBooksByAuthor).
then(function(books){
// found books
}).catch(function(reason){
// something went wrong
});
```
@method then
@param {Function} onFulfilled
@param {Function} onRejected
Useful for tooling.
@return {Promise}
*/
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
as the catch block of a try/catch statement.
```js
function findAuthor(){
throw new Error('couldn't find that author');
}
// synchronous
try {
findAuthor();
} catch(reason) {
// something went wrong
}
// async with promises
findAuthor().catch(function(reason){
// something went wrong
});
```
@method catch
@param {Function} onRejection
Useful for tooling.
@return {Promise}
*/
Promise.prototype.catch = function _catch(onRejection) {
return this.then(null, onRejection);
};
/**
`finally` will be invoked regardless of the promise's fate just as native
try/catch/finally behaves
Synchronous example:
```js
findAuthor() {
if (Math.random() > 0.5) {
throw new Error();
}
return new Author();
}
try {
return findAuthor(); // succeed or fail
} catch(error) {
return findOtherAuther();
} finally {
// always runs
// doesn't affect the return value
}
```
Asynchronous example:
```js
findAuthor().catch(function(reason){
return findOtherAuther();
}).finally(function(){
// author was either found, or not
});
```
@method finally
@param {Function} callback
@return {Promise}
*/
Promise.prototype.finally = function _finally(callback) {
var promise = this;
var constructor = promise.constructor;
if (isFunction(callback)) {
return promise.then(function (value) {
return constructor.resolve(callback()).then(function () {
return value;
});
}, function (reason) {
return constructor.resolve(callback()).then(function () {
throw reason;
});
});
}
return promise.then(callback, callback);
};
return Promise;
}();
Promise$1.prototype.then = then;
Promise$1.all = all;
Promise$1.race = race;
Promise$1.resolve = resolve$1;
Promise$1.reject = reject$1;
Promise$1._setScheduler = setScheduler;
Promise$1._setAsap = setAsap;
Promise$1._asap = asap;
/*global self*/
function polyfill() {
var local = void 0;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
var P = local.Promise;
if (P) {
var promiseToString = null;
try {
promiseToString = Object.prototype.toString.call(P.resolve());
} catch (e) {
// silently ignored
}
if (promiseToString === '[object Promise]' && !P.cast) {
return;
}
}
local.Promise = Promise$1;
}
// Strange compat..
Promise$1.polyfill = polyfill;
Promise$1.Promise = Promise$1;
return Promise$1;
})));
}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"_process":39}],24:[function(require,module,exports){
(function (process,global,Buffer){(function (){
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define("exifr",["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).exifr={})}(this,(function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function r(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}});var n=["prototype","__proto__","caller","arguments","length","name"];Object.getOwnPropertyNames(t).forEach((function(r){-1===n.indexOf(r)&&e[r]!==t[r]&&(e[r]=t[r])})),t&&u(e,t)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){return(u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function o(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function f(e,t,n){return(f=o()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&u(i,n.prototype),i}).apply(null,arguments)}function c(e){var t="function"==typeof Map?new Map:void 0;return(c=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return f(e,arguments,s(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),u(r,e)})(e)}function h(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function l(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?h(e):t}function d(e){var t=o();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}function v(e,t,n){return(v="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(e,t,n){var r=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=s(e)););return e}(e,t);if(r){var i=Object.getOwnPropertyDescriptor(r,t);return i.get?i.get.call(n):i.value}})(e,t,n||e)}var p=Object.values||function(e){var t=[];for(var n in e)t.push(e[n]);return t},y=Object.entries||function(e){var t=[];for(var n in e)t.push([n,e[n]]);return t},g=Object.assign||function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];return n.forEach((function(t){for(var n in t)e[n]=t[n]})),e},k=Object.fromEntries||function(e){var t={};return m(e).forEach((function(e){var n=e[0],r=e[1];t[n]=r})),t},m=Array.from||function(e){if(e instanceof P){var t=[];return e.forEach((function(e,n){return t.push([n,e])})),t}return Array.prototype.slice.call(e)};function b(e){return-1!==this.indexOf(e)}Array.prototype.includes||(Array.prototype.includes=b),String.prototype.includes||(String.prototype.includes=b),String.prototype.startsWith||(String.prototype.startsWith=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return this.substring(t,t+e.length)===e}),String.prototype.endsWith||(String.prototype.endsWith=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.length;return this.substring(t-e.length,t)===e});var A="undefined"!=typeof self?self:global,w=A.fetch||function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise((function(n,r){var i=new XMLHttpRequest;if(i.open("get",e,!0),i.responseType="arraybuffer",i.onerror=r,t.headers)for(var a in t.headers)i.setRequestHeader(a,t.headers[a]);i.onload=function(){n({ok:i.status>=200&&i.status<300,status:i.status,arrayBuffer:function(){return Promise.resolve(i.response)}})},i.send(null)}))},O=function(e){var t=[];if(Object.defineProperties(t,{size:{get:function(){return this.length}},has:{value:function(e){return-1!==this.indexOf(e)}},add:{value:function(e){this.has(e)||this.push(e)}},delete:{value:function(e){if(this.has(e)){var t=this.indexOf(e);this.splice(t,1)}}}}),Array.isArray(e))for(var n=0;n<e.length;n++)t.add(e[n]);return t},S=function(e){return new P(e)},P=void 0!==A.Map&&void 0!==A.Map.prototype.keys?A.Map:function(){function e(n){if(t(this,e),this.clear(),n)for(var r=0;r<n.length;r++)this.set(n[r][0],n[r][1])}return r(e,[{key:"clear",value:function(){this._map={},this._keys=[]}},{key:"size",get:function(){return this._keys.length}},{key:"get",value:function(e){return this._map["map_"+e]}},{key:"set",value:function(e,t){return this._map["map_"+e]=t,this._keys.indexOf(e)<0&&this._keys.push(e),this}},{key:"has",value:function(e){return this._keys.indexOf(e)>=0}},{key:"delete",value:function(e){var t=this._keys.indexOf(e);return!(t<0)&&(delete this._map["map_"+e],this._keys.splice(t,1),!0)}},{key:"keys",value:function(){return this._keys.slice(0)}},{key:"values",value:function(){var e=this;return this._keys.map((function(t){return e.get(t)}))}},{key:"entries",value:function(){var e=this;return this._keys.map((function(t){return[t,e.get(t)]}))}},{key:"forEach",value:function(e,t){for(var n=0;n<this._keys.length;n++)e.call(t,this._map["map_"+this._keys[n]],this._keys[n],this)}}]),e}(),U="undefined"!=typeof self?self:global,x="undefined"!=typeof navigator,C=x&&"undefined"==typeof HTMLImageElement,B=!("undefined"==typeof global||"undefined"==typeof process||!process.versions||!process.versions.node),j=U.Buffer,_=!!j;var V=function(e){return void 0!==e};function I(e){return void 0===e||(e instanceof P?0===e.size:0===p(e).filter(V).length)}function L(e){var t=new Error(e);throw delete t.stack,t}function T(e){var t=function(e){var t=0;return e.ifd0.enabled&&(t+=1024),e.exif.enabled&&(t+=2048),e.makerNote&&(t+=2048),e.userComment&&(t+=1024),e.gps.enabled&&(t+=512),e.interop.enabled&&(t+=100),e.ifd1.enabled&&(t+=1024),t+2048}(e);return e.jfif.enabled&&(t+=50),e.xmp.enabled&&(t+=2e4),e.iptc.enabled&&(t+=14e3),e.icc.enabled&&(t+=6e3),t}var z=function(e){return String.fromCharCode.apply(null,e)},F="undefined"!=typeof TextDecoder?new TextDecoder("utf-8"):void 0;function E(e){return F?F.decode(e):_?Buffer.from(e).toString("utf8"):decodeURIComponent(escape(z(e)))}var D=function(){function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2?arguments[2]:void 0,a=arguments.length>3?arguments[3]:void 0;if(t(this,e),"boolean"==typeof a&&(this.le=a),Array.isArray(n)&&(n=new Uint8Array(n)),0===n)this.byteOffset=0,this.byteLength=0;else if(n instanceof ArrayBuffer){void 0===i&&(i=n.byteLength-r);var s=new DataView(n,r,i);this._swapDataView(s)}else if(n instanceof Uint8Array||n instanceof DataView||n instanceof e){void 0===i&&(i=n.byteLength-r),(r+=n.byteOffset)+i>n.byteOffset+n.byteLength&&L("Creating view outside of available memory in ArrayBuffer");var u=new DataView(n.buffer,r,i);this._swapDataView(u)}else if("number"==typeof n){var o=new DataView(new ArrayBuffer(n));this._swapDataView(o)}else L("Invalid input argument for BufferView: "+n)}return r(e,[{key:"_swapArrayBuffer",value:function(e){this._swapDataView(new DataView(e))}},{key:"_swapBuffer",value:function(e){this._swapDataView(new DataView(e.buffer,e.byteOffset,e.byteLength))}},{key:"_swapDataView",value:function(e){this.dataView=e,this.buffer=e.buffer,this.byteOffset=e.byteOffset,this.byteLength=e.byteLength}},{key:"_lengthToEnd",value:function(e){return this.byteLength-e}},{key:"set",value:function(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e;t instanceof DataView||t instanceof e?t=new Uint8Array(t.buffer,t.byteOffset,t.byteLength):t instanceof ArrayBuffer&&(t=new Uint8Array(t)),t instanceof Uint8Array||L("BufferView.set(): Invalid data argument.");var i=this.toUint8();return i.set(t,n),new r(this,n,t.byteLength)}},{key:"subarray",value:function(t,n){return new e(this,t,n=n||this._lengthToEnd(t))}},{key:"toUint8",value:function(){return new Uint8Array(this.buffer,this.byteOffset,this.byteLength)}},{key:"getUint8Array",value:function(e,t){return new Uint8Array(this.buffer,this.byteOffset+e,t)}},{key:"getString",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.byteLength,n=this.getUint8Array(e,t);return E(n)}},{key:"getLatin1String",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.byteLength,n=this.getUint8Array(e,t);return z(n)}},{key:"getUnicodeString",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.byteLength,n=[],r=0;r<t&&e+r<this.byteLength;r+=2)n.push(this.getUint16(e+r));return z(n)}},{key:"getInt8",value:function(e){return this.dataView.getInt8(e)}},{key:"getUint8",value:function(e){return this.dataView.getUint8(e)}},{key:"getInt16",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getInt16(e,t)}},{key:"getInt32",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getInt32(e,t)}},{key:"getUint16",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getUint16(e,t)}},{key:"getUint32",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getUint32(e,t)}},{key:"getFloat32",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getFloat32(e,t)}},{key:"getFloat64",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getFloat64(e,t)}},{key:"getFloat",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getFloat32(e,t)}},{key:"getDouble",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.le;return this.dataView.getFloat64(e,t)}},{key:"getUintBytes",value:function(e,t,n){switch(t){case 1:return this.getUint8(e,n);case 2:return this.getUint16(e,n);case 4:return this.getUint32(e,n);case 8:return this.getUint64&&this.getUint64(e,n)}}},{key:"getUint",value:function(e,t,n){switch(t){case 8:return this.getUint8(e,n);case 16:return this.getUint16(e,n);case 32:return this.getUint32(e,n);case 64:return this.getUint64&&this.getUint64(e,n)}}},{key:"toString",value:function(e){return this.dataView.toString(e,this.constructor.name)}},{key:"ensureChunk",value:function(){}}],[{key:"from",value:function(t,n){return t instanceof this&&t.le===n?t:new e(t,void 0,void 0,n)}}]),e}();function R(e,t){L("".concat(e," '").concat(t,"' was not loaded, try using full build of exifr."))}var N=function(e){a(i,e);var n=d(i);function i(e){var r;return t(this,i),(r=n.call(this)).kind=e,r}return r(i,[{key:"get",value:function(e,t){return this.has(e)||R(this.kind,e),t&&(e in t||function(e,t){L("Unknown ".concat(e," '").concat(t,"'."))}(this.kind,e),t[e].enabled||R(this.kind,e)),v(s(i.prototype),"get",this).call(this,e)}},{key:"keyList",value:function(){return m(this.keys())}}]),i}(c(P)),M=new N("file parser"),W=new N("segment parser"),K=new N("file reader");function H(e){return function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function X(e,t,n){return n?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var Y=H((function(e){return new Promise((function(t,n){var r=new FileReader;r.onloadend=function(){return t(r.result||new ArrayBuffer)},r.onerror=n,r.readAsArrayBuffer(e)}))})),G=H((function(e){return w(e).then((function(e){return e.arrayBuffer()}))})),J=H((function(e,t){return X(t(e),(function(e){return new D(e)}))})),q=H((function(e,t,n){var r=new(K.get(n))(e,t);return X(r.read(),(function(){return r}))})),Q=H((function(e,t,n,r){return K.has(n)?q(e,t,n):r?J(e,r):(L("Parser ".concat(n," is not loaded")),X())})),Z="Invalid input argument";function $(e,t){return(n=e).startsWith("data:")||n.length>1e4?q(e,t,"base64"):x?Q(e,t,"url",G):B?q(e,t,"fs"):void L(Z);var n}var ee=function(e){a(i,e);var n=d(i);function i(){return t(this,i),n.apply(this,arguments)}return r(i,[{key:"tagKeys",get:function(){return this.allKeys||(this.allKeys=m(this.keys())),this.allKeys}},{key:"tagValues",get:function(){return this.allValues||(this.allValues=m(this.values())),this.allValues}}]),i}(c(P));function te(e,t,n){var r=new ee,i=n;Array.isArray(i)||("function"==typeof i.entries&&(i=i.entries()),i=m(i));for(var a=0;a<i.length;a++){var s=i[a],u=s[0],o=s[1];r.set(u,o)}if(Array.isArray(t)){var f=t;Array.isArray(f)||("function"==typeof f.entries&&(f=f.entries()),f=m(f));for(var c=0;c<f.length;c++){var h=f[c];e.set(h,r)}}else e.set(t,r);return r}function ne(e,t,n){var r,i=e.get(t),a=n;Array.isArray(a)||("function"==typeof a.entries&&(a=a.entries()),a=m(a));for(var s=0;s<a.length;s++)r=a[s],i.set(r[0],r[1])}var re=S(),ie=S(),ae=S(),se=37500,ue=37510,oe=33723,fe=34675,ce=34665,he=34853,le=40965,de=["chunked","firstChunkSize","firstChunkSizeNode","firstChunkSizeBrowser","chunkSize","chunkLimit"],ve=["jfif","xmp","icc","iptc","ihdr"],pe=["tiff"].concat(ve),ye=["ifd0","ifd1","exif","gps","interop"],ge=[].concat(pe,ye),ke=["makerNote","userComment"],me=["translateKeys","translateValues","reviveValues","multiSegment"],be=[].concat(me,["sanitize","mergeOutput","silentErrors"]),Ae=function(){function e(){t(this,e)}return r(e,[{key:"translate",get:function(){return this.translateKeys||this.translateValues||this.reviveValues}}]),e}(),we=function(e){a(s,e);var n=d(s);function s(e,r,a,u){var o;if(t(this,s),i(h(o=n.call(this)),"enabled",!1),i(h(o),"skip",O()),i(h(o),"pick",O()),i(h(o),"deps",O()),i(h(o),"translateKeys",!1),i(h(o),"translateValues",!1),i(h(o),"reviveValues",!1),o.key=e,o.enabled=r,o.parse=o.enabled,o.applyInheritables(u),o.canBeFiltered=ye.includes(e),o.canBeFiltered&&(o.dict=re.get(e)),void 0!==a)if(Array.isArray(a))o.parse=o.enabled=!0,o.canBeFiltered&&a.length>0&&o.translateTagSet(a,o.pick);else if("object"==typeof a){if(o.enabled=!0,o.parse=!1!==a.parse,o.canBeFiltered){var f=a.pick,c=a.skip;f&&f.length>0&&o.translateTagSet(f,o.pick),c&&c.length>0&&o.translateTagSet(c,o.skip)}o.applyInheritables(a)}else!0===a||!1===a?o.parse=o.enabled=a:L("Invalid options argument: ".concat(a));return o}return r(s,[{key:"needed",get:function(){return this.enabled||this.deps.size>0}},{key:"applyInheritables",value:function(e){var t,n,r=me;Array.isArray(r)||("function"==typeof r.entries&&(r=r.entries()),r=m(r));for(var i=0;i<r.length;i++)void 0!==(n=e[t=r[i]])&&(this[t]=n)}},{key:"translateTagSet",value:function(e,t){if(this.dict){var n,r,i=this.dict,a=i.tagKeys,s=i.tagValues,u=e;Array.isArray(u)||("function"==typeof u.entries&&(u=u.entries()),u=m(u));for(var o=0;o<u.length;o++)"string"==typeof(n=u[o])?(-1===(r=s.indexOf(n))&&(r=a.indexOf(Number(n))),-1!==r&&t.add(Number(a[r]))):t.add(n)}else{var f=e;Array.isArray(f)||("function"==typeof f.entries&&(f=f.entries()),f=m(f));for(var c=0;c<f.length;c++){var h=f[c];t.add(h)}}}},{key:"finalizeFilters",value:function(){!this.enabled&&this.deps.size>0?(this.enabled=!0,Ce(this.pick,this.deps)):this.enabled&&this.pick.size>0&&Ce(this.pick,this.deps)}}]),s}(Ae),Oe={jfif:!1,tiff:!0,xmp:!1,icc:!1,iptc:!1,ifd0:!0,ifd1:!1,exif:!0,gps:!0,interop:!1,ihdr:void 0,makerNote:!1,userComment:!1,multiSegment:!1,skip:[],pick:[],translateKeys:!0,translateValues:!0,reviveValues:!0,sanitize:!0,mergeOutput:!0,silentErrors:!0,chunked:!0,firstChunkSize:void 0,firstChunkSizeNode:512,firstChunkSizeBrowser:65536,chunkSize:65536,chunkLimit:5},Se=S(),Pe=function(e){a(i,e);var n=d(i);function i(e){var r;return t(this,i),r=n.call(this),!0===e?r.setupFromTrue():void 0===e?r.setupFromUndefined():Array.isArray(e)?r.setupFromArray(e):"object"==typeof e?r.setupFromObject(e):L("Invalid options argument ".concat(e)),void 0===r.firstChunkSize&&(r.firstChunkSize=x?r.firstChunkSizeBrowser:r.firstChunkSizeNode),r.mergeOutput&&(r.ifd1.enabled=!1),r.filterNestedSegmentTags(),r.traverseTiffDependencyTree(),r.checkLoadedPlugins(),r}return r(i,[{key:"setupFromUndefined",value:function(){var e,t=de;Array.isArray(t)||("function"==typeof t.entries&&(t=t.entries()),t=m(t));for(var n=0;n<t.length;n++)this[e=t[n]]=Oe[e];var r=be;Array.isArray(r)||("function"==typeof r.entries&&(r=r.entries()),r=m(r));for(var i=0;i<r.length;i++)this[e=r[i]]=Oe[e];var a=ke;Array.isArray(a)||("function"==typeof a.entries&&(a=a.entries()),a=m(a));for(var s=0;s<a.length;s++)this[e=a[s]]=Oe[e];var u=ge;Array.isArray(u)||("function"==typeof u.entries&&(u=u.entries()),u=m(u));for(var o=0;o<u.length;o++)this[e=u[o]]=new we(e,Oe[e],void 0,this)}},{key:"setupFromTrue",value:function(){var e,t=de;Array.isArray(t)||("function"==typeof t.entries&&(t=t.entries()),t=m(t));for(var n=0;n<t.length;n++)this[e=t[n]]=Oe[e];var r=be;Array.isArray(r)||("function"==typeof r.entries&&(r=r.entries()),r=m(r));for(var i=0;i<r.length;i++)this[e=r[i]]=Oe[e];var a=ke;Array.isArray(a)||("function"==typeof a.entries&&(a=a.entries()),a=m(a));for(var s=0;s<a.length;s++)this[e=a[s]]=!0;var u=ge;Array.isArray(u)||("function"==typeof u.entries&&(u=u.entries()),u=m(u));for(var o=0;o<u.length;o++)this[e=u[o]]=new we(e,!0,void 0,this)}},{key:"setupFromArray",value:function(e){var t,n=de;Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++)this[t=n[r]]=Oe[t];var i=be;Array.isArray(i)||("function"==typeof i.entries&&(i=i.entries()),i=m(i));for(var a=0;a<i.length;a++)this[t=i[a]]=Oe[t];var s=ke;Array.isArray(s)||("function"==typeof s.entries&&(s=s.entries()),s=m(s));for(var u=0;u<s.length;u++)this[t=s[u]]=Oe[t];var o=ge;Array.isArray(o)||("function"==typeof o.entries&&(o=o.entries()),o=m(o));for(var f=0;f<o.length;f++)this[t=o[f]]=new we(t,!1,void 0,this);this.setupGlobalFilters(e,void 0,ye)}},{key:"setupFromObject",value:function(e){var t;ye.ifd0=ye.ifd0||ye.image,ye.ifd1=ye.ifd1||ye.thumbnail,g(this,e);var n=de;Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++)this[t=n[r]]=xe(e[t],Oe[t]);var i=be;Array.isArray(i)||("function"==typeof i.entries&&(i=i.entries()),i=m(i));for(var a=0;a<i.length;a++)this[t=i[a]]=xe(e[t],Oe[t]);var s=ke;Array.isArray(s)||("function"==typeof s.entries&&(s=s.entries()),s=m(s));for(var u=0;u<s.length;u++)this[t=s[u]]=xe(e[t],Oe[t]);var o=pe;Array.isArray(o)||("function"==typeof o.entries&&(o=o.entries()),o=m(o));for(var f=0;f<o.length;f++)this[t=o[f]]=new we(t,Oe[t],e[t],this);var c=ye;Array.isArray(c)||("function"==typeof c.entries&&(c=c.entries()),c=m(c));for(var h=0;h<c.length;h++)this[t=c[h]]=new we(t,Oe[t],e[t],this.tiff);this.setupGlobalFilters(e.pick,e.skip,ye,ge),!0===e.tiff?this.batchEnableWithBool(ye,!0):!1===e.tiff?this.batchEnableWithUserValue(ye,e):Array.isArray(e.tiff)?this.setupGlobalFilters(e.tiff,void 0,ye):"object"==typeof e.tiff&&this.setupGlobalFilters(e.tiff.pick,e.tiff.skip,ye)}},{key:"batchEnableWithBool",value:function(e,t){var n=e;Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++){this[n[r]].enabled=t}}},{key:"batchEnableWithUserValue",value:function(e,t){var n=e;Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++){var i=n[r],a=t[i];this[i].enabled=!1!==a&&void 0!==a}}},{key:"setupGlobalFilters",value:function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:n;if(e&&e.length){var i=r;Array.isArray(i)||("function"==typeof i.entries&&(i=i.entries()),i=m(i));for(var a=0;a<i.length;a++){var s=i[a];this[s].enabled=!1}var u=Ue(e,n),o=u;Array.isArray(o)||("function"==typeof o.entries&&(o=o.entries()),o=m(o));for(var f=0;f<o.length;f++){var c=o[f],h=c[0],l=c[1];Ce(this[h].pick,l),this[h].enabled=!0}}else if(t&&t.length){var d=Ue(t,n),v=d;Array.isArray(v)||("function"==typeof v.entries&&(v=v.entries()),v=m(v));for(var p=0;p<v.length;p++){var y=v[p],g=y[0],k=y[1];Ce(this[g].skip,k)}}}},{key:"filterNestedSegmentTags",value:function(){var e=this.ifd0,t=this.exif,n=this.xmp,r=this.iptc,i=this.icc;this.makerNote?t.deps.add(se):t.skip.add(se),this.userComment?t.deps.add(ue):t.skip.add(ue),n.enabled||e.skip.add(700),r.enabled||e.skip.add(oe),i.enabled||e.skip.add(fe)}},{key:"traverseTiffDependencyTree",value:function(){var e=this,t=this.ifd0,n=this.exif,r=this.gps;this.interop.needed&&(n.deps.add(le),t.deps.add(le)),n.needed&&t.deps.add(ce),r.needed&&t.deps.add(he),this.tiff.enabled=ye.some((function(t){return!0===e[t].enabled}))||this.makerNote||this.userComment;var i=ye;Array.isArray(i)||("function"==typeof i.entries&&(i=i.entries()),i=m(i));for(var a=0;a<i.length;a++){this[i[a]].finalizeFilters()}}},{key:"onlyTiff",get:function(){var e=this;return!ve.map((function(t){return e[t].enabled})).some((function(e){return!0===e}))&&this.tiff.enabled}},{key:"checkLoadedPlugins",value:function(){var e=pe;Array.isArray(e)||("function"==typeof e.entries&&(e=e.entries()),e=m(e));for(var t=0;t<e.length;t++){var n=e[t];this[n].enabled&&!W.has(n)&&R("segment parser",n)}}}],[{key:"useCached",value:function(e){var t=Se.get(e);return void 0!==t||(t=new this(e),Se.set(e,t)),t}}]),i}(Ae);function Ue(e,t){var n,r,i,a=[],s=t;Array.isArray(s)||("function"==typeof s.entries&&(s=s.entries()),s=m(s));for(var u=0;u<s.length;u++){r=s[u],n=[];var o=re.get(r);Array.isArray(o)||("function"==typeof o.entries&&(o=o.entries()),o=m(o));for(var f=0;f<o.length;f++)i=o[f],(e.includes(i[0])||e.includes(i[1]))&&n.push(i[0]);n.length&&a.push([r,n])}return a}function xe(e,t){return void 0!==e?e:void 0!==t?t:void 0}function Ce(e,t){var n=t;Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++){var i=n[r];e.add(i)}}function Be(e,t,n){return n?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}function je(){}function _e(e,t){if(!t)return e&&e.then?e.then(je):Promise.resolve()}function Ve(e,t){var n=e();return n&&n.then?n.then(t):t(n)}i(Pe,"default",Oe);var Ie=function(){function e(n){t(this,e),i(this,"parsers",{}),this.options=Pe.useCached(n)}return r(e,[{key:"setup",value:function(){if(!this.fileParser){var e=this.file,t=e.getUint16(0),n=M;Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++){var i=n[r],a=i[0],s=i[1];if(s.canHandle(e,t))return this.fileParser=new s(this.options,this.file,this.parsers),e[a]=!0}L("Unknown file format")}}},{key:"read",value:function(e){try{var t=this;return Be(function(e,t){return"string"==typeof e?$(e,t):x&&!C&&e instanceof HTMLImageElement?$(e.src,t):e instanceof Uint8Array||e instanceof ArrayBuffer||e instanceof DataView?new D(e):x&&e instanceof Blob?Q(e,t,"blob",Y):void L(Z)}(e,t.options),(function(e){t.file=e}))}catch(e){return Promise.reject(e)}}},{key:"parse",value:function(){try{var e=this;e.setup();var t={},n=[];return Ve((function(){return e.options.silentErrors?Be(e.doParse(t,n).catch((function(e){return n.push(e)})),(function(){n.push.apply(n,e.fileParser.errors)})):_e(e.doParse(t,n))}),(function(){return e.file.close&&e.file.close(),e.options.silentErrors&&n.length>0&&(t.errors=n),I(r=t)?void 0:r;var r}))}catch(e){return Promise.reject(e)}}},{key:"doParse",value:function(e,t){try{var n=this;return Be(n.fileParser.parse(),(function(){var r,i=p(n.parsers).map((r=function(t){return Be(t.parse(),(function(n){t.assignToOutput(e,n)}))},function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];try{return Promise.resolve(r.apply(this,e))}catch(e){return Promise.reject(e)}}));if(n.options.silentErrors){var a=function(e){return t.push(e)};i=i.map((function(e){return e.catch(a)}))}return _e(Promise.all(i))}))}catch(e){return Promise.reject(e)}}},{key:"extractThumbnail",value:function(){try{var e=this;e.setup();var t,n=e.options,r=e.file,i=W.get("tiff",n);return Ve((function(){if(!r.tiff)return function(e){var t=e();if(t&&t.then)return t.then(je)}((function(){if(r.jpeg)return Be(e.fileParser.getOrFindSegment("tiff"),(function(e){t=e}))}));t={start:0,type:"tiff"}}),(function(){if(void 0!==t)return Be(e.fileParser.ensureSegmentChunk(t),(function(t){return Be((e.parsers.tiff=new i(t,n,r)).extractThumbnail(),(function(e){return r.close&&r.close(),e}))}))}))}catch(e){return Promise.reject(e)}}}]),e}();var Le,Te=(Le=function(e,t){var n,r,i,a=new Ie(t);return n=a.read(e),r=function(){return a.parse()},i?r?r(n):n:(n&&n.then||(n=Promise.resolve(n)),r?n.then(r):n)},function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];try{return Promise.resolve(Le.apply(this,e))}catch(e){return Promise.reject(e)}}),ze=Object.freeze({__proto__:null,parse:Te,Exifr:Ie,fileParsers:M,segmentParsers:W,fileReaders:K,tagKeys:re,tagValues:ie,tagRevivers:ae,createDictionary:te,extendDictionary:ne,fetchUrlAsArrayBuffer:G,readBlobAsArrayBuffer:Y,chunkedProps:de,otherSegments:ve,segments:pe,tiffBlocks:ye,segmentsAndBlocks:ge,tiffExtractables:ke,inheritables:me,allFormatters:be,Options:Pe});function Fe(){}var Ee=function(){function e(n,r,a){var s=this;t(this,e),i(this,"errors",[]),i(this,"ensureSegmentChunk",function(e){return function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}((function(e){var t,n,r,i=e.start,a=e.size||65536;return t=function(){if(s.file.chunked)return function(e){var t=e();if(t&&t.then)return t.then(Fe)}((function(){if(!s.file.available(i,a))return function(e){if(e&&e.then)return e.then(Fe)}(function(e,t){try{var n=e()}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}((function(){return t=s.file.readChunk(i,a),n=function(t){e.chunk=t},r?n?n(t):t:(t&&t.then||(t=Promise.resolve(t)),n?t.then(n):t);var t,n,r}),(function(t){L("Couldn't read segment: ".concat(JSON.stringify(e),". ").concat(t.message))})));e.chunk=s.file.subarray(i,a)}));s.file.byteLength>i+a?e.chunk=s.file.subarray(i,a):void 0===e.size?e.chunk=s.file.subarray(i):L("Segment unreachable: "+JSON.stringify(e))},n=function(){return e.chunk},(r=t())&&r.then?r.then(n):n(r)}))),this.extendOptions&&this.extendOptions(n),this.options=n,this.file=r,this.parsers=a}return r(e,[{key:"injectSegment",value:function(e,t){this.options[e].enabled&&this.createParser(e,t)}},{key:"createParser",value:function(e,t){var n=new(W.get(e))(t,this.options,this.file);return this.parsers[e]=n}},{key:"createParsers",value:function(e){var t=e;Array.isArray(t)||("function"==typeof t.entries&&(t=t.entries()),t=m(t));for(var n=0;n<t.length;n++){var r=t[n],i=r.type,a=r.chunk,s=this.options[i];if(s&&s.enabled){var u=this.parsers[i];u&&u.append||u||this.createParser(i,a)}}}},{key:"readSegments",value:function(e){try{var t=e.map(this.ensureSegmentChunk);return function(e,t){if(!t)return e&&e.then?e.then(Fe):Promise.resolve()}(Promise.all(t))}catch(e){return Promise.reject(e)}}}]),e}(),De=function(){function e(n){var r=this,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=arguments.length>2?arguments[2]:void 0;t(this,e),i(this,"errors",[]),i(this,"raw",S()),i(this,"handleError",(function(e){if(!r.options.silentErrors)throw e;r.errors.push(e.message)})),this.chunk=this.normalizeInput(n),this.file=s,this.type=this.constructor.type,this.globalOptions=this.options=a,this.localOptions=a[this.type],this.canTranslate=this.localOptions&&this.localOptions.translate}return r(e,[{key:"normalizeInput",value:function(e){return e instanceof D?e:new D(e)}},{key:"translate",value:function(){this.canTranslate&&(this.translated=this.translateBlock(this.raw,this.type))}},{key:"output",get:function(){return this.translated?this.translated:this.raw?k(this.raw):void 0}},{key:"translateBlock",value:function(e,t){var n=ae.get(t),r=ie.get(t),i=re.get(t),a=this.options[t],s=a.reviveValues&&!!n,u=a.translateValues&&!!r,o=a.translateKeys&&!!i,f={},c=e;Array.isArray(c)||("function"==typeof c.entries&&(c=c.entries()),c=m(c));for(var h=0;h<c.length;h++){var l=c[h],d=l[0],v=l[1];s&&n.has(d)?v=n.get(d)(v):u&&r.has(d)&&(v=this.translateValue(v,r.get(d))),o&&i.has(d)&&(d=i.get(d)||d),f[d]=v}return f}},{key:"translateValue",value:function(e,t){return t[e]||t.DEFAULT||e}},{key:"assignToOutput",value:function(e,t){this.assignObjectToOutput(e,this.constructor.type,t)}},{key:"assignObjectToOutput",value:function(e,t,n){if(this.globalOptions.mergeOutput)return g(e,n);e[t]?g(e[t],n):e[t]=n}}],[{key:"findPosition",value:function(e,t){var n=e.getUint16(t+2)+2,r="function"==typeof this.headerLength?this.headerLength(e,t,n):this.headerLength,i=t+r,a=n-r;return{offset:t,length:n,headerLength:r,start:i,size:a,end:i+a}}},{key:"parse",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new Pe(i({},this.type,t)),r=new this(e,n);return r.parse()}}]),e}();function Re(e,t,n){return n?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}i(De,"headerLength",4),i(De,"type",void 0),i(De,"multiSegment",!1),i(De,"canHandle",(function(){return!1}));function Ne(){}function Me(e,t){if(!t)return e&&e.then?e.then(Ne):Promise.resolve()}function We(e){var t=e();if(t&&t.then)return t.then(Ne)}function Ke(e,t){var n=e();return n&&n.then?n.then(t):t(n)}function He(e,t,n){if(!e.s){if(n instanceof Xe){if(!n.s)return void(n.o=He.bind(null,e,t));1&t&&(t=n.s),n=n.v}if(n&&n.then)return void n.then(He.bind(null,e,t),He.bind(null,e,2));e.s=t,e.v=n;var r=e.o;r&&r(e)}}var Xe=function(){function e(){}return e.prototype.then=function(t,n){var r=new e,i=this.s;if(i){var a=1&i?t:n;if(a){try{He(r,1,a(this.v))}catch(e){He(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?He(r,1,t?t(i):i):n?He(r,1,n(i)):He(r,2,i)}catch(e){He(r,2,e)}},r},e}();function Ye(e){return e instanceof Xe&&1&e.s}function Ge(e,t,n){for(var r;;){var i=e();if(Ye(i)&&(i=i.v),!i)return a;if(i.then){r=0;break}var a=n();if(a&&a.then){if(!Ye(a)){r=1;break}a=a.s}if(t){var s=t();if(s&&s.then&&!Ye(s)){r=2;break}}}var u=new Xe,o=He.bind(null,u,2);return(0===r?i.then(c):1===r?a.then(f):s.then(h)).then(void 0,o),u;function f(r){a=r;do{if(t&&(s=t())&&s.then&&!Ye(s))return void s.then(h).then(void 0,o);if(!(i=e())||Ye(i)&&!i.v)return void He(u,1,a);if(i.then)return void i.then(c).then(void 0,o);Ye(a=n())&&(a=a.v)}while(!a||!a.then);a.then(f).then(void 0,o)}function c(e){e?(a=n())&&a.then?a.then(f).then(void 0,o):f(a):He(u,1,a)}function h(){(i=e())?i.then?i.then(c).then(void 0,o):c(i):He(u,1,a)}}function Je(e){return 192===e||194===e||196===e||219===e||221===e||218===e||254===e}function qe(e){return e>=224&&e<=239}function Qe(e,t,n){var r=W;Array.isArray(r)||("function"==typeof r.entries&&(r=r.entries()),r=m(r));for(var i=0;i<r.length;i++){var a=r[i],s=a[0];if(a[1].canHandle(e,t,n))return s}}var Ze=function(e){a(s,e);var n=d(s);function s(){var e;t(this,s);for(var r=arguments.length,a=new Array(r),u=0;u<r;u++)a[u]=arguments[u];return i(h(e=n.call.apply(n,[this].concat(a))),"appSegments",[]),i(h(e),"jpegSegments",[]),i(h(e),"unknownSegments",[]),e}return r(s,[{key:"parse",value:function(){try{var e=this;return Re(e.findAppSegments(),(function(){return Re(e.readSegments(e.appSegments),(function(){e.mergeMultiSegments(),e.createParsers(e.mergedAppSegments||e.appSegments)}))}))}catch(e){return Promise.reject(e)}}},{key:"setupSegmentFinderArgs",value:function(e){var t=this;!0===e?(this.findAll=!0,this.wanted=O(W.keyList())):(e=void 0===e?W.keyList().filter((function(e){return t.options[e].enabled})):e.filter((function(e){return t.options[e].enabled&&W.has(e)})),this.findAll=!1,this.remaining=O(e),this.wanted=O(e)),this.unfinishedMultiSegment=!1}},{key:"findAppSegments",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1?arguments[1]:void 0;try{var n=this;n.setupSegmentFinderArgs(t);var r=n.file,i=n.findAll,a=n.wanted,s=n.remaining;return Ke((function(){if(!i&&n.file.chunked)return i=m(a).some((function(e){var t=W.get(e),r=n.options[e];return t.multiSegment&&r.multiSegment})),We((function(){if(i)return Me(n.file.readWhole())}))}),(function(){var t=!1;if(e=n.findAppSegmentsInRange(e,r.byteLength),!n.options.onlyTiff)return function(){if(r.chunked){var i=!1;return Ge((function(){return!t&&s.size>0&&!i&&(!!r.canReadNextChunk||!!n.unfinishedMultiSegment)}),void 0,(function(){var a=r.nextChunkOffset,s=n.appSegments.some((function(e){return!n.file.available(e.offset||e.start,e.length||e.size)}));return Ke((function(){return e>a&&!s?Re(r.readNextChunk(e),(function(e){i=!e})):Re(r.readNextChunk(a),(function(e){i=!e}))}),(function(){void 0===(e=n.findAppSegmentsInRange(e,r.byteLength))&&(t=!0)}))}))}}()}))}catch(e){return Promise.reject(e)}}},{key:"findAppSegmentsInRange",value:function(e,t){t-=2;for(var n,r,i,a,s,u,o=this.file,f=this.findAll,c=this.wanted,h=this.remaining,l=this.options;e<t;e++)if(255===o.getUint8(e))if(qe(n=o.getUint8(e+1))){if(r=o.getUint16(e+2),(i=Qe(o,e,r))&&c.has(i)&&(s=(a=W.get(i)).findPosition(o,e),u=l[i],s.type=i,this.appSegments.push(s),!f&&(a.multiSegment&&u.multiSegment?(this.unfinishedMultiSegment=s.chunkNumber<s.chunkCount,this.unfinishedMultiSegment||h.delete(i)):h.delete(i),0===h.size)))break;l.recordUnknownSegments&&((s=De.findPosition(o,e)).marker=n,this.unknownSegments.push(s)),e+=r+1}else if(Je(n)){if(r=o.getUint16(e+2),218===n&&!1!==l.stopAfterSos)return;l.recordJpegSegments&&this.jpegSegments.push({offset:e,length:r,marker:n}),e+=r+1}return e}},{key:"mergeMultiSegments",value:function(){var e=this;if(this.appSegments.some((function(e){return e.multiSegment}))){var t=function(e,t){for(var n,r,i,a=S(),s=0;s<e.length;s++)r=(n=e[s])[t],a.has(r)?i=a.get(r):a.set(r,i=[]),i.push(n);return m(a)}(this.appSegments,"type");this.mergedAppSegments=t.map((function(t){var n=t[0],r=t[1],i=W.get(n,e.options);return i.handleMultiSegments?{type:n,chunk:i.handleMultiSegments(r)}:r[0]}))}}},{key:"getSegment",value:function(e){return this.appSegments.find((function(t){return t.type===e}))}},{key:"getOrFindSegment",value:function(e){try{var t=this,n=t.getSegment(e);return Ke((function(){if(void 0===n)return Re(t.findAppSegments(0,[e]),(function(){n=t.getSegment(e)}))}),(function(){return n}))}catch(e){return Promise.reject(e)}}}],[{key:"canHandle",value:function(e,t){return 65496===t}}]),s}(Ee);function $e(){}i(Ze,"type","jpeg"),M.set("jpeg",Ze);function et(e,t){if(!t)return e&&e.then?e.then($e):Promise.resolve()}function tt(e,t){var n=e();return n&&n.then?n.then(t):t(n)}var nt=[void 0,1,1,2,4,8,1,1,2,4,8,4,8,4];var rt=function(e){a(i,e);var n=d(i);function i(){return t(this,i),n.apply(this,arguments)}return r(i,[{key:"parse",value:function(){try{var e=this;e.parseHeader();var t=e.options;return tt((function(){if(t.ifd0.enabled)return et(e.parseIfd0Block())}),(function(){return tt((function(){if(t.exif.enabled)return et(e.safeParse("parseExifBlock"))}),(function(){return tt((function(){if(t.gps.enabled)return et(e.safeParse("parseGpsBlock"))}),(function(){return tt((function(){if(t.interop.enabled)return et(e.safeParse("parseInteropBlock"))}),(function(){return tt((function(){if(t.ifd1.enabled)return et(e.safeParse("parseThumbnailBlock"))}),(function(){return e.createOutput()}))}))}))}))}))}catch(e){return Promise.reject(e)}}},{key:"safeParse",value:function(e){var t=this[e]();return void 0!==t.catch&&(t=t.catch(this.handleError)),t}},{key:"findIfd0Offset",value:function(){void 0===this.ifd0Offset&&(this.ifd0Offset=this.chunk.getUint32(4))}},{key:"findIfd1Offset",value:function(){if(void 0===this.ifd1Offset){this.findIfd0Offset();var e=this.chunk.getUint16(this.ifd0Offset),t=this.ifd0Offset+2+12*e;this.ifd1Offset=this.chunk.getUint32(t)}}},{key:"parseBlock",value:function(e,t){var n=S();return this[t]=n,this.parseTags(e,t,n),n}},{key:"parseIfd0Block",value:function(){try{var e=this;if(e.ifd0)return;var t=e.file;return e.findIfd0Offset(),e.ifd0Offset<8&&L("Malformed EXIF data"),!t.chunked&&e.ifd0Offset>t.byteLength&&L("IFD0 offset points to outside of file.\nthis.ifd0Offset: ".concat(e.ifd0Offset,", file.byteLength: ").concat(t.byteLength)),tt((function(){if(t.tiff)return et(t.ensureChunk(e.ifd0Offset,T(e.options)))}),(function(){var t=e.parseBlock(e.ifd0Offset,"ifd0");if(0!==t.size)return e.exifOffset=t.get(ce),e.interopOffset=t.get(le),e.gpsOffset=t.get(he),e.xmp=t.get(700),e.iptc=t.get(oe),e.icc=t.get(fe),e.options.sanitize&&(t.delete(ce),t.delete(le),t.delete(he),t.delete(700),t.delete(oe),t.delete(fe)),t}))}catch(e){return Promise.reject(e)}}},{key:"parseExifBlock",value:function(){try{var e=this;if(e.exif)return;return tt((function(){if(!e.ifd0)return et(e.parseIfd0Block())}),(function(){if(void 0!==e.exifOffset)return tt((function(){if(e.file.tiff)return et(e.file.ensureChunk(e.exifOffset,T(e.options)))}),(function(){var t=e.parseBlock(e.exifOffset,"exif");return e.interopOffset||(e.interopOffset=t.get(le)),e.makerNote=t.get(se),e.userComment=t.get(ue),e.options.sanitize&&(t.delete(le),t.delete(se),t.delete(ue)),e.unpack(t,41728),e.unpack(t,41729),t}))}))}catch(e){return Promise.reject(e)}}},{key:"unpack",value:function(e,t){var n=e.get(t);n&&1===n.length&&e.set(t,n[0])}},{key:"parseGpsBlock",value:function(){try{var e=this;if(e.gps)return;return tt((function(){if(!e.ifd0)return et(e.parseIfd0Block())}),(function(){if(void 0!==e.gpsOffset){var t=e.parseBlock(e.gpsOffset,"gps");return t&&t.has(2)&&t.has(4)&&(t.set("latitude",it.apply(void 0,t.get(2).concat([t.get(1)]))),t.set("longitude",it.apply(void 0,t.get(4).concat([t.get(3)])))),t}}))}catch(e){return Promise.reject(e)}}},{key:"parseInteropBlock",value:function(){try{var e=this;if(e.interop)return;return tt((function(){if(!e.ifd0)return et(e.parseIfd0Block())}),(function(){return tt((function(){if(void 0===e.interopOffset&&!e.exif)return et(e.parseExifBlock())}),(function(){if(void 0!==e.interopOffset)return e.parseBlock(e.interopOffset,"interop")}))}))}catch(e){return Promise.reject(e)}}},{key:"parseThumbnailBlock",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];try{var t=this;if(t.ifd1||t.ifd1Parsed)return;if(t.options.mergeOutput&&!e)return;return t.findIfd1Offset(),t.ifd1Offset>0&&(t.parseBlock(t.ifd1Offset,"ifd1"),t.ifd1Parsed=!0),t.ifd1}catch(e){return Promise.reject(e)}}},{key:"extractThumbnail",value:function(){try{var e=this;return e.headerParsed||e.parseHeader(),tt((function(){if(!e.ifd1Parsed)return et(e.parseThumbnailBlock(!0))}),(function(){if(void 0!==e.ifd1){var t=e.ifd1.get(513),n=e.ifd1.get(514);return e.chunk.getUint8Array(t,n)}}))}catch(e){return Promise.reject(e)}}},{key:"image",get:function(){return this.ifd0}},{key:"thumbnail",get:function(){return this.ifd1}},{key:"createOutput",value:function(){var e,t,n,r={},i=ye;Array.isArray(i)||("function"==typeof i.entries&&(i=i.entries()),i=m(i));for(var a=0;a<i.length;a++)if(!I(e=this[t=i[a]]))if(n=this.canTranslate?this.translateBlock(e,t):k(e),this.options.mergeOutput){if("ifd1"===t)continue;g(r,n)}else r[t]=n;return this.makerNote&&(r.makerNote=this.makerNote),this.userComment&&(r.userComment=this.userComment),r}},{key:"assignToOutput",value:function(e,t){if(this.globalOptions.mergeOutput)g(e,t);else{var n=y(t);Array.isArray(n)||("function"==typeof n.entries&&(n=n.entries()),n=m(n));for(var r=0;r<n.length;r++){var i=n[r],a=i[0],s=i[1];this.assignObjectToOutput(e,a,s)}}}}],[{key:"canHandle",value:function(e,t){return 225===e.getUint8(t+1)&&1165519206===e.getUint32(t+4)&&0===e.getUint16(t+8)}}]),i}(function(e){a(i,e);var n=d(i);function i(){return t(this,i),n.apply(this,arguments)}return r(i,[{key:"parseHeader",value:function(){var e=this.chunk.getUint16();18761===e?this.le=!0:19789===e&&(this.le=!1),this.chunk.le=this.le,this.headerParsed=!0}},{key:"parseTags",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:S(),r=this.options[t],i=r.pick,a=r.skip,s=(i=O(i)).size>0,u=0===a.size,o=this.chunk.getUint16(e);e+=2;for(var f=0;f<o;f++){var c=this.chunk.getUint16(e);if(s){if(i.has(c)&&(n.set(c,this.parseTag(e,c,t)),i.delete(c),0===i.size))break}else!u&&a.has(c)||n.set(c,this.parseTag(e,c,t));e+=12}return n}},{key:"parseTag",value:function(e,t,n){var r,i=this.chunk,a=i.getUint16(e+2),s=i.getUint32(e+4),u=nt[a];if(u*s<=4?e+=8:e=i.getUint32(e+8),(a<1||a>13)&&L("Invalid TIFF value type. block: ".concat(n.toUpperCase(),", tag: ").concat(t.toString(16),", type: ").concat(a,", offset ").concat(e)),e>i.byteLength&&L("Invalid TIFF value offset. block: ".concat(n.toUpperCase(),", tag: ").concat(t.toString(16),", type: ").concat(a,", offset ").concat(e," is outside of chunk size ").concat(i.byteLength)),1===a)return i.getUint8Array(e,s);if(2===a)return""===(r=function(e){for(;e.endsWith("\0");)e=e.slice(0,-1);return e}(r=i.getString(e,s)).trim())?void 0:r;if(7===a)return i.getUint8Array(e,s);if(1===s)return this.parseTagValue(a,e);for(var o=new(function(e){switch(e){case 1:return Uint8Array;case 3:return Uint16Array;case 4:return Uint32Array;case 5:return Array;case 6:return Int8Array;case 8:return Int16Array;case 9:return Int32Array;case 10:return Array;case 11:return Float32Array;case 12:return Float64Array;default:return Array}}(a))(s),f=u,c=0;c<s;c++)o[c]=this.parseTagValue(a,e),e+=f;return o}},{key:"parseTagValue",value:function(e,t){var n=this.chunk;switch(e){case 1:return n.getUint8(t);case 3:return n.getUint16(t);case 4:return n.getUint32(t);case 5:return n.getUint32(t)/n.getUint32(t+4);case 6:return n.getInt8(t);case 8:return n.getInt16(t);case 9:return n.getInt32(t);case 10:return n.getInt32(t)/n.getInt32(t+4);case 11:return n.getFloat(t);case 12:return n.getDouble(t);case 13:return n.getUint32(t);default:L("Invalid tiff type ".concat(e))}}}]),i}(De));function it(e,t,n,r){var i=e+t/60+n/3600;return"S"!==r&&"W"!==r||(i*=-1),i}i(rt,"type","tiff"),i(rt,"headerLength",10),W.set("tiff",rt);var at=Object.freeze({__proto__:null,default:ze,Exifr:Ie,fileParsers:M,segmentParsers:W,fileReaders:K,tagKeys:re,tagValues:ie,tagRevivers:ae,createDictionary:te,extendDictionary:ne,fetchUrlAsArrayBuffer:G,readBlobAsArrayBuffer:Y,chunkedProps:de,otherSegments:ve,segments:pe,tiffBlocks:ye,segmentsAndBlocks:ge,tiffExtractables:ke,inheritables:me,allFormatters:be,Options:Pe,parse:Te});function st(e,t,n){return n?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}function ut(e){return function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}var ot=ut((function(e){var t=new Ie(vt);return st(t.read(e),(function(){return st(t.parse(),(function(e){if(e&&e.ifd0)return e.ifd0[274]}))}))})),ft=ut((function(e){var t=new Ie(dt);return st(t.read(e),(function(){return st(t.parse(),(function(e){if(e&&e.gps){var t=e.gps;return{latitude:t.latitude,longitude:t.longitude}}}))}))})),ct=ut((function(e){return st(this.thumbnail(e),(function(e){if(void 0!==e){var t=new Blob([e]);return URL.createObjectURL(t)}}))})),ht=ut((function(e){var t=new Ie(pt);return st(t.read(e),(function(){return st(t.extractThumbnail(),(function(e){return e&&_?j.from(e):e}))}))})),lt={ifd0:!1,ifd1:!1,exif:!1,gps:!1,interop:!1,sanitize:!1,reviveValues:!0,translateKeys:!1,translateValues:!1,mergeOutput:!1},dt=g({},lt,{firstChunkSize:4e4,gps:[1,2,3,4]}),vt=g({},lt,{firstChunkSize:4e4,ifd0:[274]}),pt=g({},lt,{tiff:!1,ifd1:!0,mergeOutput:!1}),yt=Object.freeze({1:{dimensionSwapped:!1,scaleX:1,scaleY:1,deg:0,rad:0},2:{dimensionSwapped:!1,scaleX:-1,scaleY:1,deg:0,rad:0},3:{dimensionSwapped:!1,scaleX:1,scaleY:1,deg:180,rad:180*Math.PI/180},4:{dimensionSwapped:!1,scaleX:-1,scaleY:1,deg:180,rad:180*Math.PI/180},5:{dimensionSwapped:!0,scaleX:1,scaleY:-1,deg:90,rad:90*Math.PI/180},6:{dimensionSwapped:!0,scaleX:1,scaleY:1,deg:90,rad:90*Math.PI/180},7:{dimensionSwapped:!0,scaleX:1,scaleY:-1,deg:270,rad:270*Math.PI/180},8:{dimensionSwapped:!0,scaleX:1,scaleY:1,deg:270,rad:270*Math.PI/180}});if(e.rotateCanvas=!0,e.rotateCss=!0,"object"==typeof navigator){var gt=navigator.userAgent;if(gt.includes("iPad")||gt.includes("iPhone")){var kt=gt.match(/OS (\d+)_(\d+)/);if(kt){var mt=kt[1],bt=kt[2],At=Number(mt)+.1*Number(bt);e.rotateCanvas=At<13.4,e.rotateCss=!1}}else if(gt.includes("OS X 10")){var wt=gt.match(/OS X 10[_.](\d+)/)[1];e.rotateCanvas=e.rotateCss=Number(wt)<15}if(gt.includes("Chrome/")){var Ot=gt.match(/Chrome\/(\d+)/)[1];e.rotateCanvas=e.rotateCss=Number(Ot)<81}else if(gt.includes("Firefox/")){var St=gt.match(/Firefox\/(\d+)/)[1];e.rotateCanvas=e.rotateCss=Number(St)<77}}function Pt(){}var Ut=function(e){a(u,e);var n=d(u);function u(){var e;t(this,u);for(var r=arguments.length,a=new Array(r),s=0;s<r;s++)a[s]=arguments[s];return i(h(e=n.call.apply(n,[this].concat(a))),"ranges",new xt),0!==e.byteLength&&e.ranges.add(0,e.byteLength),e}return r(u,[{key:"_tryExtend",value:function(e,t,n){if(0===e&&0===this.byteLength&&n){var r=new DataView(n.buffer||n,n.byteOffset,n.byteLength);this._swapDataView(r)}else{var i=e+t;if(i>this.byteLength){var a=this._extend(i).dataView;this._swapDataView(a)}}}},{key:"_extend",value:function(e){var t;t=_?j.allocUnsafe(e):new Uint8Array(e);var n=new DataView(t.buffer,t.byteOffset,t.byteLength);return t.set(new Uint8Array(this.buffer,this.byteOffset,this.byteLength),0),{uintView:t,dataView:n}}},{key:"subarray",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return t=t||this._lengthToEnd(e),n&&this._tryExtend(e,t),this.ranges.add(e,t),v(s(u.prototype),"subarray",this).call(this,e,t)}},{key:"set",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];n&&this._tryExtend(t,e.byteLength,e);var r=v(s(u.prototype),"set",this).call(this,e,t);return this.ranges.add(t,r.byteLength),r}},{key:"ensureChunk",value:function(e,t){try{var n=this;if(!n.chunked)return;if(n.ranges.available(e,t))return;return function(e,t){if(!t)return e&&e.then?e.then(Pt):Promise.resolve()}(n.readChunk(e,t))}catch(e){return Promise.reject(e)}}},{key:"available",value:function(e,t){return this.ranges.available(e,t)}}]),u}(D),xt=function(){function e(){t(this,e),i(this,"list",[])}return r(e,[{key:"length",get:function(){return this.list.length}},{key:"add",value:function(e,t){var n=e+t,r=this.list.filter((function(t){return Ct(e,t.offset,n)||Ct(e,t.end,n)}));if(r.length>0){e=Math.min.apply(Math,[e].concat(r.map((function(e){return e.offset})))),t=(n=Math.max.apply(Math,[n].concat(r.map((function(e){return e.end})))))-e;var i=r.shift();i.offset=e,i.length=t,i.end=n,this.list=this.list.filter((function(e){return!r.includes(e)}))}else this.list.push({offset:e,length:t,end:n})}},{key:"available",value:function(e,t){var n=e+t;return this.list.some((function(t){return t.offset<=e&&n<=t.end}))}}]),e}();function Ct(e,t,n){return e<=t&&t<=n}function Bt(){}function jt(e,t){if(!t)return e&&e.then?e.then(Bt):Promise.resolve()}function _t(e,t,n){return n?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var Vt=function(e){a(i,e);var n=d(i);function i(){return t(this,i),n.apply(this,arguments)}return r(i,[{key:"readWhole",value:function(){try{var e=this;return e.chunked=!1,_t(Y(e.input),(function(t){e._swapArrayBuffer(t)}))}catch(e){return Promise.reject(e)}}},{key:"readChunked",value:function(){return this.chunked=!0,this.size=this.input.size,v(s(i.prototype),"readChunked",this).call(this)}},{key:"_readChunk",value:function(e,t){try{var n=this,r=t?e+t:void 0,i=n.input.slice(e,r);return _t(Y(i),(function(t){return n.set(t,e,!0)}))}catch(e){return Promise.reject(e)}}}]),i}(function(e){a(s,e);var n=d(s);function s(e,r){var a;return t(this,s),i(h(a=n.call(this,0)),"chunksRead",0),a.input=e,a.options=r,a}return r(s,[{key:"readWhole",value:function(){try{var e=this;return e.chunked=!1,jt(e.readChunk(e.nextChunkOffset))}catch(e){return Promise.reject(e)}}},{key:"readChunked",value:function(){try{var e=this;return e.chunked=!0,jt(e.readChunk(0,e.options.firstChunkSize))}catch(e){return Promise.reject(e)}}},{key:"readNextChunk",value:function(e){try{var t=this;if(void 0===e&&(e=t.nextChunkOffset),t.fullyRead)return t.chunksRead++,!1;var n=t.options.chunkSize;return r=t.readChunk(e,n),i=function(e){return!!e&&e.byteLength===n},a?i?i(r):r:(r&&r.then||(r=Promise.resolve(r)),i?r.then(i):r)}catch(e){return Promise.reject(e)}var r,i,a}},{key:"readChunk",value:function(e,t){try{var n=this;if(n.chunksRead++,0===(t=n.safeWrapAddress(e,t)))return;return n._readChunk(e,t)}catch(e){return Promise.reject(e)}}},{key:"safeWrapAddress",value:function(e,t){return void 0!==this.size&&e+t>this.size?Math.max(0,this.size-e):t}},{key:"nextChunkOffset",get:function(){if(0!==this.ranges.list.length)return this.ranges.list[0].length}},{key:"canReadNextChunk",get:function(){return this.chunksRead<this.options.chunkLimit}},{key:"fullyRead",get:function(){return void 0!==this.size&&this.nextChunkOffset===this.size}},{key:"read",value:function(){return this.options.chunked?this.readChunked():this.readWhole()}},{key:"close",value:function(){}}]),s}(Ut));K.set("blob",Vt),e.Exifr=Ie,e.Options=Pe,e.allFormatters=be,e.chunkedProps=de,e.createDictionary=te,e.default=at,e.disableAllOptions=lt,e.extendDictionary=ne,e.fetchUrlAsArrayBuffer=G,e.fileParsers=M,e.fileReaders=K,e.gps=ft,e.gpsOnlyOptions=dt,e.inheritables=me,e.orientation=ot,e.orientationOnlyOptions=vt,e.otherSegments=ve,e.parse=Te,e.readBlobAsArrayBuffer=Y,e.rotation=function(t){return st(ot(t),(function(t){return g({canvas:e.rotateCanvas,css:e.rotateCss},yt[t])}))},e.rotations=yt,e.segmentParsers=W,e.segments=pe,e.segmentsAndBlocks=ge,e.tagKeys=re,e.tagRevivers=ae,e.tagValues=ie,e.thumbnail=ht,e.thumbnailOnlyOptions=pt,e.thumbnailUrl=ct,e.tiffBlocks=ye,e.tiffExtractables=ke,Object.defineProperty(e,"__esModule",{value:!0})}));
}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
},{"_process":39,"buffer":10}],25:[function(require,module,exports){
'use strict';
exports.__esModule = true;
exports.default = getFormData;
exports.getFieldData = getFieldData;
var NODE_LIST_CLASSES = {
'[object HTMLCollection]': true,
'[object NodeList]': true,
'[object RadioNodeList]': true
// .type values for elements which can appear in .elements and should be ignored
};var IGNORED_ELEMENT_TYPES = {
'button': true,
'fieldset': true,
'reset': true,
'submit': true
};
var CHECKED_INPUT_TYPES = {
'checkbox': true,
'radio': true
};
var TRIM_RE = /^\s+|\s+$/g;
var slice = Array.prototype.slice;
var toString = Object.prototype.toString;
/**
* @param {HTMLFormElement} form
* @param {Object} options
* @return {Object.<string,(string|Array.<string>)>} an object containing
* submittable value(s) held in the form's .elements collection, with
* properties named as per element names or ids.
*/
function getFormData(form) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { trim: false };
if (!form) {
throw new Error('A form is required by getFormData, was given form=' + form);
}
var data = {};
var elementName = void 0;
var elementNames = [];
var elementNameLookup = {};
// Get unique submittable element names for the form
for (var i = 0, l = form.elements.length; i < l; i++) {
var element = form.elements[i];
if (IGNORED_ELEMENT_TYPES[element.type] || element.disabled) {
continue;
}
elementName = element.name || element.id;
if (elementName && !elementNameLookup[elementName]) {
elementNames.push(elementName);
elementNameLookup[elementName] = true;
}
}
// Extract element data name-by-name for consistent handling of special cases
// around elements which contain multiple inputs.
for (var _i = 0, _l = elementNames.length; _i < _l; _i++) {
elementName = elementNames[_i];
var value = getFieldData(form, elementName, options);
if (value != null) {
data[elementName] = value;
}
}
return data;
}
/**
* @param {HTMLFormElement} form
* @param {string} fieldName
* @param {Object} options
* @return {(string|Array.<string>)} submittable value(s) in the form for a
* named element from its .elements collection, or null if there was no
* element with that name or the element had no submittable value(s).
*/
function getFieldData(form, fieldName) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { trim: false };
if (!form) {
throw new Error('A form is required by getFieldData, was given form=' + form);
}
if (!fieldName && toString.call(fieldName) !== '[object String]') {
throw new Error('A field name is required by getFieldData, was given fieldName=' + fieldName);
}
var element = form.elements[fieldName];
if (!element || element.disabled) {
return null;
}
if (!NODE_LIST_CLASSES[toString.call(element)]) {
return getFormElementValue(element, options.trim);
}
// Deal with multiple form controls which have the same name
var data = [];
var allRadios = true;
for (var i = 0, l = element.length; i < l; i++) {
if (element[i].disabled) {
continue;
}
if (allRadios && element[i].type !== 'radio') {
allRadios = false;
}
var value = getFormElementValue(element[i], options.trim);
if (value != null) {
data = data.concat(value);
}
}
// Special case for an element with multiple same-named inputs which were all
// radio buttons: if there was a selected value, only return the value.
if (allRadios && data.length === 1) {
return data[0];
}
return data.length > 0 ? data : null;
}
/**
* @param {HTMLElement} element a form element.
* @param {booleam} trim should values for text entry inputs be trimmed?
* @return {(string|Array.<string>|File|Array.<File>)} the element's submittable
* value(s), or null if it had none.
*/
function getFormElementValue(element, trim) {
var value = null;
var type = element.type;
if (type === 'select-one') {
if (element.options.length) {
value = element.options[element.selectedIndex].value;
}
return value;
}
if (type === 'select-multiple') {
value = [];
for (var i = 0, l = element.options.length; i < l; i++) {
if (element.options[i].selected) {
value.push(element.options[i].value);
}
}
if (value.length === 0) {
value = null;
}
return value;
}
// If a file input doesn't have a files attribute, fall through to using its
// value attribute.
if (type === 'file' && 'files' in element) {
if (element.multiple) {
value = slice.call(element.files);
if (value.length === 0) {
value = null;
}
} else {
// Should be null if not present, according to the spec
value = element.files[0];
}
return value;
}
if (!CHECKED_INPUT_TYPES[type]) {
value = trim ? element.value.replace(TRIM_RE, '') : element.value;
} else if (element.checked) {
value = element.value;
}
return value;
}
// For UMD build access to getFieldData
getFormData.getFieldData = getFieldData;
},{}],26:[function(require,module,exports){
(function (Buffer){(function (){
/* global Blob File */
/*
* Module requirements.
*/
var isArray = require('isarray');
var toString = Object.prototype.toString;
var withNativeBlob = typeof Blob === 'function' ||
typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]';
var withNativeFile = typeof File === 'function' ||
typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]';
/**
* Module exports.
*/
module.exports = hasBinary;
/**
* Checks for binary data.
*
* Supports Buffer, ArrayBuffer, Blob and File.
*
* @param {Object} anything
* @api public
*/
function hasBinary (obj) {
if (!obj || typeof obj !== 'object') {
return false;
}
if (isArray(obj)) {
for (var i = 0, l = obj.length; i < l; i++) {
if (hasBinary(obj[i])) {
return true;
}
}
return false;
}
if ((typeof Buffer === 'function' && Buffer.isBuffer && Buffer.isBuffer(obj)) ||
(typeof ArrayBuffer === 'function' && obj instanceof ArrayBuffer) ||
(withNativeBlob && obj instanceof Blob) ||
(withNativeFile && obj instanceof File)
) {
return true;
}
// see: https://github.com/Automattic/has-binary/pull/4
if (obj.toJSON && typeof obj.toJSON === 'function' && arguments.length === 1) {
return hasBinary(obj.toJSON(), true);
}
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {
return true;
}
}
return false;
}
}).call(this)}).call(this,require("buffer").Buffer)
},{"buffer":10,"isarray":27}],27:[function(require,module,exports){
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
},{}],28:[function(require,module,exports){
/**
* Module exports.
*
* Logic borrowed from Modernizr:
*
* - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
*/
try {
module.exports = typeof XMLHttpRequest !== 'undefined' &&
'withCredentials' in new XMLHttpRequest();
} catch (err) {
// if XMLHttp support is disabled in IE then it will throw
// when trying to create
module.exports = false;
}
},{}],29:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = ((value * c) - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
},{}],30:[function(require,module,exports){
var indexOf = [].indexOf;
module.exports = function(arr, obj){
if (indexOf) return arr.indexOf(obj);
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) return i;
}
return -1;
};
},{}],31:[function(require,module,exports){
module.exports = function isShallowEqual (a, b) {
if (a === b) return true
for (var i in a) if (!(i in b)) return false
for (var i in b) if (a[i] !== b[i]) return false
return true
}
},{}],32:[function(require,module,exports){
(function (global){(function (){
/*
* base64.js
*
* Licensed under the BSD 3-Clause License.
* http://opensource.org/licenses/BSD-3-Clause
*
* References:
* http://en.wikipedia.org/wiki/Base64
*/
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? module.exports = factory(global)
: typeof define === 'function' && define.amd
? define(factory) : factory(global)
}((
typeof self !== 'undefined' ? self
: typeof window !== 'undefined' ? window
: typeof global !== 'undefined' ? global
: this
), function(global) {
'use strict';
// existing version for noConflict()
global = global || {};
var _Base64 = global.Base64;
var version = "2.6.4";
// constants
var b64chars
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var b64tab = function(bin) {
var t = {};
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
return t;
}(b64chars);
var fromCharCode = String.fromCharCode;
// encoder stuff
var cb_utob = function(c) {
if (c.length < 2) {
var cc = c.charCodeAt(0);
return cc < 0x80 ? c
: cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
+ fromCharCode(0x80 | (cc & 0x3f)))
: (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
+ fromCharCode(0x80 | ( cc & 0x3f)));
} else {
var cc = 0x10000
+ (c.charCodeAt(0) - 0xD800) * 0x400
+ (c.charCodeAt(1) - 0xDC00);
return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
+ fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
+ fromCharCode(0x80 | ( cc & 0x3f)));
}
};
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
var utob = function(u) {
return u.replace(re_utob, cb_utob);
};
var cb_encode = function(ccc) {
var padlen = [0, 2, 1][ccc.length % 3],
ord = ccc.charCodeAt(0) << 16
| ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
| ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
chars = [
b64chars.charAt( ord >>> 18),
b64chars.charAt((ord >>> 12) & 63),
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
];
return chars.join('');
};
var btoa = global.btoa && typeof global.btoa == 'function'
? function(b){ return global.btoa(b) } : function(b) {
if (b.match(/[^\x00-\xFF]/)) throw new RangeError(
'The string contains invalid characters.'
);
return b.replace(/[\s\S]{1,3}/g, cb_encode);
};
var _encode = function(u) {
return btoa(utob(String(u)));
};
var mkUriSafe = function (b64) {
return b64.replace(/[+\/]/g, function(m0) {
return m0 == '+' ? '-' : '_';
}).replace(/=/g, '');
};
var encode = function(u, urisafe) {
return urisafe ? mkUriSafe(_encode(u)) : _encode(u);
};
var encodeURI = function(u) { return encode(u, true) };
var fromUint8Array;
if (global.Uint8Array) fromUint8Array = function(a, urisafe) {
// return btoa(fromCharCode.apply(null, a));
var b64 = '';
for (var i = 0, l = a.length; i < l; i += 3) {
var a0 = a[i], a1 = a[i+1], a2 = a[i+2];
var ord = a0 << 16 | a1 << 8 | a2;
b64 += b64chars.charAt( ord >>> 18)
+ b64chars.charAt((ord >>> 12) & 63)
+ ( typeof a1 != 'undefined'
? b64chars.charAt((ord >>> 6) & 63) : '=')
+ ( typeof a2 != 'undefined'
? b64chars.charAt( ord & 63) : '=');
}
return urisafe ? mkUriSafe(b64) : b64;
};
// decoder stuff
var re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
var cb_btou = function(cccc) {
switch(cccc.length) {
case 4:
var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
| ((0x3f & cccc.charCodeAt(1)) << 12)
| ((0x3f & cccc.charCodeAt(2)) << 6)
| (0x3f & cccc.charCodeAt(3)),
offset = cp - 0x10000;
return (fromCharCode((offset >>> 10) + 0xD800)
+ fromCharCode((offset & 0x3FF) + 0xDC00));
case 3:
return fromCharCode(
((0x0f & cccc.charCodeAt(0)) << 12)
| ((0x3f & cccc.charCodeAt(1)) << 6)
| (0x3f & cccc.charCodeAt(2))
);
default:
return fromCharCode(
((0x1f & cccc.charCodeAt(0)) << 6)
| (0x3f & cccc.charCodeAt(1))
);
}
};
var btou = function(b) {
return b.replace(re_btou, cb_btou);
};
var cb_decode = function(cccc) {
var len = cccc.length,
padlen = len % 4,
n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
| (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
| (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
| (len > 3 ? b64tab[cccc.charAt(3)] : 0),
chars = [
fromCharCode( n >>> 16),
fromCharCode((n >>> 8) & 0xff),
fromCharCode( n & 0xff)
];
chars.length -= [0, 0, 2, 1][padlen];
return chars.join('');
};
var _atob = global.atob && typeof global.atob == 'function'
? function(a){ return global.atob(a) } : function(a){
return a.replace(/\S{1,4}/g, cb_decode);
};
var atob = function(a) {
return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g, ''));
};
var _decode = function(a) { return btou(_atob(a)) };
var _fromURI = function(a) {
return String(a).replace(/[-_]/g, function(m0) {
return m0 == '-' ? '+' : '/'
}).replace(/[^A-Za-z0-9\+\/]/g, '');
};
var decode = function(a){
return _decode(_fromURI(a));
};
var toUint8Array;
if (global.Uint8Array) toUint8Array = function(a) {
return Uint8Array.from(atob(_fromURI(a)), function(c) {
return c.charCodeAt(0);
});
};
var noConflict = function() {
var Base64 = global.Base64;
global.Base64 = _Base64;
return Base64;
};
// export Base64
global.Base64 = {
VERSION: version,
atob: atob,
btoa: btoa,
fromBase64: decode,
toBase64: encode,
utob: utob,
encode: encode,
encodeURI: encodeURI,
btou: btou,
decode: decode,
noConflict: noConflict,
fromUint8Array: fromUint8Array,
toUint8Array: toUint8Array
};
// if ES5 is available, make Base64.extendString() available
if (typeof Object.defineProperty === 'function') {
var noEnum = function(v){
return {value:v,enumerable:false,writable:true,configurable:true};
};
global.Base64.extendString = function () {
Object.defineProperty(
String.prototype, 'fromBase64', noEnum(function () {
return decode(this)
}));
Object.defineProperty(
String.prototype, 'toBase64', noEnum(function (urisafe) {
return encode(this, urisafe)
}));
Object.defineProperty(
String.prototype, 'toBase64URI', noEnum(function () {
return encode(this, true)
}));
};
}
//
// export Base64 to the namespace
//
if (global['Meteor']) { // Meteor.js
Base64 = global.Base64;
}
// module.exports and AMD are mutually exclusive.
// module.exports has precedence.
if (typeof module !== 'undefined' && module.exports) {
module.exports.Base64 = global.Base64;
}
else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function(){ return global.Base64 });
}
// that's it!
return {Base64: global.Base64}
}));
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],33:[function(require,module,exports){
(function (global){(function (){
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Gets the timestamp of the number of milliseconds that have elapsed since
* the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @since 2.4.0
* @category Date
* @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => Logs the number of milliseconds it took for the deferred invocation.
*/
var now = function() {
return root.Date.now();
};
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // Avoid costly calculations while the window size is in flux.
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
* jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
result = wait - timeSinceLastCall;
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
var time = now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now());
}
function debounced() {
var time = now(),
isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime);
}
if (maxing) {
// Handle invocations in a tight loop.
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && objectToString.call(value) == symbolTag);
}
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
module.exports = debounce;
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],34:[function(require,module,exports){
(function (global){(function (){
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Gets the timestamp of the number of milliseconds that have elapsed since
* the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @since 2.4.0
* @category Date
* @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => Logs the number of milliseconds it took for the deferred invocation.
*/
var now = function() {
return root.Date.now();
};
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // Avoid costly calculations while the window size is in flux.
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
* jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
result = wait - timeSinceLastCall;
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
var time = now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now());
}
function debounced() {
var time = now(),
isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime);
}
if (maxing) {
// Handle invocations in a tight loop.
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. The throttled function comes with a `cancel`
* method to cancel delayed `func` invocations and a `flush` method to
* immediately invoke them. Provide `options` to indicate whether `func`
* should be invoked on the leading and/or trailing edge of the `wait`
* timeout. The `func` is invoked with the last arguments provided to the
* throttled function. Subsequent calls to the throttled function return the
* result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the throttled function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.throttle` and `_.debounce`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to throttle.
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=true]
* Specify invoking on the leading edge of the timeout.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new throttled function.
* @example
*
* // Avoid excessively updating the position while scrolling.
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
*
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
* jQuery(element).on('click', throttled);
*
* // Cancel the trailing throttled invocation.
* jQuery(window).on('popstate', throttled.cancel);
*/
function throttle(func, wait, options) {
var leading = true,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
return debounce(func, wait, {
'leading': leading,
'maxWait': wait,
'trailing': trailing
});
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && objectToString.call(value) == symbolTag);
}
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
module.exports = throttle;
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],35:[function(require,module,exports){
'use strict';
module.exports = Math.log2 || function (x) {
return Math.log(x) * Math.LOG2E;
};
},{}],36:[function(require,module,exports){
'use strict';
function areInputsEqual(newInputs, lastInputs) {
if (newInputs.length !== lastInputs.length) {
return false;
}
for (var i = 0; i < newInputs.length; i++) {
if (newInputs[i] !== lastInputs[i]) {
return false;
}
}
return true;
}
function memoizeOne(resultFn, isEqual) {
if (isEqual === void 0) { isEqual = areInputsEqual; }
var lastThis;
var lastArgs = [];
var lastResult;
var calledOnce = false;
function memoized() {
var newArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
newArgs[_i] = arguments[_i];
}
if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
return lastResult;
}
lastResult = resultFn.apply(this, newArgs);
calledOnce = true;
lastThis = this;
lastArgs = newArgs;
return lastResult;
}
return memoized;
}
module.exports = memoizeOne;
},{}],37:[function(require,module,exports){
var wildcard = require('wildcard');
var reMimePartSplit = /[\/\+\.]/;
/**
# mime-match
A simple function to checker whether a target mime type matches a mime-type
pattern (e.g. image/jpeg matches image/jpeg OR image/*).
## Example Usage
<<< example.js
**/
module.exports = function(target, pattern) {
function test(pattern) {
var result = wildcard(pattern, target, reMimePartSplit);
// ensure that we have a valid mime type (should have two parts)
return result && result.length >= 2;
}
return pattern ? test(pattern.split(';')[0]) : test;
};
},{"wildcard":61}],38:[function(require,module,exports){
/**
* Create an event emitter with namespaces
* @name createNamespaceEmitter
* @example
* var emitter = require('./index')()
*
* emitter.on('*', function () {
* console.log('all events emitted', this.event)
* })
*
* emitter.on('example', function () {
* console.log('example event emitted')
* })
*/
module.exports = function createNamespaceEmitter () {
var emitter = {}
var _fns = emitter._fns = {}
/**
* Emit an event. Optionally namespace the event. Handlers are fired in the order in which they were added with exact matches taking precedence. Separate the namespace and event with a `:`
* @name emit
* @param {String} event – the name of the event, with optional namespace
* @param {...*} data – up to 6 arguments that are passed to the event listener
* @example
* emitter.emit('example')
* emitter.emit('demo:test')
* emitter.emit('data', { example: true}, 'a string', 1)
*/
emitter.emit = function emit (event, arg1, arg2, arg3, arg4, arg5, arg6) {
var toEmit = getListeners(event)
if (toEmit.length) {
emitAll(event, toEmit, [arg1, arg2, arg3, arg4, arg5, arg6])
}
}
/**
* Create en event listener.
* @name on
* @param {String} event
* @param {Function} fn
* @example
* emitter.on('example', function () {})
* emitter.on('demo', function () {})
*/
emitter.on = function on (event, fn) {
if (!_fns[event]) {
_fns[event] = []
}
_fns[event].push(fn)
}
/**
* Create en event listener that fires once.
* @name once
* @param {String} event
* @param {Function} fn
* @example
* emitter.once('example', function () {})
* emitter.once('demo', function () {})
*/
emitter.once = function once (event, fn) {
function one () {
fn.apply(this, arguments)
emitter.off(event, one)
}
this.on(event, one)
}
/**
* Stop listening to an event. Stop all listeners on an event by only passing the event name. Stop a single listener by passing that event handler as a callback.
* You must be explicit about what will be unsubscribed: `emitter.off('demo')` will unsubscribe an `emitter.on('demo')` listener,
* `emitter.off('demo:example')` will unsubscribe an `emitter.on('demo:example')` listener
* @name off
* @param {String} event
* @param {Function} [fn] – the specific handler
* @example
* emitter.off('example')
* emitter.off('demo', function () {})
*/
emitter.off = function off (event, fn) {
var keep = []
if (event && fn) {
var fns = this._fns[event]
var i = 0
var l = fns ? fns.length : 0
for (i; i < l; i++) {
if (fns[i] !== fn) {
keep.push(fns[i])
}
}
}
keep.length ? this._fns[event] = keep : delete this._fns[event]
}
function getListeners (e) {
var out = _fns[e] ? _fns[e] : []
var idx = e.indexOf(':')
var args = (idx === -1) ? [e] : [e.substring(0, idx), e.substring(idx + 1)]
var keys = Object.keys(_fns)
var i = 0
var l = keys.length
for (i; i < l; i++) {
var key = keys[i]
if (key === '*') {
out = out.concat(_fns[key])
}
if (args.length === 2 && args[0] === key) {
out = out.concat(_fns[key])
break
}
}
return out
}
function emitAll (e, fns, args) {
var i = 0
var l = fns.length
for (i; i < l; i++) {
if (!fns[i]) break
fns[i].event = e
fns[i].apply(fns[i], args)
}
}
return emitter
}
},{}],39:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],40:[function(require,module,exports){
var has = Object.prototype.hasOwnProperty
/**
* Stringify an object for use in a query string.
*
* @param {Object} obj - The object.
* @param {string} prefix - When nesting, the parent key.
* keys in `obj` will be stringified as `prefix[key]`.
* @returns {string}
*/
module.exports = function queryStringify (obj, prefix) {
var pairs = []
for (var key in obj) {
if (!has.call(obj, key)) {
continue
}
var value = obj[key]
var enkey = encodeURIComponent(key)
var pair
if (typeof value === 'object') {
pair = queryStringify(value, prefix ? prefix + '[' + enkey + ']' : enkey)
} else {
pair = (prefix ? prefix + '[' + enkey + ']' : enkey) + '=' + encodeURIComponent(value)
}
pairs.push(pair)
}
return pairs.join('&')
}
},{}],41:[function(require,module,exports){
'use strict';
var has = Object.prototype.hasOwnProperty
, undef;
/**
* Decode a URI encoded string.
*
* @param {String} input The URI encoded string.
* @returns {String|Null} The decoded string.
* @api private
*/
function decode(input) {
try {
return decodeURIComponent(input.replace(/\+/g, ' '));
} catch (e) {
return null;
}
}
/**
* Attempts to encode a given input.
*
* @param {String} input The string that needs to be encoded.
* @returns {String|Null} The encoded string.
* @api private
*/
function encode(input) {
try {
return encodeURIComponent(input);
} catch (e) {
return null;
}
}
/**
* Simple query string parser.
*
* @param {String} query The query string that needs to be parsed.
* @returns {Object}
* @api public
*/
function querystring(query) {
var parser = /([^=?#&]+)=?([^&]*)/g
, result = {}
, part;
while (part = parser.exec(query)) {
var key = decode(part[1])
, value = decode(part[2]);
//
// Prevent overriding of existing properties. This ensures that build-in
// methods like `toString` or __proto__ are not overriden by malicious
// querystrings.
//
// In the case if failed decoding, we want to omit the key/value pairs
// from the result.
//
if (key === null || value === null || key in result) continue;
result[key] = value;
}
return result;
}
/**
* Transform a query string to an object.
*
* @param {Object} obj Object that should be transformed.
* @param {String} prefix Optional prefix.
* @returns {String}
* @api public
*/
function querystringify(obj, prefix) {
prefix = prefix || '';
var pairs = []
, value
, key;
//
// Optionally prefix with a '?' if needed
//
if ('string' !== typeof prefix) prefix = '?';
for (key in obj) {
if (has.call(obj, key)) {
value = obj[key];
//
// Edge cases where we actually want to encode the value to an empty
// string instead of the stringified value.
//
if (!value && (value === null || value === undef || isNaN(value))) {
value = '';
}
key = encode(key);
value = encode(value);
//
// If we failed to encode the strings, we should bail out as we don't
// want to add invalid strings to the query.
//
if (key === null || value === null) continue;
pairs.push(key +'='+ value);
}
}
return pairs.length ? prefix + pairs.join('&') : '';
}
//
// Expose the module.
//
exports.stringify = querystringify;
exports.parse = querystring;
},{}],42:[function(require,module,exports){
'use strict';
/**
* Check if we're required to add a port number.
*
* @see https://url.spec.whatwg.org/#default-port
* @param {Number|String} port Port number we need to check
* @param {String} protocol Protocol we need to check against.
* @returns {Boolean} Is it a default port for the given protocol
* @api private
*/
module.exports = function required(port, protocol) {
protocol = protocol.split(':')[0];
port = +port;
if (!port) return false;
switch (protocol) {
case 'http':
case 'ws':
return port !== 80;
case 'https':
case 'wss':
return port !== 443;
case 'ftp':
return port !== 21;
case 'gopher':
return port !== 70;
case 'file':
return false;
}
return port !== 0;
};
},{}],43:[function(require,module,exports){
(function (global){(function (){
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.ResizeObserver = factory());
}(this, (function () { 'use strict';
/**
* A collection of shims that provide minimal functionality of the ES6 collections.
*
* These implementations are not meant to be used outside of the ResizeObserver
* modules as they cover only a limited range of use cases.
*/
/* eslint-disable require-jsdoc, valid-jsdoc */
var MapShim = (function () {
if (typeof Map !== 'undefined') {
return Map;
}
/**
* Returns index in provided array that matches the specified key.
*
* @param {Array<Array>} arr
* @param {*} key
* @returns {number}
*/
function getIndex(arr, key) {
var result = -1;
arr.some(function (entry, index) {
if (entry[0] === key) {
result = index;
return true;
}
return false;
});
return result;
}
return /** @class */ (function () {
function class_1() {
this.__entries__ = [];
}
Object.defineProperty(class_1.prototype, "size", {
/**
* @returns {boolean}
*/
get: function () {
return this.__entries__.length;
},
enumerable: true,
configurable: true
});
/**
* @param {*} key
* @returns {*}
*/
class_1.prototype.get = function (key) {
var index = getIndex(this.__entries__, key);
var entry = this.__entries__[index];
return entry && entry[1];
};
/**
* @param {*} key
* @param {*} value
* @returns {void}
*/
class_1.prototype.set = function (key, value) {
var index = getIndex(this.__entries__, key);
if (~index) {
this.__entries__[index][1] = value;
}
else {
this.__entries__.push([key, value]);
}
};
/**
* @param {*} key
* @returns {void}
*/
class_1.prototype.delete = function (key) {
var entries = this.__entries__;
var index = getIndex(entries, key);
if (~index) {
entries.splice(index, 1);
}
};
/**
* @param {*} key
* @returns {void}
*/
class_1.prototype.has = function (key) {
return !!~getIndex(this.__entries__, key);
};
/**
* @returns {void}
*/
class_1.prototype.clear = function () {
this.__entries__.splice(0);
};
/**
* @param {Function} callback
* @param {*} [ctx=null]
* @returns {void}
*/
class_1.prototype.forEach = function (callback, ctx) {
if (ctx === void 0) { ctx = null; }
for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {
var entry = _a[_i];
callback.call(ctx, entry[1], entry[0]);
}
};
return class_1;
}());
})();
/**
* Detects whether window and document objects are available in current environment.
*/
var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;
// Returns global object of a current environment.
var global$1 = (function () {
if (typeof global !== 'undefined' && global.Math === Math) {
return global;
}
if (typeof self !== 'undefined' && self.Math === Math) {
return self;
}
if (typeof window !== 'undefined' && window.Math === Math) {
return window;
}
// eslint-disable-next-line no-new-func
return Function('return this')();
})();
/**
* A shim for the requestAnimationFrame which falls back to the setTimeout if
* first one is not supported.
*
* @returns {number} Requests' identifier.
*/
var requestAnimationFrame$1 = (function () {
if (typeof requestAnimationFrame === 'function') {
// It's required to use a bounded function because IE sometimes throws
// an "Invalid calling object" error if rAF is invoked without the global
// object on the left hand side.
return requestAnimationFrame.bind(global$1);
}
return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
})();
// Defines minimum timeout before adding a trailing call.
var trailingTimeout = 2;
/**
* Creates a wrapper function which ensures that provided callback will be
* invoked only once during the specified delay period.
*
* @param {Function} callback - Function to be invoked after the delay period.
* @param {number} delay - Delay after which to invoke callback.
* @returns {Function}
*/
function throttle (callback, delay) {
var leadingCall = false, trailingCall = false, lastCallTime = 0;
/**
* Invokes the original callback function and schedules new invocation if
* the "proxy" was called during current request.
*
* @returns {void}
*/
function resolvePending() {
if (leadingCall) {
leadingCall = false;
callback();
}
if (trailingCall) {
proxy();
}
}
/**
* Callback invoked after the specified delay. It will further postpone
* invocation of the original function delegating it to the
* requestAnimationFrame.
*
* @returns {void}
*/
function timeoutCallback() {
requestAnimationFrame$1(resolvePending);
}
/**
* Schedules invocation of the original function.
*
* @returns {void}
*/
function proxy() {
var timeStamp = Date.now();
if (leadingCall) {
// Reject immediately following calls.
if (timeStamp - lastCallTime < trailingTimeout) {
return;
}
// Schedule new call to be in invoked when the pending one is resolved.
// This is important for "transitions" which never actually start
// immediately so there is a chance that we might miss one if change
// happens amids the pending invocation.
trailingCall = true;
}
else {
leadingCall = true;
trailingCall = false;
setTimeout(timeoutCallback, delay);
}
lastCallTime = timeStamp;
}
return proxy;
}
// Minimum delay before invoking the update of observers.
var REFRESH_DELAY = 20;
// A list of substrings of CSS properties used to find transition events that
// might affect dimensions of observed elements.
var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
// Check if MutationObserver is available.
var mutationObserverSupported = typeof MutationObserver !== 'undefined';
/**
* Singleton controller class which handles updates of ResizeObserver instances.
*/
var ResizeObserverController = /** @class */ (function () {
/**
* Creates a new instance of ResizeObserverController.
*
* @private
*/
function ResizeObserverController() {
/**
* Indicates whether DOM listeners have been added.
*
* @private {boolean}
*/
this.connected_ = false;
/**
* Tells that controller has subscribed for Mutation Events.
*
* @private {boolean}
*/
this.mutationEventsAdded_ = false;
/**
* Keeps reference to the instance of MutationObserver.
*
* @private {MutationObserver}
*/
this.mutationsObserver_ = null;
/**
* A list of connected observers.
*
* @private {Array<ResizeObserverSPI>}
*/
this.observers_ = [];
this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);
}
/**
* Adds observer to observers list.
*
* @param {ResizeObserverSPI} observer - Observer to be added.
* @returns {void}
*/
ResizeObserverController.prototype.addObserver = function (observer) {
if (!~this.observers_.indexOf(observer)) {
this.observers_.push(observer);
}
// Add listeners if they haven't been added yet.
if (!this.connected_) {
this.connect_();
}
};
/**
* Removes observer from observers list.
*
* @param {ResizeObserverSPI} observer - Observer to be removed.
* @returns {void}
*/
ResizeObserverController.prototype.removeObserver = function (observer) {
var observers = this.observers_;
var index = observers.indexOf(observer);
// Remove observer if it's present in registry.
if (~index) {
observers.splice(index, 1);
}
// Remove listeners if controller has no connected observers.
if (!observers.length && this.connected_) {
this.disconnect_();
}
};
/**
* Invokes the update of observers. It will continue running updates insofar
* it detects changes.
*
* @returns {void}
*/
ResizeObserverController.prototype.refresh = function () {
var changesDetected = this.updateObservers_();
// Continue running updates if changes have been detected as there might
// be future ones caused by CSS transitions.
if (changesDetected) {
this.refresh();
}
};
/**
* Updates every observer from observers list and notifies them of queued
* entries.
*
* @private
* @returns {boolean} Returns "true" if any observer has detected changes in
* dimensions of it's elements.
*/
ResizeObserverController.prototype.updateObservers_ = function () {
// Collect observers that have active observations.
var activeObservers = this.observers_.filter(function (observer) {
return observer.gatherActive(), observer.hasActive();
});
// Deliver notifications in a separate cycle in order to avoid any
// collisions between observers, e.g. when multiple instances of
// ResizeObserver are tracking the same element and the callback of one
// of them changes content dimensions of the observed target. Sometimes
// this may result in notifications being blocked for the rest of observers.
activeObservers.forEach(function (observer) { return observer.broadcastActive(); });
return activeObservers.length > 0;
};
/**
* Initializes DOM listeners.
*
* @private
* @returns {void}
*/
ResizeObserverController.prototype.connect_ = function () {
// Do nothing if running in a non-browser environment or if listeners
// have been already added.
if (!isBrowser || this.connected_) {
return;
}
// Subscription to the "Transitionend" event is used as a workaround for
// delayed transitions. This way it's possible to capture at least the
// final state of an element.
document.addEventListener('transitionend', this.onTransitionEnd_);
window.addEventListener('resize', this.refresh);
if (mutationObserverSupported) {
this.mutationsObserver_ = new MutationObserver(this.refresh);
this.mutationsObserver_.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree: true
});
}
else {
document.addEventListener('DOMSubtreeModified', this.refresh);
this.mutationEventsAdded_ = true;
}
this.connected_ = true;
};
/**
* Removes DOM listeners.
*
* @private
* @returns {void}
*/
ResizeObserverController.prototype.disconnect_ = function () {
// Do nothing if running in a non-browser environment or if listeners
// have been already removed.
if (!isBrowser || !this.connected_) {
return;
}
document.removeEventListener('transitionend', this.onTransitionEnd_);
window.removeEventListener('resize', this.refresh);
if (this.mutationsObserver_) {
this.mutationsObserver_.disconnect();
}
if (this.mutationEventsAdded_) {
document.removeEventListener('DOMSubtreeModified', this.refresh);
}
this.mutationsObserver_ = null;
this.mutationEventsAdded_ = false;
this.connected_ = false;
};
/**
* "Transitionend" event handler.
*
* @private
* @param {TransitionEvent} event
* @returns {void}
*/
ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {
var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;
// Detect whether transition may affect dimensions of an element.
var isReflowProperty = transitionKeys.some(function (key) {
return !!~propertyName.indexOf(key);
});
if (isReflowProperty) {
this.refresh();
}
};
/**
* Returns instance of the ResizeObserverController.
*
* @returns {ResizeObserverController}
*/
ResizeObserverController.getInstance = function () {
if (!this.instance_) {
this.instance_ = new ResizeObserverController();
}
return this.instance_;
};
/**
* Holds reference to the controller's instance.
*
* @private {ResizeObserverController}
*/
ResizeObserverController.instance_ = null;
return ResizeObserverController;
}());
/**
* Defines non-writable/enumerable properties of the provided target object.
*
* @param {Object} target - Object for which to define properties.
* @param {Object} props - Properties to be defined.
* @returns {Object} Target object.
*/
var defineConfigurable = (function (target, props) {
for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {
var key = _a[_i];
Object.defineProperty(target, key, {
value: props[key],
enumerable: false,
writable: false,
configurable: true
});
}
return target;
});
/**
* Returns the global object associated with provided element.
*
* @param {Object} target
* @returns {Object}
*/
var getWindowOf = (function (target) {
// Assume that the element is an instance of Node, which means that it
// has the "ownerDocument" property from which we can retrieve a
// corresponding global object.
var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
// Return the local global object if it's not possible extract one from
// provided element.
return ownerGlobal || global$1;
});
// Placeholder of an empty content rectangle.
var emptyRect = createRectInit(0, 0, 0, 0);
/**
* Converts provided string to a number.
*
* @param {number|string} value
* @returns {number}
*/
function toFloat(value) {
return parseFloat(value) || 0;
}
/**
* Extracts borders size from provided styles.
*
* @param {CSSStyleDeclaration} styles
* @param {...string} positions - Borders positions (top, right, ...)
* @returns {number}
*/
function getBordersSize(styles) {
var positions = [];
for (var _i = 1; _i < arguments.length; _i++) {
positions[_i - 1] = arguments[_i];
}
return positions.reduce(function (size, position) {
var value = styles['border-' + position + '-width'];
return size + toFloat(value);
}, 0);
}
/**
* Extracts paddings sizes from provided styles.
*
* @param {CSSStyleDeclaration} styles
* @returns {Object} Paddings box.
*/
function getPaddings(styles) {
var positions = ['top', 'right', 'bottom', 'left'];
var paddings = {};
for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {
var position = positions_1[_i];
var value = styles['padding-' + position];
paddings[position] = toFloat(value);
}
return paddings;
}
/**
* Calculates content rectangle of provided SVG element.
*
* @param {SVGGraphicsElement} target - Element content rectangle of which needs
* to be calculated.
* @returns {DOMRectInit}
*/
function getSVGContentRect(target) {
var bbox = target.getBBox();
return createRectInit(0, 0, bbox.width, bbox.height);
}
/**
* Calculates content rectangle of provided HTMLElement.
*
* @param {HTMLElement} target - Element for which to calculate the content rectangle.
* @returns {DOMRectInit}
*/
function getHTMLElementContentRect(target) {
// Client width & height properties can't be
// used exclusively as they provide rounded values.
var clientWidth = target.clientWidth, clientHeight = target.clientHeight;
// By this condition we can catch all non-replaced inline, hidden and
// detached elements. Though elements with width & height properties less
// than 0.5 will be discarded as well.
//
// Without it we would need to implement separate methods for each of
// those cases and it's not possible to perform a precise and performance
// effective test for hidden elements. E.g. even jQuery's ':visible' filter
// gives wrong results for elements with width & height less than 0.5.
if (!clientWidth && !clientHeight) {
return emptyRect;
}
var styles = getWindowOf(target).getComputedStyle(target);
var paddings = getPaddings(styles);
var horizPad = paddings.left + paddings.right;
var vertPad = paddings.top + paddings.bottom;
// Computed styles of width & height are being used because they are the
// only dimensions available to JS that contain non-rounded values. It could
// be possible to utilize the getBoundingClientRect if only it's data wasn't
// affected by CSS transformations let alone paddings, borders and scroll bars.
var width = toFloat(styles.width), height = toFloat(styles.height);
// Width & height include paddings and borders when the 'border-box' box
// model is applied (except for IE).
if (styles.boxSizing === 'border-box') {
// Following conditions are required to handle Internet Explorer which
// doesn't include paddings and borders to computed CSS dimensions.
//
// We can say that if CSS dimensions + paddings are equal to the "client"
// properties then it's either IE, and thus we don't need to subtract
// anything, or an element merely doesn't have paddings/borders styles.
if (Math.round(width + horizPad) !== clientWidth) {
width -= getBordersSize(styles, 'left', 'right') + horizPad;
}
if (Math.round(height + vertPad) !== clientHeight) {
height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
}
}
// Following steps can't be applied to the document's root element as its
// client[Width/Height] properties represent viewport area of the window.
// Besides, it's as well not necessary as the <html> itself neither has
// rendered scroll bars nor it can be clipped.
if (!isDocumentElement(target)) {
// In some browsers (only in Firefox, actually) CSS width & height
// include scroll bars size which can be removed at this step as scroll
// bars are the only difference between rounded dimensions + paddings
// and "client" properties, though that is not always true in Chrome.
var vertScrollbar = Math.round(width + horizPad) - clientWidth;
var horizScrollbar = Math.round(height + vertPad) - clientHeight;
// Chrome has a rather weird rounding of "client" properties.
// E.g. for an element with content width of 314.2px it sometimes gives
// the client width of 315px and for the width of 314.7px it may give
// 314px. And it doesn't happen all the time. So just ignore this delta
// as a non-relevant.
if (Math.abs(vertScrollbar) !== 1) {
width -= vertScrollbar;
}
if (Math.abs(horizScrollbar) !== 1) {
height -= horizScrollbar;
}
}
return createRectInit(paddings.left, paddings.top, width, height);
}
/**
* Checks whether provided element is an instance of the SVGGraphicsElement.
*
* @param {Element} target - Element to be checked.
* @returns {boolean}
*/
var isSVGGraphicsElement = (function () {
// Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
// interface.
if (typeof SVGGraphicsElement !== 'undefined') {
return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
}
// If it's so, then check that element is at least an instance of the
// SVGElement and that it has the "getBBox" method.
// eslint-disable-next-line no-extra-parens
return function (target) { return (target instanceof getWindowOf(target).SVGElement &&
typeof target.getBBox === 'function'); };
})();
/**
* Checks whether provided element is a document element (<html>).
*
* @param {Element} target - Element to be checked.
* @returns {boolean}
*/
function isDocumentElement(target) {
return target === getWindowOf(target).document.documentElement;
}
/**
* Calculates an appropriate content rectangle for provided html or svg element.
*
* @param {Element} target - Element content rectangle of which needs to be calculated.
* @returns {DOMRectInit}
*/
function getContentRect(target) {
if (!isBrowser) {
return emptyRect;
}
if (isSVGGraphicsElement(target)) {
return getSVGContentRect(target);
}
return getHTMLElementContentRect(target);
}
/**
* Creates rectangle with an interface of the DOMRectReadOnly.
* Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
*
* @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
* @returns {DOMRectReadOnly}
*/
function createReadOnlyRect(_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
// If DOMRectReadOnly is available use it as a prototype for the rectangle.
var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
var rect = Object.create(Constr.prototype);
// Rectangle's properties are not writable and non-enumerable.
defineConfigurable(rect, {
x: x, y: y, width: width, height: height,
top: y,
right: x + width,
bottom: height + y,
left: x
});
return rect;
}
/**
* Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
* Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
*
* @param {number} x - X coordinate.
* @param {number} y - Y coordinate.
* @param {number} width - Rectangle's width.
* @param {number} height - Rectangle's height.
* @returns {DOMRectInit}
*/
function createRectInit(x, y, width, height) {
return { x: x, y: y, width: width, height: height };
}
/**
* Class that is responsible for computations of the content rectangle of
* provided DOM element and for keeping track of it's changes.
*/
var ResizeObservation = /** @class */ (function () {
/**
* Creates an instance of ResizeObservation.
*
* @param {Element} target - Element to be observed.
*/
function ResizeObservation(target) {
/**
* Broadcasted width of content rectangle.
*
* @type {number}
*/
this.broadcastWidth = 0;
/**
* Broadcasted height of content rectangle.
*
* @type {number}
*/
this.broadcastHeight = 0;
/**
* Reference to the last observed content rectangle.
*
* @private {DOMRectInit}
*/
this.contentRect_ = createRectInit(0, 0, 0, 0);
this.target = target;
}
/**
* Updates content rectangle and tells whether it's width or height properties
* have changed since the last broadcast.
*
* @returns {boolean}
*/
ResizeObservation.prototype.isActive = function () {
var rect = getContentRect(this.target);
this.contentRect_ = rect;
return (rect.width !== this.broadcastWidth ||
rect.height !== this.broadcastHeight);
};
/**
* Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
* from the corresponding properties of the last observed content rectangle.
*
* @returns {DOMRectInit} Last observed content rectangle.
*/
ResizeObservation.prototype.broadcastRect = function () {
var rect = this.contentRect_;
this.broadcastWidth = rect.width;
this.broadcastHeight = rect.height;
return rect;
};
return ResizeObservation;
}());
var ResizeObserverEntry = /** @class */ (function () {
/**
* Creates an instance of ResizeObserverEntry.
*
* @param {Element} target - Element that is being observed.
* @param {DOMRectInit} rectInit - Data of the element's content rectangle.
*/
function ResizeObserverEntry(target, rectInit) {
var contentRect = createReadOnlyRect(rectInit);
// According to the specification following properties are not writable
// and are also not enumerable in the native implementation.
//
// Property accessors are not being used as they'd require to define a
// private WeakMap storage which may cause memory leaks in browsers that
// don't support this type of collections.
defineConfigurable(this, { target: target, contentRect: contentRect });
}
return ResizeObserverEntry;
}());
var ResizeObserverSPI = /** @class */ (function () {
/**
* Creates a new instance of ResizeObserver.
*
* @param {ResizeObserverCallback} callback - Callback function that is invoked
* when one of the observed elements changes it's content dimensions.
* @param {ResizeObserverController} controller - Controller instance which
* is responsible for the updates of observer.
* @param {ResizeObserver} callbackCtx - Reference to the public
* ResizeObserver instance which will be passed to callback function.
*/
function ResizeObserverSPI(callback, controller, callbackCtx) {
/**
* Collection of resize observations that have detected changes in dimensions
* of elements.
*
* @private {Array<ResizeObservation>}
*/
this.activeObservations_ = [];
/**
* Registry of the ResizeObservation instances.
*
* @private {Map<Element, ResizeObservation>}
*/
this.observations_ = new MapShim();
if (typeof callback !== 'function') {
throw new TypeError('The callback provided as parameter 1 is not a function.');
}
this.callback_ = callback;
this.controller_ = controller;
this.callbackCtx_ = callbackCtx;
}
/**
* Starts observing provided element.
*
* @param {Element} target - Element to be observed.
* @returns {void}
*/
ResizeObserverSPI.prototype.observe = function (target) {
if (!arguments.length) {
throw new TypeError('1 argument required, but only 0 present.');
}
// Do nothing if current environment doesn't have the Element interface.
if (typeof Element === 'undefined' || !(Element instanceof Object)) {
return;
}
if (!(target instanceof getWindowOf(target).Element)) {
throw new TypeError('parameter 1 is not of type "Element".');
}
var observations = this.observations_;
// Do nothing if element is already being observed.
if (observations.has(target)) {
return;
}
observations.set(target, new ResizeObservation(target));
this.controller_.addObserver(this);
// Force the update of observations.
this.controller_.refresh();
};
/**
* Stops observing provided element.
*
* @param {Element} target - Element to stop observing.
* @returns {void}
*/
ResizeObserverSPI.prototype.unobserve = function (target) {
if (!arguments.length) {
throw new TypeError('1 argument required, but only 0 present.');
}
// Do nothing if current environment doesn't have the Element interface.
if (typeof Element === 'undefined' || !(Element instanceof Object)) {
return;
}
if (!(target instanceof getWindowOf(target).Element)) {
throw new TypeError('parameter 1 is not of type "Element".');
}
var observations = this.observations_;
// Do nothing if element is not being observed.
if (!observations.has(target)) {
return;
}
observations.delete(target);
if (!observations.size) {
this.controller_.removeObserver(this);
}
};
/**
* Stops observing all elements.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.disconnect = function () {
this.clearActive();
this.observations_.clear();
this.controller_.removeObserver(this);
};
/**
* Collects observation instances the associated element of which has changed
* it's content rectangle.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.gatherActive = function () {
var _this = this;
this.clearActive();
this.observations_.forEach(function (observation) {
if (observation.isActive()) {
_this.activeObservations_.push(observation);
}
});
};
/**
* Invokes initial callback function with a list of ResizeObserverEntry
* instances collected from active resize observations.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.broadcastActive = function () {
// Do nothing if observer doesn't have active observations.
if (!this.hasActive()) {
return;
}
var ctx = this.callbackCtx_;
// Create ResizeObserverEntry instance for every active observation.
var entries = this.activeObservations_.map(function (observation) {
return new ResizeObserverEntry(observation.target, observation.broadcastRect());
});
this.callback_.call(ctx, entries, ctx);
this.clearActive();
};
/**
* Clears the collection of active observations.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.clearActive = function () {
this.activeObservations_.splice(0);
};
/**
* Tells whether observer has active observations.
*
* @returns {boolean}
*/
ResizeObserverSPI.prototype.hasActive = function () {
return this.activeObservations_.length > 0;
};
return ResizeObserverSPI;
}());
// Registry of internal observers. If WeakMap is not available use current shim
// for the Map collection as it has all required methods and because WeakMap
// can't be fully polyfilled anyway.
var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
/**
* ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
* exposing only those methods and properties that are defined in the spec.
*/
var ResizeObserver = /** @class */ (function () {
/**
* Creates a new instance of ResizeObserver.
*
* @param {ResizeObserverCallback} callback - Callback that is invoked when
* dimensions of the observed elements change.
*/
function ResizeObserver(callback) {
if (!(this instanceof ResizeObserver)) {
throw new TypeError('Cannot call a class as a function.');
}
if (!arguments.length) {
throw new TypeError('1 argument required, but only 0 present.');
}
var controller = ResizeObserverController.getInstance();
var observer = new ResizeObserverSPI(callback, controller, this);
observers.set(this, observer);
}
return ResizeObserver;
}());
// Expose public methods of ResizeObserver.
[
'observe',
'unobserve',
'disconnect'
].forEach(function (method) {
ResizeObserver.prototype[method] = function () {
var _a;
return (_a = observers.get(this))[method].apply(_a, arguments);
};
});
var index = (function () {
// Export existing implementation if available.
if (typeof global$1.ResizeObserver !== 'undefined') {
return global$1.ResizeObserver;
}
return ResizeObserver;
})();
return index;
})));
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],44:[function(require,module,exports){
module.exports = toArray
function toArray(list, index) {
var array = []
index = index || 0
for (var i = index || 0; i < list.length; i++) {
array[i - index] = list[i]
}
return array
}
},{}],45:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _isReactNative = _interopRequireDefault(require("./isReactNative"));
var _uriToBlob = _interopRequireDefault(require("./uriToBlob"));
var _isCordova = _interopRequireDefault(require("./isCordova"));
var _readAsByteArray = _interopRequireDefault(require("./readAsByteArray"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var FileSource = /*#__PURE__*/function () {
// Make this.size a method
function FileSource(file) {
_classCallCheck(this, FileSource);
this._file = file;
this.size = file.size;
}
_createClass(FileSource, [{
key: "slice",
value: function slice(start, end) {
// In Apache Cordova applications, a File must be resolved using
// FileReader instances, see
// https://cordova.apache.org/docs/en/8.x/reference/cordova-plugin-file/index.html#read-a-file
if ((0, _isCordova.default)()) {
return (0, _readAsByteArray.default)(this._file.slice(start, end));
}
var value = this._file.slice(start, end);
return Promise.resolve({
value: value
});
}
}, {
key: "close",
value: function close() {// Nothing to do here since we don't need to release any resources.
}
}]);
return FileSource;
}();
var StreamSource = /*#__PURE__*/function () {
function StreamSource(reader, chunkSize) {
_classCallCheck(this, StreamSource);
this._chunkSize = chunkSize;
this._buffer = undefined;
this._bufferOffset = 0;
this._reader = reader;
this._done = false;
}
_createClass(StreamSource, [{
key: "slice",
value: function slice(start, end) {
if (start < this._bufferOffset) {
return Promise.reject(new Error("Requested data is before the reader's current offset"));
}
return this._readUntilEnoughDataOrDone(start, end);
}
}, {
key: "_readUntilEnoughDataOrDone",
value: function _readUntilEnoughDataOrDone(start, end) {
var _this = this;
var hasEnoughData = end <= this._bufferOffset + len(this._buffer);
if (this._done || hasEnoughData) {
var value = this._getDataFromBuffer(start, end);
var done = value == null ? this._done : false;
return Promise.resolve({
value: value,
done: done
});
}
return this._reader.read().then(function (_ref) {
var value = _ref.value,
done = _ref.done;
if (done) {
_this._done = true;
} else if (_this._buffer === undefined) {
_this._buffer = value;
} else {
_this._buffer = concat(_this._buffer, value);
}
return _this._readUntilEnoughDataOrDone(start, end);
});
}
}, {
key: "_getDataFromBuffer",
value: function _getDataFromBuffer(start, end) {
// Remove data from buffer before `start`.
// Data might be reread from the buffer if an upload fails, so we can only
// safely delete data when it comes *before* what is currently being read.
if (start > this._bufferOffset) {
this._buffer = this._buffer.slice(start - this._bufferOffset);
this._bufferOffset = start;
} // If the buffer is empty after removing old data, all data has been read.
var hasAllDataBeenRead = len(this._buffer) === 0;
if (this._done && hasAllDataBeenRead) {
return null;
} // We already removed data before `start`, so we just return the first
// chunk from the buffer.
return this._buffer.slice(0, end - start);
}
}, {
key: "close",
value: function close() {
if (this._reader.cancel) {
this._reader.cancel();
}
}
}]);
return StreamSource;
}();
function len(blobOrArray) {
if (blobOrArray === undefined) return 0;
if (blobOrArray.size !== undefined) return blobOrArray.size;
return blobOrArray.length;
}
/*
Typed arrays and blobs don't have a concat method.
This function helps StreamSource accumulate data to reach chunkSize.
*/
function concat(a, b) {
if (a.concat) {
// Is `a` an Array?
return a.concat(b);
}
if (a instanceof Blob) {
return new Blob([a, b], {
type: a.type
});
}
if (a.set) {
// Is `a` a typed array?
var c = new a.constructor(a.length + b.length);
c.set(a);
c.set(b, a.length);
return c;
}
throw new Error("Unknown data type");
}
var FileReader = /*#__PURE__*/function () {
function FileReader() {
_classCallCheck(this, FileReader);
}
_createClass(FileReader, [{
key: "openFile",
value: function openFile(input, chunkSize) {
// In React Native, when user selects a file, instead of a File or Blob,
// you usually get a file object {} with a uri property that contains
// a local path to the file. We use XMLHttpRequest to fetch
// the file blob, before uploading with tus.
if ((0, _isReactNative.default)() && input && typeof input.uri !== "undefined") {
return (0, _uriToBlob.default)(input.uri).then(function (blob) {
return new FileSource(blob);
})["catch"](function (err) {
throw new Error("tus: cannot fetch `file.uri` as Blob, make sure the uri is correct and accessible. " + err);
});
} // Since we emulate the Blob type in our tests (not all target browsers
// support it), we cannot use `instanceof` for testing whether the input value
// can be handled. Instead, we simply check is the slice() function and the
// size property are available.
if (typeof input.slice === "function" && typeof input.size !== "undefined") {
return Promise.resolve(new FileSource(input));
}
if (typeof input.read === "function") {
chunkSize = +chunkSize;
if (!isFinite(chunkSize)) {
return Promise.reject(new Error("cannot create source for stream without a finite value for the `chunkSize` option"));
}
return Promise.resolve(new StreamSource(input, chunkSize));
}
return Promise.reject(new Error("source object may only be an instance of File, Blob, or Reader in this environment"));
}
}]);
return FileReader;
}();
exports.default = FileReader;
},{"./isCordova":49,"./isReactNative":50,"./readAsByteArray":51,"./uriToBlob":52}],46:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = fingerprint;
var _isReactNative = _interopRequireDefault(require("./isReactNative"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// TODO: Differenciate between input types
/**
* Generate a fingerprint for a file which will be used the store the endpoint
*
* @param {File} file
* @param {Object} options
* @param {Function} callback
*/
function fingerprint(file, options) {
if ((0, _isReactNative.default)()) {
return Promise.resolve(reactNativeFingerprint(file, options));
}
return Promise.resolve(["tus-br", file.name, file.type, file.size, file.lastModified, options.endpoint].join("-"));
}
function reactNativeFingerprint(file, options) {
var exifHash = file.exif ? hashCode(JSON.stringify(file.exif)) : "noexif";
return ["tus-rn", file.name || "noname", file.size || "nosize", exifHash, options.endpoint].join("/");
}
function hashCode(str) {
// from https://stackoverflow.com/a/8831937/151666
var hash = 0;
if (str.length === 0) {
return hash;
}
for (var i = 0; i < str.length; i++) {
var _char = str.charCodeAt(i);
hash = (hash << 5) - hash + _char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
},{"./isReactNative":50}],47:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
/* global window */
var XHRHttpStack = /*#__PURE__*/function () {
function XHRHttpStack() {
_classCallCheck(this, XHRHttpStack);
}
_createClass(XHRHttpStack, [{
key: "createRequest",
value: function createRequest(method, url) {
return new Request(method, url);
}
}, {
key: "getName",
value: function getName() {
return "XHRHttpStack";
}
}]);
return XHRHttpStack;
}();
exports.default = XHRHttpStack;
var Request = /*#__PURE__*/function () {
function Request(method, url) {
_classCallCheck(this, Request);
this._xhr = new XMLHttpRequest();
this._xhr.open(method, url, true);
this._method = method;
this._url = url;
this._headers = {};
}
_createClass(Request, [{
key: "getMethod",
value: function getMethod() {
return this._method;
}
}, {
key: "getURL",
value: function getURL() {
return this._url;
}
}, {
key: "setHeader",
value: function setHeader(header, value) {
this._xhr.setRequestHeader(header, value);
this._headers[header] = value;
}
}, {
key: "getHeader",
value: function getHeader(header) {
return this._headers[header];
}
}, {
key: "setProgressHandler",
value: function setProgressHandler(progressHandler) {
// Test support for progress events before attaching an event listener
if (!("upload" in this._xhr)) {
return;
}
this._xhr.upload.onprogress = function (e) {
if (!e.lengthComputable) {
return;
}
progressHandler(e.loaded);
};
}
}, {
key: "send",
value: function send() {
var _this = this;
var body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
return new Promise(function (resolve, reject) {
_this._xhr.onload = function () {
resolve(new Response(_this._xhr));
};
_this._xhr.onerror = function (err) {
reject(err);
};
_this._xhr.send(body);
});
}
}, {
key: "abort",
value: function abort() {
this._xhr.abort();
return Promise.resolve();
}
}, {
key: "getUnderlyingObject",
value: function getUnderlyingObject() {
return this._xhr;
}
}]);
return Request;
}();
var Response = /*#__PURE__*/function () {
function Response(xhr) {
_classCallCheck(this, Response);
this._xhr = xhr;
}
_createClass(Response, [{
key: "getStatus",
value: function getStatus() {
return this._xhr.status;
}
}, {
key: "getHeader",
value: function getHeader(header) {
return this._xhr.getResponseHeader(header);
}
}, {
key: "getBody",
value: function getBody() {
return this._xhr.responseText;
}
}, {
key: "getUnderlyingObject",
value: function getUnderlyingObject() {
return this._xhr;
}
}]);
return Response;
}();
},{}],48:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "enableDebugLog", {
enumerable: true,
get: function () {
return _logger.enableDebugLog;
}
});
Object.defineProperty(exports, "canStoreURLs", {
enumerable: true,
get: function () {
return _urlStorage.canStoreURLs;
}
});
exports.isSupported = exports.defaultOptions = exports.Upload = void 0;
var _upload = _interopRequireDefault(require("../upload"));
var _noopUrlStorage = _interopRequireDefault(require("../noopUrlStorage"));
var _logger = require("../logger");
var _urlStorage = require("./urlStorage");
var _httpStack = _interopRequireDefault(require("./httpStack"));
var _fileReader = _interopRequireDefault(require("./fileReader"));
var _fingerprint = _interopRequireDefault(require("./fingerprint"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function _typeof(obj) {
return typeof obj;
};
} else {
_typeof = function _typeof(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _createSuper(Derived) {
return function () {
var Super = _getPrototypeOf(Derived),
result;
if (_isNativeReflectConstruct()) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
/* global window */
var defaultOptions = _objectSpread({}, _upload.default.defaultOptions, {
httpStack: new _httpStack.default(),
fileReader: new _fileReader.default(),
urlStorage: _urlStorage.canStoreURLs ? new _urlStorage.WebStorageUrlStorage() : new _noopUrlStorage.default(),
fingerprint: _fingerprint.default
});
exports.defaultOptions = defaultOptions;
var Upload = /*#__PURE__*/function (_BaseUpload) {
_inherits(Upload, _BaseUpload);
var _super = _createSuper(Upload);
function Upload() {
var file = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Upload);
options = _objectSpread({}, defaultOptions, {}, options);
return _super.call(this, file, options);
}
_createClass(Upload, null, [{
key: "terminate",
value: function terminate(url, options, cb) {
options = _objectSpread({}, defaultOptions, {}, options);
return _upload.default.terminate(url, options, cb);
}
}]);
return Upload;
}(_upload.default);
exports.Upload = Upload;
var _window = window,
XMLHttpRequest = _window.XMLHttpRequest,
Blob = _window.Blob;
var isSupported = XMLHttpRequest && Blob && typeof Blob.prototype.slice === "function";
exports.isSupported = isSupported;
},{"../logger":55,"../noopUrlStorage":56,"../upload":57,"./fileReader":45,"./fingerprint":46,"./httpStack":47,"./urlStorage":53}],49:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var isCordova = function isCordova() {
return typeof window != "undefined" && (typeof window.PhoneGap != "undefined" || typeof window.Cordova != "undefined" || typeof window.cordova != "undefined");
};
var _default = isCordova;
exports.default = _default;
},{}],50:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var isReactNative = function isReactNative() {
return typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product.toLowerCase() === "reactnative";
};
var _default = isReactNative;
exports.default = _default;
},{}],51:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = readAsByteArray;
/**
* readAsByteArray converts a File object to a Uint8Array.
* This function is only used on the Apache Cordova platform.
* See https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html#read-a-file
*/
function readAsByteArray(chunk) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function () {
var value = new Uint8Array(reader.result);
resolve({
value: value
});
};
reader.onerror = function (err) {
reject(err);
};
reader.readAsArrayBuffer(chunk);
});
}
},{}],52:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = uriToBlob;
/**
* uriToBlob resolves a URI to a Blob object. This is used for
* React Native to retrieve a file (identified by a file://
* URI) as a blob.
*/
function uriToBlob(uri) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.onload = function () {
var blob = xhr.response;
resolve(blob);
};
xhr.onerror = function (err) {
reject(err);
};
xhr.open("GET", uri);
xhr.send();
});
}
},{}],53:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.WebStorageUrlStorage = exports.canStoreURLs = void 0;
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
/* global window, localStorage */
var hasStorage = false;
try {
hasStorage = "localStorage" in window; // Attempt to store and read entries from the local storage to detect Private
// Mode on Safari on iOS (see #49)
var key = "tusSupport";
localStorage.setItem(key, localStorage.getItem(key));
} catch (e) {
// If we try to access localStorage inside a sandboxed iframe, a SecurityError
// is thrown. When in private mode on iOS Safari, a QuotaExceededError is
// thrown (see #49)
if (e.code === e.SECURITY_ERR || e.code === e.QUOTA_EXCEEDED_ERR) {
hasStorage = false;
} else {
throw e;
}
}
var canStoreURLs = hasStorage;
exports.canStoreURLs = canStoreURLs;
var WebStorageUrlStorage = /*#__PURE__*/function () {
function WebStorageUrlStorage() {
_classCallCheck(this, WebStorageUrlStorage);
}
_createClass(WebStorageUrlStorage, [{
key: "findAllUploads",
value: function findAllUploads() {
var results = this._findEntries("tus::");
return Promise.resolve(results);
}
}, {
key: "findUploadsByFingerprint",
value: function findUploadsByFingerprint(fingerprint) {
var results = this._findEntries("tus::".concat(fingerprint, "::"));
return Promise.resolve(results);
}
}, {
key: "removeUpload",
value: function removeUpload(urlStorageKey) {
localStorage.removeItem(urlStorageKey);
return Promise.resolve();
}
}, {
key: "addUpload",
value: function addUpload(fingerprint, upload) {
var id = Math.round(Math.random() * 1e12);
var key = "tus::".concat(fingerprint, "::").concat(id);
localStorage.setItem(key, JSON.stringify(upload));
return Promise.resolve(key);
}
}, {
key: "_findEntries",
value: function _findEntries(prefix) {
var results = [];
for (var i = 0; i < localStorage.length; i++) {
var _key = localStorage.key(i);
if (_key.indexOf(prefix) !== 0) continue;
try {
var upload = JSON.parse(localStorage.getItem(_key));
upload.urlStorageKey = _key;
results.push(upload);
} catch (e) {// The JSON parse error is intentionally ignored here, so a malformed
// entry in the storage cannot prevent an upload.
}
}
return results;
}
}]);
return WebStorageUrlStorage;
}();
exports.WebStorageUrlStorage = WebStorageUrlStorage;
},{}],54:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function _typeof(obj) {
return typeof obj;
};
} else {
_typeof = function _typeof(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _createSuper(Derived) {
return function () {
var Super = _getPrototypeOf(Derived),
result;
if (_isNativeReflectConstruct()) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
_wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !_isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return _construct(Class, arguments, _getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return _setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
function _construct(Parent, args, Class) {
if (_isNativeReflectConstruct()) {
_construct = Reflect.construct;
} else {
_construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) _setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
var DetailedError = /*#__PURE__*/function (_Error) {
_inherits(DetailedError, _Error);
var _super = _createSuper(DetailedError);
function DetailedError(message) {
var _this;
var causingErr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var req = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var res = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
_classCallCheck(this, DetailedError);
_this = _super.call(this, message);
_this.originalRequest = req;
_this.originalResponse = res;
_this.causingError = causingErr;
if (causingErr != null) {
message += ", caused by ".concat(causingErr.toString());
}
if (req != null) {
var requestId = req.getHeader("X-Request-ID") || "n/a";
var method = req.getMethod();
var url = req.getURL();
var status = res ? res.getStatus() : "n/a";
var body = res ? res.getBody() || "" : "n/a";
message += ", originated from request (method: ".concat(method, ", url: ").concat(url, ", response code: ").concat(status, ", response text: ").concat(body, ", request id: ").concat(requestId, ")");
}
_this.message = message;
return _this;
}
return DetailedError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
var _default = DetailedError;
exports.default = _default;
},{}],55:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.enableDebugLog = enableDebugLog;
exports.log = log;
/* eslint no-console: "off" */
var isEnabled = false;
function enableDebugLog() {
isEnabled = true;
}
function log(msg) {
if (!isEnabled) return;
console.log(msg);
}
},{}],56:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
/* eslint no-unused-vars: "off" */
var NoopUrlStorage = /*#__PURE__*/function () {
function NoopUrlStorage() {
_classCallCheck(this, NoopUrlStorage);
}
_createClass(NoopUrlStorage, [{
key: "listAllUploads",
value: function listAllUploads() {
return Promise.resolve([]);
}
}, {
key: "findUploadsByFingerprint",
value: function findUploadsByFingerprint(fingerprint) {
return Promise.resolve([]);
}
}, {
key: "removeUpload",
value: function removeUpload(urlStorageKey) {
return Promise.resolve();
}
}, {
key: "addUpload",
value: function addUpload(fingerprint, upload) {
return Promise.resolve(null);
}
}]);
return NoopUrlStorage;
}();
exports.default = NoopUrlStorage;
},{}],57:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _error = _interopRequireDefault(require("./error"));
var _uuid = _interopRequireDefault(require("./uuid"));
var _jsBase = require("js-base64");
var _urlParse = _interopRequireDefault(require("url-parse"));
var _logger = require("./logger");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
/* global window */
var defaultOptions = {
endpoint: null,
uploadUrl: null,
metadata: {},
fingerprint: null,
uploadSize: null,
onProgress: null,
onChunkComplete: null,
onSuccess: null,
onError: null,
_onUploadUrlAvailable: null,
overridePatchMethod: false,
headers: {},
addRequestId: false,
onBeforeRequest: null,
onAfterResponse: null,
chunkSize: Infinity,
retryDelays: [0, 1000, 3000, 5000],
parallelUploads: 1,
storeFingerprintForResuming: true,
removeFingerprintOnSuccess: false,
uploadLengthDeferred: false,
uploadDataDuringCreation: false,
urlStorage: null,
fileReader: null,
httpStack: null
};
var BaseUpload = /*#__PURE__*/function () {
function BaseUpload(file, options) {
_classCallCheck(this, BaseUpload); // Warn about removed options from previous versions
if ("resume" in options) {
console.log("tus: The `resume` option has been removed in tus-js-client v2. Please use the URL storage API instead."); // eslint-disable-line no-console
} // The default options will already be added from the wrapper classes.
this.options = options; // The storage module used to store URLs
this._urlStorage = this.options.urlStorage; // The underlying File/Blob object
this.file = file; // The URL against which the file will be uploaded
this.url = null; // The underlying request object for the current PATCH request
this._req = null; // The fingerpinrt for the current file (set after start())
this._fingerprint = null; // The key that the URL storage returned when saving an URL with a fingerprint,
this._urlStorageKey = null; // The offset used in the current PATCH request
this._offset = null; // True if the current PATCH request has been aborted
this._aborted = false; // The file's size in bytes
this._size = null; // The Source object which will wrap around the given file and provides us
// with a unified interface for getting its size and slice chunks from its
// content allowing us to easily handle Files, Blobs, Buffers and Streams.
this._source = null; // The current count of attempts which have been made. Zero indicates none.
this._retryAttempt = 0; // The timeout's ID which is used to delay the next retry
this._retryTimeout = null; // The offset of the remote upload before the latest attempt was started.
this._offsetBeforeRetry = 0; // An array of BaseUpload instances which are used for uploading the different
// parts, if the parallelUploads option is used.
this._parallelUploads = null; // An array of upload URLs which are used for uploading the different
// parts, if the parallelUploads option is used.
this._parallelUploadUrls = null;
}
/**
* Use the Termination extension to delete an upload from the server by sending a DELETE
* request to the specified upload URL. This is only possible if the server supports the
* Termination extension. If the `options.retryDelays` property is set, the method will
* also retry if an error ocurrs.
*
* @param {String} url The upload's URL which will be terminated.
* @param {object} options Optional options for influencing HTTP requests.
* @return {Promise} The Promise will be resolved/rejected when the requests finish.
*/
_createClass(BaseUpload, [{
key: "findPreviousUploads",
value: function findPreviousUploads() {
var _this = this;
return this.options.fingerprint(this.file, this.options).then(function (fingerprint) {
return _this._urlStorage.findUploadsByFingerprint(fingerprint);
});
}
}, {
key: "resumeFromPreviousUpload",
value: function resumeFromPreviousUpload(previousUpload) {
this.url = previousUpload.uploadUrl || null;
this._parallelUploadUrls = previousUpload.parallelUploadUrls || null;
this._urlStorageKey = previousUpload.urlStorageKey;
}
}, {
key: "start",
value: function start() {
var _this2 = this;
var file = this.file;
if (!file) {
this._emitError(new Error("tus: no file or stream to upload provided"));
return;
}
if (!this.options.endpoint && !this.options.uploadUrl) {
this._emitError(new Error("tus: neither an endpoint or an upload URL is provided"));
return;
}
var retryDelays = this.options.retryDelays;
if (retryDelays != null && Object.prototype.toString.call(retryDelays) !== "[object Array]") {
this._emitError(new Error("tus: the `retryDelays` option must either be an array or null"));
return;
}
if (this.options.parallelUploads > 1) {
// Test which options are incompatible with parallel uploads.
["uploadUrl", "uploadSize", "uploadLengthDeferred"].forEach(function (optionName) {
if (_this2.options[optionName]) {
_this2._emitError(new Error("tus: cannot use the ".concat(optionName, " option when parallelUploads is enabled")));
}
});
}
this.options.fingerprint(file, this.options).then(function (fingerprint) {
if (fingerprint == null) {
(0, _logger.log)("No fingerprint was calculated meaning that the upload cannot be stored in the URL storage.");
} else {
(0, _logger.log)("Calculated fingerprint: ".concat(fingerprint));
}
_this2._fingerprint = fingerprint;
if (_this2._source) {
return _this2._source;
} else {
return _this2.options.fileReader.openFile(file, _this2.options.chunkSize);
}
}).then(function (source) {
_this2._source = source; // If the upload was configured to use multiple requests or if we resume from
// an upload which used multiple requests, we start a parallel upload.
if (_this2.options.parallelUploads > 1 || _this2._parallelUploadUrls != null) {
_this2._startParallelUpload();
} else {
_this2._startSingleUpload();
}
})["catch"](function (err) {
_this2._emitError(err);
});
}
/**
* Initiate the uploading procedure for a parallelized upload, where one file is split into
* multiple request which are run in parallel.
*
* @api private
*/
}, {
key: "_startParallelUpload",
value: function _startParallelUpload() {
var _this3 = this;
var totalSize = this._size = this._source.size;
var totalProgress = 0;
this._parallelUploads = [];
var partCount = this._parallelUploadUrls != null ? this._parallelUploadUrls.length : this.options.parallelUploads; // The input file will be split into multiple slices which are uploaded in separate
// requests. Here we generate the start and end position for the slices.
var parts = splitSizeIntoParts(this._source.size, partCount, this._parallelUploadUrls); // Create an empty list for storing the upload URLs
this._parallelUploadUrls = new Array(parts.length); // Generate a promise for each slice that will be resolve if the respective
// upload is completed.
var uploads = parts.map(function (part, index) {
var lastPartProgress = 0;
return _this3._source.slice(part.start, part.end).then(function (_ref) {
var value = _ref.value;
return new Promise(function (resolve, reject) {
// Merge with the user supplied options but overwrite some values.
var options = _objectSpread({}, _this3.options, {
// If available, the partial upload should be resumed from a previous URL.
uploadUrl: part.uploadUrl || null,
// We take manually care of resuming for partial uploads, so they should
// not be stored in the URL storage.
storeFingerprintForResuming: false,
removeFingerprintOnSuccess: false,
// Reset the parallelUploads option to not cause recursion.
parallelUploads: 1,
metadata: {},
// Add the header to indicate the this is a partial upload.
headers: _objectSpread({}, _this3.options.headers, {
"Upload-Concat": "partial"
}),
// Reject or resolve the promise if the upload errors or completes.
onSuccess: resolve,
onError: reject,
// Based in the progress for this partial upload, calculate the progress
// for the entire final upload.
onProgress: function onProgress(newPartProgress) {
totalProgress = totalProgress - lastPartProgress + newPartProgress;
lastPartProgress = newPartProgress;
_this3._emitProgress(totalProgress, totalSize);
},
// Wait until every partial upload has an upload URL, so we can add
// them to the URL storage.
_onUploadUrlAvailable: function _onUploadUrlAvailable() {
_this3._parallelUploadUrls[index] = upload.url; // Test if all uploads have received an URL
if (_this3._parallelUploadUrls.filter(function (u) {
return !!u;
}).length === parts.length) {
_this3._saveUploadInUrlStorage();
}
}
});
var upload = new BaseUpload(value, options);
upload.start(); // Store the upload in an array, so we can later abort them if necessary.
_this3._parallelUploads.push(upload);
});
});
});
var req; // Wait until all partial uploads are finished and we can send the POST request for
// creating the final upload.
Promise.all(uploads).then(function () {
req = _this3._openRequest("POST", _this3.options.endpoint);
req.setHeader("Upload-Concat", "final;".concat(_this3._parallelUploadUrls.join(" "))); // Add metadata if values have been added
var metadata = encodeMetadata(_this3.options.metadata);
if (metadata !== "") {
req.setHeader("Upload-Metadata", metadata);
}
return _this3._sendRequest(req, null);
}).then(function (res) {
if (!inStatusCategory(res.getStatus(), 200)) {
_this3._emitHttpError(req, res, "tus: unexpected response while creating upload");
return;
}
var location = res.getHeader("Location");
if (location == null) {
_this3._emitHttpError(req, res, "tus: invalid or missing Location header");
return;
}
_this3.url = resolveUrl(_this3.options.endpoint, location);
(0, _logger.log)("Created upload at ".concat(_this3.url));
_this3._emitSuccess();
})["catch"](function (err) {
_this3._emitError(err);
});
}
/**
* Initiate the uploading procedure for a non-parallel upload. Here the entire file is
* uploaded in a sequential matter.
*
* @api private
*/
}, {
key: "_startSingleUpload",
value: function _startSingleUpload() {
// First, we look at the uploadLengthDeferred option.
// Next, we check if the caller has supplied a manual upload size.
// Finally, we try to use the calculated size from the source object.
if (this.options.uploadLengthDeferred) {
this._size = null;
} else if (this.options.uploadSize != null) {
this._size = +this.options.uploadSize;
if (isNaN(this._size)) {
this._emitError(new Error("tus: cannot convert `uploadSize` option into a number"));
return;
}
} else {
this._size = this._source.size;
if (this._size == null) {
this._emitError(new Error("tus: cannot automatically derive upload's size from input and must be specified manually using the `uploadSize` option"));
return;
}
} // Reset the aborted flag when the upload is started or else the
// _performUpload will stop before sending a request if the upload has been
// aborted previously.
this._aborted = false; // The upload had been started previously and we should reuse this URL.
if (this.url != null) {
(0, _logger.log)("Resuming upload from previous URL: ".concat(this.url));
this._resumeUpload();
return;
} // A URL has manually been specified, so we try to resume
if (this.options.uploadUrl != null) {
(0, _logger.log)("Resuming upload from provided URL: ".concat(this.options.url));
this.url = this.options.uploadUrl;
this._resumeUpload();
return;
} // An upload has not started for the file yet, so we start a new one
(0, _logger.log)("Creating a new upload");
this._createUpload();
}
/**
* Abort any running request and stop the current upload. After abort is called, no event
* handler will be invoked anymore. You can use the `start` method to resume the upload
* again.
* If `shouldTerminate` is true, the `terminate` function will be called to remove the
* current upload from the server.
*
* @param {boolean} shouldTerminate True if the upload should be deleted from the server.
* @return {Promise} The Promise will be resolved/rejected when the requests finish.
*/
}, {
key: "abort",
value: function abort(shouldTerminate, cb) {
var _this4 = this;
if (typeof cb === "function") {
throw new Error("tus: the abort function does not accept a callback since v2 anymore; please use the returned Promise instead");
} // Stop any parallel partial uploads, that have been started in _startParallelUploads.
if (this._parallelUploads != null) {
this._parallelUploads.forEach(function (upload) {
upload.abort(shouldTerminate);
});
} // Stop any current running request.
if (this._req !== null) {
this._req.abort();
this._source.close();
}
this._aborted = true; // Stop any timeout used for initiating a retry.
if (this._retryTimeout != null) {
clearTimeout(this._retryTimeout);
this._retryTimeout = null;
}
if (!shouldTerminate || this.url == null) {
return Promise.resolve();
}
return BaseUpload.terminate(this.url, this.options) // Remove entry from the URL storage since the upload URL is no longer valid.
.then(function () {
return _this4._removeFromUrlStorage();
});
}
}, {
key: "_emitHttpError",
value: function _emitHttpError(req, res, message, causingErr) {
this._emitError(new _error.default(message, causingErr, req, res));
}
}, {
key: "_emitError",
value: function _emitError(err) {
var _this5 = this; // Do not emit errors, e.g. from aborted HTTP requests, if the upload has been stopped.
if (this._aborted) return; // Check if we should retry, when enabled, before sending the error to the user.
if (this.options.retryDelays != null) {
// We will reset the attempt counter if
// - we were already able to connect to the server (offset != null) and
// - we were able to upload a small chunk of data to the server
var shouldResetDelays = this._offset != null && this._offset > this._offsetBeforeRetry;
if (shouldResetDelays) {
this._retryAttempt = 0;
}
if (shouldRetry(err, this._retryAttempt, this.options)) {
var delay = this.options.retryDelays[this._retryAttempt++];
this._offsetBeforeRetry = this._offset;
this._retryTimeout = setTimeout(function () {
_this5.start();
}, delay);
return;
}
}
if (typeof this.options.onError === "function") {
this.options.onError(err);
} else {
throw err;
}
}
/**
* Publishes notification if the upload has been successfully completed.
*
* @api private
*/
}, {
key: "_emitSuccess",
value: function _emitSuccess() {
if (this.options.removeFingerprintOnSuccess) {
// Remove stored fingerprint and corresponding endpoint. This causes
// new uploads of the same file to be treated as a different file.
this._removeFromUrlStorage();
}
if (typeof this.options.onSuccess === "function") {
this.options.onSuccess();
}
}
/**
* Publishes notification when data has been sent to the server. This
* data may not have been accepted by the server yet.
*
* @param {number} bytesSent Number of bytes sent to the server.
* @param {number} bytesTotal Total number of bytes to be sent to the server.
* @api private
*/
}, {
key: "_emitProgress",
value: function _emitProgress(bytesSent, bytesTotal) {
if (typeof this.options.onProgress === "function") {
this.options.onProgress(bytesSent, bytesTotal);
}
}
/**
* Publishes notification when a chunk of data has been sent to the server
* and accepted by the server.
* @param {number} chunkSize Size of the chunk that was accepted by the server.
* @param {number} bytesAccepted Total number of bytes that have been
* accepted by the server.
* @param {number} bytesTotal Total number of bytes to be sent to the server.
* @api private
*/
}, {
key: "_emitChunkComplete",
value: function _emitChunkComplete(chunkSize, bytesAccepted, bytesTotal) {
if (typeof this.options.onChunkComplete === "function") {
this.options.onChunkComplete(chunkSize, bytesAccepted, bytesTotal);
}
}
/**
* Create a new upload using the creation extension by sending a POST
* request to the endpoint. After successful creation the file will be
* uploaded
*
* @api private
*/
}, {
key: "_createUpload",
value: function _createUpload() {
var _this6 = this;
if (!this.options.endpoint) {
this._emitError(new Error("tus: unable to create upload because no endpoint is provided"));
return;
}
var req = this._openRequest("POST", this.options.endpoint);
if (this.options.uploadLengthDeferred) {
req.setHeader("Upload-Defer-Length", 1);
} else {
req.setHeader("Upload-Length", this._size);
} // Add metadata if values have been added
var metadata = encodeMetadata(this.options.metadata);
if (metadata !== "") {
req.setHeader("Upload-Metadata", metadata);
}
var promise;
if (this.options.uploadDataDuringCreation && !this.options.uploadLengthDeferred) {
this._offset = 0;
promise = this._addChunkToRequest(req);
} else {
promise = this._sendRequest(req, null);
}
promise.then(function (res) {
if (!inStatusCategory(res.getStatus(), 200)) {
_this6._emitHttpError(req, res, "tus: unexpected response while creating upload");
return;
}
var location = res.getHeader("Location");
if (location == null) {
_this6._emitHttpError(req, res, "tus: invalid or missing Location header");
return;
}
_this6.url = resolveUrl(_this6.options.endpoint, location);
(0, _logger.log)("Created upload at ".concat(_this6.url));
if (typeof _this6.options._onUploadUrlAvailable === "function") {
_this6.options._onUploadUrlAvailable();
}
if (_this6._size === 0) {
// Nothing to upload and file was successfully created
_this6._emitSuccess();
_this6._source.close();
return;
}
_this6._saveUploadInUrlStorage();
if (_this6.options.uploadDataDuringCreation) {
_this6._handleUploadResponse(req, res);
} else {
_this6._offset = 0;
_this6._performUpload();
}
})["catch"](function (err) {
_this6._emitHttpError(req, null, "tus: failed to create upload", err);
});
}
/*
* Try to resume an existing upload. First a HEAD request will be sent
* to retrieve the offset. If the request fails a new upload will be
* created. In the case of a successful response the file will be uploaded.
*
* @api private
*/
}, {
key: "_resumeUpload",
value: function _resumeUpload() {
var _this7 = this;
var req = this._openRequest("HEAD", this.url);
var promise = this._sendRequest(req, null);
promise.then(function (res) {
var status = res.getStatus();
if (!inStatusCategory(status, 200)) {
if (inStatusCategory(status, 400)) {
// Remove stored fingerprint and corresponding endpoint,
// on client errors since the file can not be found
_this7._removeFromUrlStorage();
} // If the upload is locked (indicated by the 423 Locked status code), we
// emit an error instead of directly starting a new upload. This way the
// retry logic can catch the error and will retry the upload. An upload
// is usually locked for a short period of time and will be available
// afterwards.
if (status === 423) {
_this7._emitHttpError(req, res, "tus: upload is currently locked; retry later");
return;
}
if (!_this7.options.endpoint) {
// Don't attempt to create a new upload if no endpoint is provided.
_this7._emitHttpError(req, res, "tus: unable to resume upload (new upload cannot be created without an endpoint)");
return;
} // Try to create a new upload
_this7.url = null;
_this7._createUpload();
return;
}
var offset = parseInt(res.getHeader("Upload-Offset"), 10);
if (isNaN(offset)) {
_this7._emitHttpError(req, res, "tus: invalid or missing offset value");
return;
}
var length = parseInt(res.getHeader("Upload-Length"), 10);
if (isNaN(length) && !_this7.options.uploadLengthDeferred) {
_this7._emitHttpError(req, res, "tus: invalid or missing length value");
return;
}
if (typeof _this7.options._onUploadUrlAvailable === "function") {
_this7.options._onUploadUrlAvailable();
} // Upload has already been completed and we do not need to send additional
// data to the server
if (offset === length) {
_this7._emitProgress(length, length);
_this7._emitSuccess();
return;
}
_this7._offset = offset;
_this7._performUpload();
})["catch"](function (err) {
_this7._emitHttpError(req, null, "tus: failed to resume upload", err);
});
}
/**
* Start uploading the file using PATCH requests. The file will be divided
* into chunks as specified in the chunkSize option. During the upload
* the onProgress event handler may be invoked multiple times.
*
* @api private
*/
}, {
key: "_performUpload",
value: function _performUpload() {
var _this8 = this; // If the upload has been aborted, we will not send the next PATCH request.
// This is important if the abort method was called during a callback, such
// as onChunkComplete or onProgress.
if (this._aborted) {
return;
}
var req; // Some browser and servers may not support the PATCH method. For those
// cases, you can tell tus-js-client to use a POST request with the
// X-HTTP-Method-Override header for simulating a PATCH request.
if (this.options.overridePatchMethod) {
req = this._openRequest("POST", this.url);
req.setHeader("X-HTTP-Method-Override", "PATCH");
} else {
req = this._openRequest("PATCH", this.url);
}
req.setHeader("Upload-Offset", this._offset);
var promise = this._addChunkToRequest(req);
promise.then(function (res) {
if (!inStatusCategory(res.getStatus(), 200)) {
_this8._emitHttpError(req, res, "tus: unexpected response while uploading chunk");
return;
}
_this8._handleUploadResponse(req, res);
})["catch"](function (err) {
// Don't emit an error if the upload was aborted manually
if (_this8._aborted) {
return;
}
_this8._emitHttpError(req, null, "tus: failed to upload chunk at offset " + _this8._offset, err);
});
}
/**
* _addChunktoRequest reads a chunk from the source and sends it using the
* supplied request object. It will not handle the response.
*
* @api private
*/
}, {
key: "_addChunkToRequest",
value: function _addChunkToRequest(req) {
var _this9 = this;
var start = this._offset;
var end = this._offset + this.options.chunkSize;
req.setProgressHandler(function (bytesSent) {
_this9._emitProgress(start + bytesSent, _this9._size);
});
req.setHeader("Content-Type", "application/offset+octet-stream"); // The specified chunkSize may be Infinity or the calcluated end position
// may exceed the file's size. In both cases, we limit the end position to
// the input's total size for simpler calculations and correctness.
if ((end === Infinity || end > this._size) && !this.options.uploadLengthDeferred) {
end = this._size;
}
return this._source.slice(start, end).then(function (_ref2) {
var value = _ref2.value,
done = _ref2.done; // If the upload length is deferred, the upload size was not specified during
// upload creation. So, if the file reader is done reading, we know the total
// upload size and can tell the tus server.
if (_this9.options.uploadLengthDeferred && done) {
_this9._size = _this9._offset + (value && value.size ? value.size : 0);
req.setHeader("Upload-Length", _this9._size);
}
if (value === null) {
return _this9._sendRequest(req);
} else {
_this9._emitProgress(_this9._offset, _this9._size);
return _this9._sendRequest(req, value);
}
});
}
/**
* _handleUploadResponse is used by requests that haven been sent using _addChunkToRequest
* and already have received a response.
*
* @api private
*/
}, {
key: "_handleUploadResponse",
value: function _handleUploadResponse(req, res) {
var offset = parseInt(res.getHeader("Upload-Offset"), 10);
if (isNaN(offset)) {
this._emitHttpError(req, res, "tus: invalid or missing offset value");
return;
}
this._emitProgress(offset, this._size);
this._emitChunkComplete(offset - this._offset, offset, this._size);
this._offset = offset;
if (offset == this._size) {
// Yay, finally done :)
this._emitSuccess();
this._source.close();
return;
}
this._performUpload();
}
/**
* Create a new HTTP request object with the given method and URL.
*
* @api private
*/
}, {
key: "_openRequest",
value: function _openRequest(method, url) {
var req = openRequest(method, url, this.options);
this._req = req;
return req;
}
/**
* Remove the entry in the URL storage, if it has been saved before.
*
* @api private
*/
}, {
key: "_removeFromUrlStorage",
value: function _removeFromUrlStorage() {
var _this10 = this;
if (!this._urlStorageKey) return;
this._urlStorage.removeUpload(this._urlStorageKey)["catch"](function (err) {
_this10._emitError(err);
});
this._urlStorageKey = null;
}
/**
* Add the upload URL to the URL storage, if possible.
*
* @api private
*/
}, {
key: "_saveUploadInUrlStorage",
value: function _saveUploadInUrlStorage() {
var _this11 = this; // Only if a fingerprint was calculated for the input (i.e. not a stream), we can store the upload URL.
if (!this.options.storeFingerprintForResuming || !this._fingerprint) {
return;
}
var storedUpload = {
size: this._size,
metadata: this.options.metadata,
creationTime: new Date().toString()
};
if (this._parallelUploads) {
// Save multiple URLs if the parallelUploads option is used ...
storedUpload.parallelUploadUrls = this._parallelUploadUrls;
} else {
// ... otherwise we just save the one available URL.
storedUpload.uploadUrl = this.url;
}
this._urlStorage.addUpload(this._fingerprint, storedUpload).then(function (urlStorageKey) {
return _this11._urlStorageKey = urlStorageKey;
})["catch"](function (err) {
_this11._emitError(err);
});
}
/**
* Send a request with the provided body while invoking the onBeforeRequest
* and onAfterResponse callbacks.
*
* @api private
*/
}, {
key: "_sendRequest",
value: function _sendRequest(req) {
var _this12 = this;
var body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if (typeof this.options.onBeforeRequest === "function") {
this.options.onBeforeRequest(req);
}
return req.send(body).then(function (res) {
if (typeof _this12.options.onAfterResponse === "function") {
_this12.options.onAfterResponse(req, res);
}
return res;
});
}
}], [{
key: "terminate",
value: function terminate(url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var cb = arguments.length > 2 ? arguments[2] : undefined;
if (typeof options === "function" || typeof cb === "function") {
throw new Error("tus: the terminate function does not accept a callback since v2 anymore; please use the returned Promise instead");
}
var req = openRequest("DELETE", url, options);
var promise = req.send();
return promise.then(function (res) {
// A 204 response indicates a successfull request
if (res.getStatus() === 204) {
return;
}
throw new _error.default("tus: unexpected response while terminating upload", null, req, res);
})["catch"](function (err) {
if (!(err instanceof _error.default)) {
err = new _error.default("tus: failed to terminate upload", err, req, null);
}
if (!shouldRetry(err, 0, options)) {
throw err;
} // Instead of keeping track of the retry attempts, we remove the first element from the delays
// array. If the array is empty, all retry attempts are used up and we will bubble up the error.
// We recursively call the terminate function will removing elements from the retryDelays array.
var delay = options.retryDelays[0];
var remainingDelays = options.retryDelays.slice(1);
var newOptions = _objectSpread({}, options, {
retryDelays: remainingDelays
});
return new Promise(function (resolve) {
return setTimeout(resolve, delay);
}).then(function () {
return BaseUpload.terminate(url, newOptions);
});
});
}
}]);
return BaseUpload;
}();
function encodeMetadata(metadata) {
var encoded = [];
for (var key in metadata) {
encoded.push(key + " " + _jsBase.Base64.encode(metadata[key]));
}
return encoded.join(",");
}
/**
* Checks whether a given status is in the range of the expected category.
* For example, only a status between 200 and 299 will satisfy the category 200.
*
* @api private
*/
function inStatusCategory(status, category) {
return status >= category && status < category + 100;
}
/**
* Create a new HTTP request with the specified method and URL.
* The necessary headers that are included in every request
* will be added, including the request ID.
*
* @api private
*/
function openRequest(method, url, options) {
var req = options.httpStack.createRequest(method, url);
req.setHeader("Tus-Resumable", "1.0.0");
var headers = options.headers || {};
for (var name in headers) {
req.setHeader(name, headers[name]);
}
if (options.addRequestId) {
var requestId = (0, _uuid.default)();
req.setHeader("X-Request-ID", requestId);
}
return req;
}
/**
* Checks whether the browser running this code has internet access.
* This function will always return true in the node.js environment
*
* @api private
*/
function isOnline() {
var online = true;
if (typeof window !== "undefined" && "navigator" in window && window.navigator.onLine === false) {
online = false;
}
return online;
}
/**
* Checks whether or not it is ok to retry a request.
* @param {Error} err the error returned from the last request
* @param {number} retryAttempt the number of times the request has already been retried
* @param {object} options tus Upload options
*
* @api private
*/
function shouldRetry(err, retryAttempt, options) {
// We only attempt a retry if
// - retryDelays option is set
// - we didn't exceed the maxium number of retries, yet, and
// - this error was caused by a request or it's response and
// - the error is server error (i.e. no a status 4xx or a 409 or 423) and
// - the browser does not indicate that we are offline
var status = err.originalResponse ? err.originalResponse.getStatus() : 0;
var isServerError = !inStatusCategory(status, 400) || status === 409 || status === 423;
return options.retryDelays != null && retryAttempt < options.retryDelays.length && err.originalRequest != null && isServerError && isOnline();
}
/**
* Resolve a relative link given the origin as source. For example,
* if a HTTP request to http://example.com/files/ returns a Location
* header with the value /upload/abc, the resolved URL will be:
* http://example.com/upload/abc
*/
function resolveUrl(origin, link) {
return new _urlParse.default(link, origin).toString();
}
/**
* Calculate the start and end positions for the parts if an upload
* is split into multiple parallel requests.
*
* @param {number} totalSize The byte size of the upload, which will be split.
* @param {number} partCount The number in how many parts the upload will be split.
* @param {string[]} previousUrls The upload URLs for previous parts.
* @return {object[]}
* @api private
*/
function splitSizeIntoParts(totalSize, partCount, previousUrls) {
var partSize = Math.floor(totalSize / partCount);
var parts = [];
for (var i = 0; i < partCount; i++) {
parts.push({
start: partSize * i,
end: partSize * (i + 1)
});
}
parts[partCount - 1].end = totalSize; // Attach URLs from previous uploads, if available.
if (previousUrls) {
parts.forEach(function (part, index) {
part.uploadUrl = previousUrls[index] || null;
});
}
return parts;
}
BaseUpload.defaultOptions = defaultOptions;
var _default = BaseUpload;
exports.default = _default;
},{"./error":54,"./logger":55,"./uuid":58,"js-base64":32,"url-parse":59}],58:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = uuid;
/**
* Generate a UUID v4 based on random numbers. We intentioanlly use the less
* secure Math.random function here since the more secure crypto.getRandomNumbers
* is not available on all platforms.
* This is not a problem for us since we use the UUID only for generating a
* request ID, so we can correlate server logs to client errors.
*
* This function is taken from following site:
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
*
* @return {string} The generate UUID
*/
function uuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == "x" ? r : r & 0x3 | 0x8;
return v.toString(16);
});
}
},{}],59:[function(require,module,exports){
(function (global){(function (){
'use strict';
var required = require('requires-port')
, qs = require('querystringify')
, slashes = /^[A-Za-z][A-Za-z0-9+-.]*:[\\/]+/
, protocolre = /^([a-z][a-z0-9.+-]*:)?([\\/]{1,})?([\S\s]*)/i
, whitespace = '[\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF]'
, left = new RegExp('^'+ whitespace +'+');
/**
* Trim a given string.
*
* @param {String} str String to trim.
* @public
*/
function trimLeft(str) {
return (str ? str : '').toString().replace(left, '');
}
/**
* These are the parse rules for the URL parser, it informs the parser
* about:
*
* 0. The char it Needs to parse, if it's a string it should be done using
* indexOf, RegExp using exec and NaN means set as current value.
* 1. The property we should set when parsing this value.
* 2. Indication if it's backwards or forward parsing, when set as number it's
* the value of extra chars that should be split off.
* 3. Inherit from location if non existing in the parser.
* 4. `toLowerCase` the resulting value.
*/
var rules = [
['#', 'hash'], // Extract from the back.
['?', 'query'], // Extract from the back.
function sanitize(address) { // Sanitize what is left of the address
return address.replace('\\', '/');
},
['/', 'pathname'], // Extract from the back.
['@', 'auth', 1], // Extract from the front.
[NaN, 'host', undefined, 1, 1], // Set left over value.
[/:(\d+)$/, 'port', undefined, 1], // RegExp the back.
[NaN, 'hostname', undefined, 1, 1] // Set left over.
];
/**
* These properties should not be copied or inherited from. This is only needed
* for all non blob URL's as a blob URL does not include a hash, only the
* origin.
*
* @type {Object}
* @private
*/
var ignore = { hash: 1, query: 1 };
/**
* The location object differs when your code is loaded through a normal page,
* Worker or through a worker using a blob. And with the blobble begins the
* trouble as the location object will contain the URL of the blob, not the
* location of the page where our code is loaded in. The actual origin is
* encoded in the `pathname` so we can thankfully generate a good "default"
* location from it so we can generate proper relative URL's again.
*
* @param {Object|String} loc Optional default location object.
* @returns {Object} lolcation object.
* @public
*/
function lolcation(loc) {
var globalVar;
if (typeof window !== 'undefined') globalVar = window;
else if (typeof global !== 'undefined') globalVar = global;
else if (typeof self !== 'undefined') globalVar = self;
else globalVar = {};
var location = globalVar.location || {};
loc = loc || location;
var finaldestination = {}
, type = typeof loc
, key;
if ('blob:' === loc.protocol) {
finaldestination = new Url(unescape(loc.pathname), {});
} else if ('string' === type) {
finaldestination = new Url(loc, {});
for (key in ignore) delete finaldestination[key];
} else if ('object' === type) {
for (key in loc) {
if (key in ignore) continue;
finaldestination[key] = loc[key];
}
if (finaldestination.slashes === undefined) {
finaldestination.slashes = slashes.test(loc.href);
}
}
return finaldestination;
}
/**
* @typedef ProtocolExtract
* @type Object
* @property {String} protocol Protocol matched in the URL, in lowercase.
* @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
* @property {String} rest Rest of the URL that is not part of the protocol.
*/
/**
* Extract protocol information from a URL with/without double slash ("//").
*
* @param {String} address URL we want to extract from.
* @return {ProtocolExtract} Extracted information.
* @private
*/
function extractProtocol(address) {
address = trimLeft(address);
var match = protocolre.exec(address)
, protocol = match[1] ? match[1].toLowerCase() : ''
, slashes = !!(match[2] && match[2].length >= 2)
, rest = match[2] && match[2].length === 1 ? '/' + match[3] : match[3];
return {
protocol: protocol,
slashes: slashes,
rest: rest
};
}
/**
* Resolve a relative URL pathname against a base URL pathname.
*
* @param {String} relative Pathname of the relative URL.
* @param {String} base Pathname of the base URL.
* @return {String} Resolved pathname.
* @private
*/
function resolve(relative, base) {
if (relative === '') return base;
var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
, i = path.length
, last = path[i - 1]
, unshift = false
, up = 0;
while (i--) {
if (path[i] === '.') {
path.splice(i, 1);
} else if (path[i] === '..') {
path.splice(i, 1);
up++;
} else if (up) {
if (i === 0) unshift = true;
path.splice(i, 1);
up--;
}
}
if (unshift) path.unshift('');
if (last === '.' || last === '..') path.push('');
return path.join('/');
}
/**
* The actual URL instance. Instead of returning an object we've opted-in to
* create an actual constructor as it's much more memory efficient and
* faster and it pleases my OCD.
*
* It is worth noting that we should not use `URL` as class name to prevent
* clashes with the global URL instance that got introduced in browsers.
*
* @constructor
* @param {String} address URL we want to parse.
* @param {Object|String} [location] Location defaults for relative paths.
* @param {Boolean|Function} [parser] Parser for the query string.
* @private
*/
function Url(address, location, parser) {
address = trimLeft(address);
if (!(this instanceof Url)) {
return new Url(address, location, parser);
}
var relative, extracted, parse, instruction, index, key
, instructions = rules.slice()
, type = typeof location
, url = this
, i = 0;
//
// The following if statements allows this module two have compatibility with
// 2 different API:
//
// 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
// where the boolean indicates that the query string should also be parsed.
//
// 2. The `URL` interface of the browser which accepts a URL, object as
// arguments. The supplied object will be used as default values / fall-back
// for relative paths.
//
if ('object' !== type && 'string' !== type) {
parser = location;
location = null;
}
if (parser && 'function' !== typeof parser) parser = qs.parse;
location = lolcation(location);
//
// Extract protocol information before running the instructions.
//
extracted = extractProtocol(address || '');
relative = !extracted.protocol && !extracted.slashes;
url.slashes = extracted.slashes || relative && location.slashes;
url.protocol = extracted.protocol || location.protocol || '';
address = extracted.rest;
//
// When the authority component is absent the URL starts with a path
// component.
//
if (!extracted.slashes) instructions[3] = [/(.*)/, 'pathname'];
for (; i < instructions.length; i++) {
instruction = instructions[i];
if (typeof instruction === 'function') {
address = instruction(address);
continue;
}
parse = instruction[0];
key = instruction[1];
if (parse !== parse) {
url[key] = address;
} else if ('string' === typeof parse) {
if (~(index = address.indexOf(parse))) {
if ('number' === typeof instruction[2]) {
url[key] = address.slice(0, index);
address = address.slice(index + instruction[2]);
} else {
url[key] = address.slice(index);
address = address.slice(0, index);
}
}
} else if ((index = parse.exec(address))) {
url[key] = index[1];
address = address.slice(0, index.index);
}
url[key] = url[key] || (
relative && instruction[3] ? location[key] || '' : ''
);
//
// Hostname, host and protocol should be lowercased so they can be used to
// create a proper `origin`.
//
if (instruction[4]) url[key] = url[key].toLowerCase();
}
//
// Also parse the supplied query string in to an object. If we're supplied
// with a custom parser as function use that instead of the default build-in
// parser.
//
if (parser) url.query = parser(url.query);
//
// If the URL is relative, resolve the pathname against the base URL.
//
if (
relative
&& location.slashes
&& url.pathname.charAt(0) !== '/'
&& (url.pathname !== '' || location.pathname !== '')
) {
url.pathname = resolve(url.pathname, location.pathname);
}
//
// Default to a / for pathname if none exists. This normalizes the URL
// to always have a /
//
if (url.pathname.charAt(0) !== '/' && url.hostname) {
url.pathname = '/' + url.pathname;
}
//
// We should not add port numbers if they are already the default port number
// for a given protocol. As the host also contains the port number we're going
// override it with the hostname which contains no port number.
//
if (!required(url.port, url.protocol)) {
url.host = url.hostname;
url.port = '';
}
//
// Parse down the `auth` for the username and password.
//
url.username = url.password = '';
if (url.auth) {
instruction = url.auth.split(':');
url.username = instruction[0] || '';
url.password = instruction[1] || '';
}
url.origin = url.protocol && url.host && url.protocol !== 'file:'
? url.protocol +'//'+ url.host
: 'null';
//
// The href is just the compiled result.
//
url.href = url.toString();
}
/**
* This is convenience method for changing properties in the URL instance to
* insure that they all propagate correctly.
*
* @param {String} part Property we need to adjust.
* @param {Mixed} value The newly assigned value.
* @param {Boolean|Function} fn When setting the query, it will be the function
* used to parse the query.
* When setting the protocol, double slash will be
* removed from the final url if it is true.
* @returns {URL} URL instance for chaining.
* @public
*/
function set(part, value, fn) {
var url = this;
switch (part) {
case 'query':
if ('string' === typeof value && value.length) {
value = (fn || qs.parse)(value);
}
url[part] = value;
break;
case 'port':
url[part] = value;
if (!required(value, url.protocol)) {
url.host = url.hostname;
url[part] = '';
} else if (value) {
url.host = url.hostname +':'+ value;
}
break;
case 'hostname':
url[part] = value;
if (url.port) value += ':'+ url.port;
url.host = value;
break;
case 'host':
url[part] = value;
if (/:\d+$/.test(value)) {
value = value.split(':');
url.port = value.pop();
url.hostname = value.join(':');
} else {
url.hostname = value;
url.port = '';
}
break;
case 'protocol':
url.protocol = value.toLowerCase();
url.slashes = !fn;
break;
case 'pathname':
case 'hash':
if (value) {
var char = part === 'pathname' ? '/' : '#';
url[part] = value.charAt(0) !== char ? char + value : value;
} else {
url[part] = value;
}
break;
default:
url[part] = value;
}
for (var i = 0; i < rules.length; i++) {
var ins = rules[i];
if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
}
url.origin = url.protocol && url.host && url.protocol !== 'file:'
? url.protocol +'//'+ url.host
: 'null';
url.href = url.toString();
return url;
}
/**
* Transform the properties back in to a valid and full URL string.
*
* @param {Function} stringify Optional query stringify function.
* @returns {String} Compiled version of the URL.
* @public
*/
function toString(stringify) {
if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
var query
, url = this
, protocol = url.protocol;
if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
var result = protocol + (url.slashes ? '//' : '');
if (url.username) {
result += url.username;
if (url.password) result += ':'+ url.password;
result += '@';
}
result += url.host + url.pathname;
query = 'object' === typeof url.query ? stringify(url.query) : url.query;
if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
if (url.hash) result += url.hash;
return result;
}
Url.prototype = { set: set, toString: toString };
//
// Expose the URL parser and some additional properties that might be useful for
// others or testing.
//
Url.extractProtocol = extractProtocol;
Url.location = lolcation;
Url.trimLeft = trimLeft;
Url.qs = qs;
module.exports = Url;
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"querystringify":41,"requires-port":42}],60:[function(require,module,exports){
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.WHATWGFetch = {})));
}(this, (function (exports) { 'use strict';
var global =
(typeof globalThis !== 'undefined' && globalThis) ||
(typeof self !== 'undefined' && self) ||
(typeof global !== 'undefined' && global);
var support = {
searchParams: 'URLSearchParams' in global,
iterable: 'Symbol' in global && 'iterator' in Symbol,
blob:
'FileReader' in global &&
'Blob' in global &&
(function() {
try {
new Blob();
return true
} catch (e) {
return false
}
})(),
formData: 'FormData' in global,
arrayBuffer: 'ArrayBuffer' in global
};
function isDataView(obj) {
return obj && DataView.prototype.isPrototypeOf(obj)
}
if (support.arrayBuffer) {
var viewClasses = [
'[object Int8Array]',
'[object Uint8Array]',
'[object Uint8ClampedArray]',
'[object Int16Array]',
'[object Uint16Array]',
'[object Int32Array]',
'[object Uint32Array]',
'[object Float32Array]',
'[object Float64Array]'
];
var isArrayBufferView =
ArrayBuffer.isView ||
function(obj) {
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
};
}
function normalizeName(name) {
if (typeof name !== 'string') {
name = String(name);
}
if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') {
throw new TypeError('Invalid character in header field name: "' + name + '"')
}
return name.toLowerCase()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = String(value);
}
return value
}
// Build a destructive iterator for the value list
function iteratorFor(items) {
var iterator = {
next: function() {
var value = items.shift();
return {done: value === undefined, value: value}
}
};
if (support.iterable) {
iterator[Symbol.iterator] = function() {
return iterator
};
}
return iterator
}
function Headers(headers) {
this.map = {};
if (headers instanceof Headers) {
headers.forEach(function(value, name) {
this.append(name, value);
}, this);
} else if (Array.isArray(headers)) {
headers.forEach(function(header) {
this.append(header[0], header[1]);
}, this);
} else if (headers) {
Object.getOwnPropertyNames(headers).forEach(function(name) {
this.append(name, headers[name]);
}, this);
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name);
value = normalizeValue(value);
var oldValue = this.map[name];
this.map[name] = oldValue ? oldValue + ', ' + value : value;
};
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)];
};
Headers.prototype.get = function(name) {
name = normalizeName(name);
return this.has(name) ? this.map[name] : null
};
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
};
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = normalizeValue(value);
};
Headers.prototype.forEach = function(callback, thisArg) {
for (var name in this.map) {
if (this.map.hasOwnProperty(name)) {
callback.call(thisArg, this.map[name], name, this);
}
}
};
Headers.prototype.keys = function() {
var items = [];
this.forEach(function(value, name) {
items.push(name);
});
return iteratorFor(items)
};
Headers.prototype.values = function() {
var items = [];
this.forEach(function(value) {
items.push(value);
});
return iteratorFor(items)
};
Headers.prototype.entries = function() {
var items = [];
this.forEach(function(value, name) {
items.push([name, value]);
});
return iteratorFor(items)
};
if (support.iterable) {
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true;
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result);
};
reader.onerror = function() {
reject(reader.error);
};
})
}
function readBlobAsArrayBuffer(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsArrayBuffer(blob);
return promise
}
function readBlobAsText(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsText(blob);
return promise
}
function readArrayBufferAsText(buf) {
var view = new Uint8Array(buf);
var chars = new Array(view.length);
for (var i = 0; i < view.length; i++) {
chars[i] = String.fromCharCode(view[i]);
}
return chars.join('')
}
function bufferClone(buf) {
if (buf.slice) {
return buf.slice(0)
} else {
var view = new Uint8Array(buf.byteLength);
view.set(new Uint8Array(buf));
return view.buffer
}
}
function Body() {
this.bodyUsed = false;
this._initBody = function(body) {
/*
fetch-mock wraps the Response object in an ES6 Proxy to
provide useful test harness features such as flush. However, on
ES5 browsers without fetch or Proxy support pollyfills must be used;
the proxy-pollyfill is unable to proxy an attribute unless it exists
on the object before the Proxy is created. This change ensures
Response.bodyUsed exists on the instance, while maintaining the
semantic of setting Request.bodyUsed in the constructor before
_initBody is called.
*/
this.bodyUsed = this.bodyUsed;
this._bodyInit = body;
if (!body) {
this._bodyText = '';
} else if (typeof body === 'string') {
this._bodyText = body;
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
this._bodyBlob = body;
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
this._bodyFormData = body;
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this._bodyText = body.toString();
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
this._bodyArrayBuffer = bufferClone(body.buffer);
// IE 10-11 can't handle a DataView body.
this._bodyInit = new Blob([this._bodyArrayBuffer]);
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
this._bodyArrayBuffer = bufferClone(body);
} else {
this._bodyText = body = Object.prototype.toString.call(body);
}
if (!this.headers.get('content-type')) {
if (typeof body === 'string') {
this.headers.set('content-type', 'text/plain;charset=UTF-8');
} else if (this._bodyBlob && this._bodyBlob.type) {
this.headers.set('content-type', this._bodyBlob.type);
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
}
}
};
if (support.blob) {
this.blob = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return Promise.resolve(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as blob')
} else {
return Promise.resolve(new Blob([this._bodyText]))
}
};
this.arrayBuffer = function() {
if (this._bodyArrayBuffer) {
var isConsumed = consumed(this);
if (isConsumed) {
return isConsumed
}
if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
return Promise.resolve(
this._bodyArrayBuffer.buffer.slice(
this._bodyArrayBuffer.byteOffset,
this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
)
)
} else {
return Promise.resolve(this._bodyArrayBuffer)
}
} else {
return this.blob().then(readBlobAsArrayBuffer)
}
};
}
this.text = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return readBlobAsText(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
};
if (support.formData) {
this.formData = function() {
return this.text().then(decode)
};
}
this.json = function() {
return this.text().then(JSON.parse)
};
return this
}
// HTTP methods whose capitalization should be normalized
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
function normalizeMethod(method) {
var upcased = method.toUpperCase();
return methods.indexOf(upcased) > -1 ? upcased : method
}
function Request(input, options) {
if (!(this instanceof Request)) {
throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
}
options = options || {};
var body = options.body;
if (input instanceof Request) {
if (input.bodyUsed) {
throw new TypeError('Already read')
}
this.url = input.url;
this.credentials = input.credentials;
if (!options.headers) {
this.headers = new Headers(input.headers);
}
this.method = input.method;
this.mode = input.mode;
this.signal = input.signal;
if (!body && input._bodyInit != null) {
body = input._bodyInit;
input.bodyUsed = true;
}
} else {
this.url = String(input);
}
this.credentials = options.credentials || this.credentials || 'same-origin';
if (options.headers || !this.headers) {
this.headers = new Headers(options.headers);
}
this.method = normalizeMethod(options.method || this.method || 'GET');
this.mode = options.mode || this.mode || null;
this.signal = options.signal || this.signal;
this.referrer = null;
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
throw new TypeError('Body not allowed for GET or HEAD requests')
}
this._initBody(body);
if (this.method === 'GET' || this.method === 'HEAD') {
if (options.cache === 'no-store' || options.cache === 'no-cache') {
// Search for a '_' parameter in the query string
var reParamSearch = /([?&])_=[^&]*/;
if (reParamSearch.test(this.url)) {
// If it already exists then set the value with the current time
this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime());
} else {
// Otherwise add a new '_' parameter to the end with the current time
var reQueryString = /\?/;
this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime();
}
}
}
}
Request.prototype.clone = function() {
return new Request(this, {body: this._bodyInit})
};
function decode(body) {
var form = new FormData();
body
.trim()
.split('&')
.forEach(function(bytes) {
if (bytes) {
var split = bytes.split('=');
var name = split.shift().replace(/\+/g, ' ');
var value = split.join('=').replace(/\+/g, ' ');
form.append(decodeURIComponent(name), decodeURIComponent(value));
}
});
return form
}
function parseHeaders(rawHeaders) {
var headers = new Headers();
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
// https://tools.ietf.org/html/rfc7230#section-3.2
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
// Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill
// https://github.com/github/fetch/issues/748
// https://github.com/zloirock/core-js/issues/751
preProcessedHeaders
.split('\r')
.map(function(header) {
return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header
})
.forEach(function(line) {
var parts = line.split(':');
var key = parts.shift().trim();
if (key) {
var value = parts.join(':').trim();
headers.append(key, value);
}
});
return headers
}
Body.call(Request.prototype);
function Response(bodyInit, options) {
if (!(this instanceof Response)) {
throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
}
if (!options) {
options = {};
}
this.type = 'default';
this.status = options.status === undefined ? 200 : options.status;
this.ok = this.status >= 200 && this.status < 300;
this.statusText = options.statusText === undefined ? '' : '' + options.statusText;
this.headers = new Headers(options.headers);
this.url = options.url || '';
this._initBody(bodyInit);
}
Body.call(Response.prototype);
Response.prototype.clone = function() {
return new Response(this._bodyInit, {
status: this.status,
statusText: this.statusText,
headers: new Headers(this.headers),
url: this.url
})
};
Response.error = function() {
var response = new Response(null, {status: 0, statusText: ''});
response.type = 'error';
return response
};
var redirectStatuses = [301, 302, 303, 307, 308];
Response.redirect = function(url, status) {
if (redirectStatuses.indexOf(status) === -1) {
throw new RangeError('Invalid status code')
}
return new Response(null, {status: status, headers: {location: url}})
};
exports.DOMException = global.DOMException;
try {
new exports.DOMException();
} catch (err) {
exports.DOMException = function(message, name) {
this.message = message;
this.name = name;
var error = Error(message);
this.stack = error.stack;
};
exports.DOMException.prototype = Object.create(Error.prototype);
exports.DOMException.prototype.constructor = exports.DOMException;
}
function fetch(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init);
if (request.signal && request.signal.aborted) {
return reject(new exports.DOMException('Aborted', 'AbortError'))
}
var xhr = new XMLHttpRequest();
function abortXhr() {
xhr.abort();
}
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
};
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
var body = 'response' in xhr ? xhr.response : xhr.responseText;
setTimeout(function() {
resolve(new Response(body, options));
}, 0);
};
xhr.onerror = function() {
setTimeout(function() {
reject(new TypeError('Network request failed'));
}, 0);
};
xhr.ontimeout = function() {
setTimeout(function() {
reject(new TypeError('Network request failed'));
}, 0);
};
xhr.onabort = function() {
setTimeout(function() {
reject(new exports.DOMException('Aborted', 'AbortError'));
}, 0);
};
function fixUrl(url) {
try {
return url === '' && global.location.href ? global.location.href : url
} catch (e) {
return url
}
}
xhr.open(request.method, fixUrl(request.url), true);
if (request.credentials === 'include') {
xhr.withCredentials = true;
} else if (request.credentials === 'omit') {
xhr.withCredentials = false;
}
if ('responseType' in xhr) {
if (support.blob) {
xhr.responseType = 'blob';
} else if (
support.arrayBuffer &&
request.headers.get('Content-Type') &&
request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1
) {
xhr.responseType = 'arraybuffer';
}
}
if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers)) {
Object.getOwnPropertyNames(init.headers).forEach(function(name) {
xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
});
} else {
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value);
});
}
if (request.signal) {
request.signal.addEventListener('abort', abortXhr);
xhr.onreadystatechange = function() {
// DONE (success or failure)
if (xhr.readyState === 4) {
request.signal.removeEventListener('abort', abortXhr);
}
};
}
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
})
}
fetch.polyfill = true;
if (!global.fetch) {
global.fetch = fetch;
global.Headers = Headers;
global.Request = Request;
global.Response = Response;
}
exports.Headers = Headers;
exports.Request = Request;
exports.Response = Response;
exports.fetch = fetch;
Object.defineProperty(exports, '__esModule', { value: true });
})));
},{}],61:[function(require,module,exports){
/* jshint node: true */
'use strict';
/**
# wildcard
Very simple wildcard matching, which is designed to provide the same
functionality that is found in the
[eve](https://github.com/adobe-webplatform/eve) eventing library.
## Usage
It works with strings:
<<< examples/strings.js
Arrays:
<<< examples/arrays.js
Objects (matching against keys):
<<< examples/objects.js
While the library works in Node, if you are are looking for file-based
wildcard matching then you should have a look at:
<https://github.com/isaacs/node-glob>
**/
function WildcardMatcher(text, separator) {
this.text = text = text || '';
this.hasWild = ~text.indexOf('*');
this.separator = separator;
this.parts = text.split(separator);
}
WildcardMatcher.prototype.match = function(input) {
var matches = true;
var parts = this.parts;
var ii;
var partsCount = parts.length;
var testParts;
if (typeof input == 'string' || input instanceof String) {
if (!this.hasWild && this.text != input) {
matches = false;
} else {
testParts = (input || '').split(this.separator);
for (ii = 0; matches && ii < partsCount; ii++) {
if (parts[ii] === '*') {
continue;
} else if (ii < testParts.length) {
matches = parts[ii] === testParts[ii];
} else {
matches = false;
}
}
// If matches, then return the component parts
matches = matches && testParts;
}
}
else if (typeof input.splice == 'function') {
matches = [];
for (ii = input.length; ii--; ) {
if (this.match(input[ii])) {
matches[matches.length] = input[ii];
}
}
}
else if (typeof input == 'object') {
matches = {};
for (var key in input) {
if (this.match(key)) {
matches[key] = input[key];
}
}
}
return matches;
};
module.exports = function(text, test, separator) {
var matcher = new WildcardMatcher(text, separator || /[\/\.]/);
if (typeof test != 'undefined') {
return matcher.match(test);
}
return matcher;
};
},{}],62:[function(require,module,exports){
'use strict';
var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('')
, length = 64
, map = {}
, seed = 0
, i = 0
, prev;
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
function encode(num) {
var encoded = '';
do {
encoded = alphabet[num % length] + encoded;
num = Math.floor(num / length);
} while (num > 0);
return encoded;
}
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
function decode(str) {
var decoded = 0;
for (i = 0; i < str.length; i++) {
decoded = decoded * length + map[str.charAt(i)];
}
return decoded;
}
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
function yeast() {
var now = encode(+new Date());
if (now !== prev) return seed = 0, prev = now;
return now +'.'+ encode(seed++);
}
//
// Map each character to its index.
//
for (; i < length; i++) map[alphabet[i]] = i;
//
// Expose the `yeast`, `encode` and `decode` functions.
//
yeast.encode = encode;
yeast.decode = decode;
module.exports = yeast;
},{}],63:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('@uppy/utils/lib/AbortController'),
AbortController = _require.AbortController,
createAbortError = _require.createAbortError;
var delay = require('@uppy/utils/lib/delay');
var MB = 1024 * 1024;
var defaultOptions = {
limit: 1,
retryDelays: [0, 1000, 3000, 5000],
getChunkSize: function getChunkSize(file) {
return Math.ceil(file.size / 10000);
},
onStart: function onStart() {},
onProgress: function onProgress() {},
onPartComplete: function onPartComplete() {},
onSuccess: function onSuccess() {},
onError: function onError(err) {
throw err;
}
};
function ensureInt(value) {
if (typeof value === 'string') {
return parseInt(value, 10);
}
if (typeof value === 'number') {
return value;
}
throw new TypeError('Expected a number');
}
var MultipartUploader = /*#__PURE__*/function () {
function MultipartUploader(file, options) {
this.options = _extends({}, defaultOptions, options); // Use default `getChunkSize` if it was null or something
if (!this.options.getChunkSize) {
this.options.getChunkSize = defaultOptions.getChunkSize;
}
this.file = file;
this.abortController = new AbortController();
this.key = this.options.key || null;
this.uploadId = this.options.uploadId || null;
this.parts = []; // Do `this.createdPromise.then(OP)` to execute an operation `OP` _only_ if the
// upload was created already. That also ensures that the sequencing is right
// (so the `OP` definitely happens if the upload is created).
//
// This mostly exists to make `_abortUpload` work well: only sending the abort request if
// the upload was already created, and if the createMultipartUpload request is still in flight,
// aborting it immediately after it finishes.
this.createdPromise = Promise.reject(); // eslint-disable-line prefer-promise-reject-errors
this.isPaused = false;
this.partsInProgress = 0;
this.chunks = null;
this.chunkState = null;
this._initChunks();
this.createdPromise.catch(function () {}); // silence uncaught rejection warning
}
/**
* Was this upload aborted?
*
* If yes, we may need to throw an AbortError.
*
* @returns {boolean}
*/
var _proto = MultipartUploader.prototype;
_proto._aborted = function _aborted() {
return this.abortController.signal.aborted;
};
_proto._initChunks = function _initChunks() {
var chunks = [];
var desiredChunkSize = this.options.getChunkSize(this.file); // at least 5MB per request, at most 10k requests
var minChunkSize = Math.max(5 * MB, Math.ceil(this.file.size / 10000));
var chunkSize = Math.max(desiredChunkSize, minChunkSize); // Upload zero-sized files in one zero-sized chunk
if (this.file.size === 0) {
chunks.push(this.file);
} else {
for (var i = 0; i < this.file.size; i += chunkSize) {
var end = Math.min(this.file.size, i + chunkSize);
chunks.push(this.file.slice(i, end));
}
}
this.chunks = chunks;
this.chunkState = chunks.map(function () {
return {
uploaded: 0,
busy: false,
done: false
};
});
};
_proto._createUpload = function _createUpload() {
var _this = this;
this.createdPromise = Promise.resolve().then(function () {
return _this.options.createMultipartUpload();
});
return this.createdPromise.then(function (result) {
if (_this._aborted()) throw createAbortError();
var valid = typeof result === 'object' && result && typeof result.uploadId === 'string' && typeof result.key === 'string';
if (!valid) {
throw new TypeError('AwsS3/Multipart: Got incorrect result from `createMultipartUpload()`, expected an object `{ uploadId, key }`.');
}
_this.key = result.key;
_this.uploadId = result.uploadId;
_this.options.onStart(result);
_this._uploadParts();
}).catch(function (err) {
_this._onError(err);
});
};
_proto._resumeUpload = function _resumeUpload() {
var _this2 = this;
return Promise.resolve().then(function () {
return _this2.options.listParts({
uploadId: _this2.uploadId,
key: _this2.key
});
}).then(function (parts) {
if (_this2._aborted()) throw createAbortError();
parts.forEach(function (part) {
var i = part.PartNumber - 1;
_this2.chunkState[i] = {
uploaded: ensureInt(part.Size),
etag: part.ETag,
done: true
}; // Only add if we did not yet know about this part.
if (!_this2.parts.some(function (p) {
return p.PartNumber === part.PartNumber;
})) {
_this2.parts.push({
PartNumber: part.PartNumber,
ETag: part.ETag
});
}
});
_this2._uploadParts();
}).catch(function (err) {
_this2._onError(err);
});
};
_proto._uploadParts = function _uploadParts() {
var _this3 = this;
if (this.isPaused) return;
var need = this.options.limit - this.partsInProgress;
if (need === 0) return; // All parts are uploaded.
if (this.chunkState.every(function (state) {
return state.done;
})) {
this._completeUpload();
return;
}
var candidates = [];
for (var i = 0; i < this.chunkState.length; i++) {
var state = this.chunkState[i];
if (state.done || state.busy) continue;
candidates.push(i);
if (candidates.length >= need) {
break;
}
}
candidates.forEach(function (index) {
_this3._uploadPartRetryable(index).then(function () {
// Continue uploading parts
_this3._uploadParts();
}, function (err) {
_this3._onError(err);
});
});
};
_proto._retryable = function _retryable(_ref) {
var _this4 = this;
var before = _ref.before,
attempt = _ref.attempt,
after = _ref.after;
var retryDelays = this.options.retryDelays;
var signal = this.abortController.signal;
if (before) before();
function shouldRetry(err) {
if (err.source && typeof err.source.status === 'number') {
var status = err.source.status; // 0 probably indicates network failure
return status === 0 || status === 409 || status === 423 || status >= 500 && status < 600;
}
return false;
}
var doAttempt = function doAttempt(retryAttempt) {
return attempt().catch(function (err) {
if (_this4._aborted()) throw createAbortError();
if (shouldRetry(err) && retryAttempt < retryDelays.length) {
return delay(retryDelays[retryAttempt], {
signal: signal
}).then(function () {
return doAttempt(retryAttempt + 1);
});
}
throw err;
});
};
return doAttempt(0).then(function (result) {
if (after) after();
return result;
}, function (err) {
if (after) after();
throw err;
});
};
_proto._uploadPartRetryable = function _uploadPartRetryable(index) {
var _this5 = this;
return this._retryable({
before: function before() {
_this5.partsInProgress += 1;
},
attempt: function attempt() {
return _this5._uploadPart(index);
},
after: function after() {
_this5.partsInProgress -= 1;
}
});
};
_proto._uploadPart = function _uploadPart(index) {
var _this6 = this;
var body = this.chunks[index];
this.chunkState[index].busy = true;
return Promise.resolve().then(function () {
return _this6.options.prepareUploadPart({
key: _this6.key,
uploadId: _this6.uploadId,
body: body,
number: index + 1
});
}).then(function (result) {
var valid = typeof result === 'object' && result && typeof result.url === 'string';
if (!valid) {
throw new TypeError('AwsS3/Multipart: Got incorrect result from `prepareUploadPart()`, expected an object `{ url }`.');
}
return result;
}).then(function (_ref2) {
var url = _ref2.url,
headers = _ref2.headers;
if (_this6._aborted()) {
_this6.chunkState[index].busy = false;
throw createAbortError();
}
return _this6._uploadPartBytes(index, url, headers);
});
};
_proto._onPartProgress = function _onPartProgress(index, sent, total) {
this.chunkState[index].uploaded = ensureInt(sent);
var totalUploaded = this.chunkState.reduce(function (n, c) {
return n + c.uploaded;
}, 0);
this.options.onProgress(totalUploaded, this.file.size);
};
_proto._onPartComplete = function _onPartComplete(index, etag) {
this.chunkState[index].etag = etag;
this.chunkState[index].done = true;
var part = {
PartNumber: index + 1,
ETag: etag
};
this.parts.push(part);
this.options.onPartComplete(part);
};
_proto._uploadPartBytes = function _uploadPartBytes(index, url, headers) {
var _this7 = this;
var body = this.chunks[index];
var signal = this.abortController.signal;
var defer;
var promise = new Promise(function (resolve, reject) {
defer = {
resolve: resolve,
reject: reject
};
});
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
if (headers) {
Object.keys(headers).map(function (key) {
xhr.setRequestHeader(key, headers[key]);
});
}
xhr.responseType = 'text';
function cleanup() {
signal.removeEventListener('abort', onabort);
}
function onabort() {
xhr.abort();
}
signal.addEventListener('abort', onabort);
xhr.upload.addEventListener('progress', function (ev) {
if (!ev.lengthComputable) return;
_this7._onPartProgress(index, ev.loaded, ev.total);
});
xhr.addEventListener('abort', function (ev) {
cleanup();
_this7.chunkState[index].busy = false;
defer.reject(createAbortError());
});
xhr.addEventListener('load', function (ev) {
cleanup();
_this7.chunkState[index].busy = false;
if (ev.target.status < 200 || ev.target.status >= 300) {
var error = new Error('Non 2xx');
error.source = ev.target;
defer.reject(error);
return;
}
_this7._onPartProgress(index, body.size, body.size); // NOTE This must be allowed by CORS.
var etag = ev.target.getResponseHeader('ETag');
if (etag === null) {
defer.reject(new Error('AwsS3/Multipart: Could not read the ETag header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.'));
return;
}
_this7._onPartComplete(index, etag);
defer.resolve();
});
xhr.addEventListener('error', function (ev) {
cleanup();
_this7.chunkState[index].busy = false;
var error = new Error('Unknown error');
error.source = ev.target;
defer.reject(error);
});
xhr.send(body);
return promise;
};
_proto._completeUpload = function _completeUpload() {
var _this8 = this;
// Parts may not have completed uploading in sorted order, if limit > 1.
this.parts.sort(function (a, b) {
return a.PartNumber - b.PartNumber;
});
return Promise.resolve().then(function () {
return _this8.options.completeMultipartUpload({
key: _this8.key,
uploadId: _this8.uploadId,
parts: _this8.parts
});
}).then(function (result) {
_this8.options.onSuccess(result);
}, function (err) {
_this8._onError(err);
});
};
_proto._abortUpload = function _abortUpload() {
var _this9 = this;
this.abortController.abort();
this.createdPromise.then(function () {
_this9.options.abortMultipartUpload({
key: _this9.key,
uploadId: _this9.uploadId
});
}, function () {// if the creation failed we do not need to abort
});
};
_proto._onError = function _onError(err) {
if (err && err.name === 'AbortError') {
return;
}
this.options.onError(err);
};
_proto.start = function start() {
this.isPaused = false;
if (this.uploadId) {
this._resumeUpload();
} else {
this._createUpload();
}
};
_proto.pause = function pause() {
this.abortController.abort(); // Swap it out for a new controller, because this instance may be resumed later.
this.abortController = new AbortController();
this.isPaused = true;
};
_proto.abort = function abort(opts) {
if (opts === void 0) {
opts = {};
}
var really = opts.really || false;
if (!really) return this.pause();
this._abortUpload();
};
return MultipartUploader;
}();
module.exports = MultipartUploader;
},{"@uppy/utils/lib/AbortController":212,"@uppy/utils/lib/delay":221}],64:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Socket = _require2.Socket,
Provider = _require2.Provider,
RequestClient = _require2.RequestClient;
var EventTracker = require('@uppy/utils/lib/EventTracker');
var emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress');
var getSocketHost = require('@uppy/utils/lib/getSocketHost');
var RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue');
var Uploader = require('./MultipartUploader');
function assertServerError(res) {
if (res && res.error) {
var error = new Error(res.message);
_extends(error, res.error);
throw error;
}
return res;
}
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(AwsS3Multipart, _Plugin);
function AwsS3Multipart(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'uploader';
_this.id = _this.opts.id || 'AwsS3Multipart';
_this.title = 'AWS S3 Multipart';
_this.client = new RequestClient(uppy, opts);
var defaultOptions = {
timeout: 30 * 1000,
limit: 0,
retryDelays: [0, 1000, 3000, 5000],
createMultipartUpload: _this.createMultipartUpload.bind(_assertThisInitialized(_this)),
listParts: _this.listParts.bind(_assertThisInitialized(_this)),
prepareUploadPart: _this.prepareUploadPart.bind(_assertThisInitialized(_this)),
abortMultipartUpload: _this.abortMultipartUpload.bind(_assertThisInitialized(_this)),
completeMultipartUpload: _this.completeMultipartUpload.bind(_assertThisInitialized(_this))
};
_this.opts = _extends({}, defaultOptions, opts);
_this.upload = _this.upload.bind(_assertThisInitialized(_this));
_this.requests = new RateLimitedQueue(_this.opts.limit);
_this.uploaders = Object.create(null);
_this.uploaderEvents = Object.create(null);
_this.uploaderSockets = Object.create(null);
return _this;
}
/**
* Clean up all references for a file's upload: the MultipartUploader instance,
* any events related to the file, and the Companion WebSocket connection.
*
* Set `opts.abort` to tell S3 that the multipart upload is cancelled and must be removed.
* This should be done when the user cancels the upload, not when the upload is completed or errored.
*/
var _proto = AwsS3Multipart.prototype;
_proto.resetUploaderReferences = function resetUploaderReferences(fileID, opts) {
if (opts === void 0) {
opts = {};
}
if (this.uploaders[fileID]) {
this.uploaders[fileID].abort({
really: opts.abort || false
});
this.uploaders[fileID] = null;
}
if (this.uploaderEvents[fileID]) {
this.uploaderEvents[fileID].remove();
this.uploaderEvents[fileID] = null;
}
if (this.uploaderSockets[fileID]) {
this.uploaderSockets[fileID].close();
this.uploaderSockets[fileID] = null;
}
};
_proto.assertHost = function assertHost(method) {
if (!this.opts.companionUrl) {
throw new Error("Expected a `companionUrl` option containing a Companion address, or if you are not using Companion, a custom `" + method + "` implementation.");
}
};
_proto.createMultipartUpload = function createMultipartUpload(file) {
this.assertHost('createMultipartUpload');
var metadata = {};
Object.keys(file.meta).map(function (key) {
if (file.meta[key] != null) {
metadata[key] = file.meta[key].toString();
}
});
return this.client.post('s3/multipart', {
filename: file.name,
type: file.type,
metadata: metadata
}).then(assertServerError);
};
_proto.listParts = function listParts(file, _ref) {
var key = _ref.key,
uploadId = _ref.uploadId;
this.assertHost('listParts');
var filename = encodeURIComponent(key);
return this.client.get("s3/multipart/" + uploadId + "?key=" + filename).then(assertServerError);
};
_proto.prepareUploadPart = function prepareUploadPart(file, _ref2) {
var key = _ref2.key,
uploadId = _ref2.uploadId,
number = _ref2.number;
this.assertHost('prepareUploadPart');
var filename = encodeURIComponent(key);
return this.client.get("s3/multipart/" + uploadId + "/" + number + "?key=" + filename).then(assertServerError);
};
_proto.completeMultipartUpload = function completeMultipartUpload(file, _ref3) {
var key = _ref3.key,
uploadId = _ref3.uploadId,
parts = _ref3.parts;
this.assertHost('completeMultipartUpload');
var filename = encodeURIComponent(key);
var uploadIdEnc = encodeURIComponent(uploadId);
return this.client.post("s3/multipart/" + uploadIdEnc + "/complete?key=" + filename, {
parts: parts
}).then(assertServerError);
};
_proto.abortMultipartUpload = function abortMultipartUpload(file, _ref4) {
var key = _ref4.key,
uploadId = _ref4.uploadId;
this.assertHost('abortMultipartUpload');
var filename = encodeURIComponent(key);
var uploadIdEnc = encodeURIComponent(uploadId);
return this.client.delete("s3/multipart/" + uploadIdEnc + "?key=" + filename).then(assertServerError);
};
_proto.uploadFile = function uploadFile(file) {
var _this2 = this;
return new Promise(function (resolve, reject) {
var onStart = function onStart(data) {
var cFile = _this2.uppy.getFile(file.id);
_this2.uppy.setFileState(file.id, {
s3Multipart: _extends({}, cFile.s3Multipart, {
key: data.key,
uploadId: data.uploadId
})
});
};
var onProgress = function onProgress(bytesUploaded, bytesTotal) {
_this2.uppy.emit('upload-progress', file, {
uploader: _this2,
bytesUploaded: bytesUploaded,
bytesTotal: bytesTotal
});
};
var onError = function onError(err) {
_this2.uppy.log(err);
_this2.uppy.emit('upload-error', file, err);
queuedRequest.done();
_this2.resetUploaderReferences(file.id);
reject(err);
};
var onSuccess = function onSuccess(result) {
var uploadResp = {
body: _extends({}, result),
uploadURL: result.location
};
queuedRequest.done();
_this2.resetUploaderReferences(file.id);
var cFile = _this2.uppy.getFile(file.id);
_this2.uppy.emit('upload-success', cFile || file, uploadResp);
if (result.location) {
_this2.uppy.log("Download " + upload.file.name + " from " + result.location);
}
resolve(upload);
};
var onPartComplete = function onPartComplete(part) {
var cFile = _this2.uppy.getFile(file.id);
if (!cFile) {
return;
}
_this2.uppy.emit('s3-multipart:part-uploaded', cFile, part);
};
var upload = new Uploader(file.data, _extends({
// .bind to pass the file object to each handler.
createMultipartUpload: _this2.opts.createMultipartUpload.bind(_this2, file),
listParts: _this2.opts.listParts.bind(_this2, file),
prepareUploadPart: _this2.opts.prepareUploadPart.bind(_this2, file),
completeMultipartUpload: _this2.opts.completeMultipartUpload.bind(_this2, file),
abortMultipartUpload: _this2.opts.abortMultipartUpload.bind(_this2, file),
getChunkSize: _this2.opts.getChunkSize ? _this2.opts.getChunkSize.bind(_this2) : null,
onStart: onStart,
onProgress: onProgress,
onError: onError,
onSuccess: onSuccess,
onPartComplete: onPartComplete,
limit: _this2.opts.limit || 5,
retryDelays: _this2.opts.retryDelays || []
}, file.s3Multipart));
_this2.uploaders[file.id] = upload;
_this2.uploaderEvents[file.id] = new EventTracker(_this2.uppy);
var queuedRequest = _this2.requests.run(function () {
if (!file.isPaused) {
upload.start();
} // Don't do anything here, the caller will take care of cancelling the upload itself
// using resetUploaderReferences(). This is because resetUploaderReferences() has to be
// called when this request is still in the queue, and has not been started yet, too. At
// that point this cancellation function is not going to be called.
return function () {};
});
_this2.onFileRemove(file.id, function (removed) {
queuedRequest.abort();
_this2.resetUploaderReferences(file.id, {
abort: true
});
resolve("upload " + removed.id + " was removed");
});
_this2.onCancelAll(file.id, function () {
queuedRequest.abort();
_this2.resetUploaderReferences(file.id, {
abort: true
});
resolve("upload " + file.id + " was canceled");
});
_this2.onFilePause(file.id, function (isPaused) {
if (isPaused) {
// Remove this file from the queue so another file can start in its place.
queuedRequest.abort();
upload.pause();
} else {
// Resuming an upload should be queued, else you could pause and then resume a queued upload to make it skip the queue.
queuedRequest.abort();
queuedRequest = _this2.requests.run(function () {
upload.start();
return function () {};
});
}
});
_this2.onPauseAll(file.id, function () {
queuedRequest.abort();
upload.pause();
});
_this2.onResumeAll(file.id, function () {
queuedRequest.abort();
if (file.error) {
upload.abort();
}
queuedRequest = _this2.requests.run(function () {
upload.start();
return function () {};
});
}); // Don't double-emit upload-started for Golden Retriever-restored files that were already started
if (!file.progress.uploadStarted || !file.isRestored) {
_this2.uppy.emit('upload-started', file);
}
});
};
_proto.uploadRemote = function uploadRemote(file) {
var _this3 = this;
this.resetUploaderReferences(file.id); // Don't double-emit upload-started for Golden Retriever-restored files that were already started
if (!file.progress.uploadStarted || !file.isRestored) {
this.uppy.emit('upload-started', file);
}
if (file.serverToken) {
return this.connectToServerSocket(file);
}
return new Promise(function (resolve, reject) {
var Client = file.remote.providerOptions.provider ? Provider : RequestClient;
var client = new Client(_this3.uppy, file.remote.providerOptions);
client.post(file.remote.url, _extends({}, file.remote.body, {
protocol: 's3-multipart',
size: file.data.size,
metadata: file.meta
})).then(function (res) {
_this3.uppy.setFileState(file.id, {
serverToken: res.token
});
file = _this3.uppy.getFile(file.id);
return file;
}).then(function (file) {
return _this3.connectToServerSocket(file);
}).then(function () {
resolve();
}).catch(function (err) {
_this3.uppy.emit('upload-error', file, err);
reject(err);
});
});
};
_proto.connectToServerSocket = function connectToServerSocket(file) {
var _this4 = this;
return new Promise(function (resolve, reject) {
var token = file.serverToken;
var host = getSocketHost(file.remote.companionUrl);
var socket = new Socket({
target: host + "/api/" + token,
autoOpen: false
});
_this4.uploaderSockets[file.id] = socket;
_this4.uploaderEvents[file.id] = new EventTracker(_this4.uppy);
_this4.onFileRemove(file.id, function (removed) {
queuedRequest.abort();
socket.send('pause', {});
_this4.resetUploaderReferences(file.id, {
abort: true
});
resolve("upload " + file.id + " was removed");
});
_this4.onFilePause(file.id, function (isPaused) {
if (isPaused) {
// Remove this file from the queue so another file can start in its place.
queuedRequest.abort();
socket.send('pause', {});
} else {
// Resuming an upload should be queued, else you could pause and then resume a queued upload to make it skip the queue.
queuedRequest.abort();
queuedRequest = _this4.requests.run(function () {
socket.send('resume', {});
return function () {};
});
}
});
_this4.onPauseAll(file.id, function () {
queuedRequest.abort();
socket.send('pause', {});
});
_this4.onCancelAll(file.id, function () {
queuedRequest.abort();
socket.send('pause', {});
_this4.resetUploaderReferences(file.id);
resolve("upload " + file.id + " was canceled");
});
_this4.onResumeAll(file.id, function () {
queuedRequest.abort();
if (file.error) {
socket.send('pause', {});
}
queuedRequest = _this4.requests.run(function () {
socket.send('resume', {});
});
});
_this4.onRetry(file.id, function () {
// Only do the retry if the upload is actually in progress;
// else we could try to send these messages when the upload is still queued.
// We may need a better check for this since the socket may also be closed
// for other reasons, like network failures.
if (socket.isOpen) {
socket.send('pause', {});
socket.send('resume', {});
}
});
_this4.onRetryAll(file.id, function () {
if (socket.isOpen) {
socket.send('pause', {});
socket.send('resume', {});
}
});
socket.on('progress', function (progressData) {
return emitSocketProgress(_this4, progressData, file);
});
socket.on('error', function (errData) {
_this4.uppy.emit('upload-error', file, new Error(errData.error));
_this4.resetUploaderReferences(file.id);
queuedRequest.done();
reject(new Error(errData.error));
});
socket.on('success', function (data) {
var uploadResp = {
uploadURL: data.url
};
_this4.uppy.emit('upload-success', file, uploadResp);
_this4.resetUploaderReferences(file.id);
queuedRequest.done();
resolve();
});
var queuedRequest = _this4.requests.run(function () {
socket.open();
if (file.isPaused) {
socket.send('pause', {});
}
return function () {};
});
});
};
_proto.upload = function upload(fileIDs) {
var _this5 = this;
if (fileIDs.length === 0) return Promise.resolve();
var promises = fileIDs.map(function (id) {
var file = _this5.uppy.getFile(id);
if (file.isRemote) {
return _this5.uploadRemote(file);
}
return _this5.uploadFile(file);
});
return Promise.all(promises);
};
_proto.onFileRemove = function onFileRemove(fileID, cb) {
this.uploaderEvents[fileID].on('file-removed', function (file) {
if (fileID === file.id) cb(file.id);
});
};
_proto.onFilePause = function onFilePause(fileID, cb) {
this.uploaderEvents[fileID].on('upload-pause', function (targetFileID, isPaused) {
if (fileID === targetFileID) {
// const isPaused = this.uppy.pauseResume(fileID)
cb(isPaused);
}
});
};
_proto.onRetry = function onRetry(fileID, cb) {
this.uploaderEvents[fileID].on('upload-retry', function (targetFileID) {
if (fileID === targetFileID) {
cb();
}
});
};
_proto.onRetryAll = function onRetryAll(fileID, cb) {
var _this6 = this;
this.uploaderEvents[fileID].on('retry-all', function (filesToRetry) {
if (!_this6.uppy.getFile(fileID)) return;
cb();
});
};
_proto.onPauseAll = function onPauseAll(fileID, cb) {
var _this7 = this;
this.uploaderEvents[fileID].on('pause-all', function () {
if (!_this7.uppy.getFile(fileID)) return;
cb();
});
};
_proto.onCancelAll = function onCancelAll(fileID, cb) {
var _this8 = this;
this.uploaderEvents[fileID].on('cancel-all', function () {
if (!_this8.uppy.getFile(fileID)) return;
cb();
});
};
_proto.onResumeAll = function onResumeAll(fileID, cb) {
var _this9 = this;
this.uploaderEvents[fileID].on('resume-all', function () {
if (!_this9.uppy.getFile(fileID)) return;
cb();
});
};
_proto.install = function install() {
var _this$uppy$getState = this.uppy.getState(),
capabilities = _this$uppy$getState.capabilities;
this.uppy.setState({
capabilities: _extends({}, capabilities, {
resumableUploads: true
})
});
this.uppy.addUploader(this.upload);
};
_proto.uninstall = function uninstall() {
var _this$uppy$getState2 = this.uppy.getState(),
capabilities = _this$uppy$getState2.capabilities;
this.uppy.setState({
capabilities: _extends({}, capabilities, {
resumableUploads: false
})
});
this.uppy.removeUploader(this.upload);
};
return AwsS3Multipart;
}(Plugin), _class.VERSION = "1.8.18", _temp);
},{"./MultipartUploader":63,"@uppy/companion-client":75,"@uppy/core":78,"@uppy/utils/lib/EventTracker":213,"@uppy/utils/lib/RateLimitedQueue":217,"@uppy/utils/lib/emitSocketProgress":222,"@uppy/utils/lib/getSocketHost":237}],65:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var cuid = require('cuid');
var _require = require('@uppy/companion-client'),
Provider = _require.Provider,
RequestClient = _require.RequestClient,
Socket = _require.Socket;
var emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress');
var getSocketHost = require('@uppy/utils/lib/getSocketHost');
var EventTracker = require('@uppy/utils/lib/EventTracker');
var ProgressTimeout = require('@uppy/utils/lib/ProgressTimeout');
var NetworkError = require('@uppy/utils/lib/NetworkError');
var isNetworkError = require('@uppy/utils/lib/isNetworkError'); // See XHRUpload
function buildResponseError(xhr, error) {
// No error message
if (!error) error = new Error('Upload error'); // Got an error message string
if (typeof error === 'string') error = new Error(error); // Got something else
if (!(error instanceof Error)) {
error = _extends(new Error('Upload error'), {
data: error
});
}
if (isNetworkError(xhr)) {
error = new NetworkError(error, xhr);
return error;
}
error.request = xhr;
return error;
} // See XHRUpload
function setTypeInBlob(file) {
var dataWithUpdatedType = file.data.slice(0, file.data.size, file.meta.type);
return dataWithUpdatedType;
}
module.exports = /*#__PURE__*/function () {
function MiniXHRUpload(uppy, opts) {
this.uppy = uppy;
this.opts = _extends({
validateStatus: function validateStatus(status, responseText, response) {
return status >= 200 && status < 300;
}
}, opts);
this.requests = opts.__queue;
this.uploaderEvents = Object.create(null);
this.i18n = opts.i18n;
}
var _proto = MiniXHRUpload.prototype;
_proto._getOptions = function _getOptions(file) {
var uppy = this.uppy;
var overrides = uppy.getState().xhrUpload;
var opts = _extends({}, this.opts, overrides || {}, file.xhrUpload || {}, {
headers: {}
});
_extends(opts.headers, this.opts.headers);
if (overrides) {
_extends(opts.headers, overrides.headers);
}
if (file.xhrUpload) {
_extends(opts.headers, file.xhrUpload.headers);
}
return opts;
};
_proto.uploadFile = function uploadFile(id, current, total) {
var file = this.uppy.getFile(id);
if (file.error) {
throw new Error(file.error);
} else if (file.isRemote) {
return this._uploadRemoteFile(file, current, total);
}
return this._uploadLocalFile(file, current, total);
};
_proto._addMetadata = function _addMetadata(formData, meta, opts) {
var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default.
: Object.keys(meta);
metaFields.forEach(function (item) {
formData.append(item, meta[item]);
});
};
_proto._createFormDataUpload = function _createFormDataUpload(file, opts) {
var formPost = new FormData();
this._addMetadata(formPost, file.meta, opts);
var dataWithUpdatedType = setTypeInBlob(file);
if (file.name) {
formPost.append(opts.fieldName, dataWithUpdatedType, file.meta.name);
} else {
formPost.append(opts.fieldName, dataWithUpdatedType);
}
return formPost;
};
_proto._createBareUpload = function _createBareUpload(file, opts) {
return file.data;
};
_proto._onFileRemoved = function _onFileRemoved(fileID, cb) {
this.uploaderEvents[fileID].on('file-removed', function (file) {
if (fileID === file.id) cb(file.id);
});
};
_proto._onRetry = function _onRetry(fileID, cb) {
this.uploaderEvents[fileID].on('upload-retry', function (targetFileID) {
if (fileID === targetFileID) {
cb();
}
});
};
_proto._onRetryAll = function _onRetryAll(fileID, cb) {
var _this = this;
this.uploaderEvents[fileID].on('retry-all', function (filesToRetry) {
if (!_this.uppy.getFile(fileID)) return;
cb();
});
};
_proto._onCancelAll = function _onCancelAll(fileID, cb) {
var _this2 = this;
this.uploaderEvents[fileID].on('cancel-all', function () {
if (!_this2.uppy.getFile(fileID)) return;
cb();
});
};
_proto._uploadLocalFile = function _uploadLocalFile(file, current, total) {
var _this3 = this;
var opts = this._getOptions(file);
this.uppy.log("uploading " + current + " of " + total);
return new Promise(function (resolve, reject) {
// This is done in index.js in the S3 plugin.
// this.uppy.emit('upload-started', file)
var data = opts.formData ? _this3._createFormDataUpload(file, opts) : _this3._createBareUpload(file, opts);
var xhr = new XMLHttpRequest();
_this3.uploaderEvents[file.id] = new EventTracker(_this3.uppy);
var timer = new ProgressTimeout(opts.timeout, function () {
xhr.abort();
queuedRequest.done();
var error = new Error(_this3.i18n('timedOut', {
seconds: Math.ceil(opts.timeout / 1000)
}));
_this3.uppy.emit('upload-error', file, error);
reject(error);
});
var id = cuid();
xhr.upload.addEventListener('loadstart', function (ev) {
_this3.uppy.log("[AwsS3/XHRUpload] " + id + " started");
});
xhr.upload.addEventListener('progress', function (ev) {
_this3.uppy.log("[AwsS3/XHRUpload] " + id + " progress: " + ev.loaded + " / " + ev.total); // Begin checking for timeouts when progress starts, instead of loading,
// to avoid timing out requests on browser concurrency queue
timer.progress();
if (ev.lengthComputable) {
_this3.uppy.emit('upload-progress', file, {
uploader: _this3,
bytesUploaded: ev.loaded,
bytesTotal: ev.total
});
}
});
xhr.addEventListener('load', function (ev) {
_this3.uppy.log("[AwsS3/XHRUpload] " + id + " finished");
timer.done();
queuedRequest.done();
if (_this3.uploaderEvents[file.id]) {
_this3.uploaderEvents[file.id].remove();
_this3.uploaderEvents[file.id] = null;
}
if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
var _body = opts.getResponseData(xhr.responseText, xhr);
var uploadURL = _body[opts.responseUrlFieldName];
var uploadResp = {
status: ev.target.status,
body: _body,
uploadURL: uploadURL
};
_this3.uppy.emit('upload-success', file, uploadResp);
if (uploadURL) {
_this3.uppy.log("Download " + file.name + " from " + uploadURL);
}
return resolve(file);
}
var body = opts.getResponseData(xhr.responseText, xhr);
var error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr));
var response = {
status: ev.target.status,
body: body
};
_this3.uppy.emit('upload-error', file, error, response);
return reject(error);
});
xhr.addEventListener('error', function (ev) {
_this3.uppy.log("[AwsS3/XHRUpload] " + id + " errored");
timer.done();
queuedRequest.done();
if (_this3.uploaderEvents[file.id]) {
_this3.uploaderEvents[file.id].remove();
_this3.uploaderEvents[file.id] = null;
}
var error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr));
_this3.uppy.emit('upload-error', file, error);
return reject(error);
});
xhr.open(opts.method.toUpperCase(), opts.endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType`
// before `open()` is called.
xhr.withCredentials = opts.withCredentials;
if (opts.responseType !== '') {
xhr.responseType = opts.responseType;
}
Object.keys(opts.headers).forEach(function (header) {
xhr.setRequestHeader(header, opts.headers[header]);
});
var queuedRequest = _this3.requests.run(function () {
xhr.send(data);
return function () {
timer.done();
xhr.abort();
};
}, {
priority: 1
});
_this3._onFileRemoved(file.id, function () {
queuedRequest.abort();
reject(new Error('File removed'));
});
_this3._onCancelAll(file.id, function () {
queuedRequest.abort();
reject(new Error('Upload cancelled'));
});
});
};
_proto._uploadRemoteFile = function _uploadRemoteFile(file, current, total) {
var _this4 = this;
var opts = this._getOptions(file);
return new Promise(function (resolve, reject) {
// This is done in index.js in the S3 plugin.
// this.uppy.emit('upload-started', file)
var fields = {};
var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default.
: Object.keys(file.meta);
metaFields.forEach(function (name) {
fields[name] = file.meta[name];
});
var Client = file.remote.providerOptions.provider ? Provider : RequestClient;
var client = new Client(_this4.uppy, file.remote.providerOptions);
client.post(file.remote.url, _extends({}, file.remote.body, {
endpoint: opts.endpoint,
size: file.data.size,
fieldname: opts.fieldName,
metadata: fields,
httpMethod: opts.method,
useFormData: opts.formData,
headers: opts.headers
})).then(function (res) {
var token = res.token;
var host = getSocketHost(file.remote.companionUrl);
var socket = new Socket({
target: host + "/api/" + token,
autoOpen: false
});
_this4.uploaderEvents[file.id] = new EventTracker(_this4.uppy);
_this4._onFileRemoved(file.id, function () {
socket.send('pause', {});
queuedRequest.abort();
resolve("upload " + file.id + " was removed");
});
_this4._onCancelAll(file.id, function () {
socket.send('pause', {});
queuedRequest.abort();
resolve("upload " + file.id + " was canceled");
});
_this4._onRetry(file.id, function () {
socket.send('pause', {});
socket.send('resume', {});
});
_this4._onRetryAll(file.id, function () {
socket.send('pause', {});
socket.send('resume', {});
});
socket.on('progress', function (progressData) {
return emitSocketProgress(_this4, progressData, file);
});
socket.on('success', function (data) {
var body = opts.getResponseData(data.response.responseText, data.response);
var uploadURL = body[opts.responseUrlFieldName];
var uploadResp = {
status: data.response.status,
body: body,
uploadURL: uploadURL,
bytesUploaded: data.bytesUploaded
};
_this4.uppy.emit('upload-success', file, uploadResp);
queuedRequest.done();
if (_this4.uploaderEvents[file.id]) {
_this4.uploaderEvents[file.id].remove();
_this4.uploaderEvents[file.id] = null;
}
return resolve();
});
socket.on('error', function (errData) {
var resp = errData.response;
var error = resp ? opts.getResponseError(resp.responseText, resp) : _extends(new Error(errData.error.message), {
cause: errData.error
});
_this4.uppy.emit('upload-error', file, error);
queuedRequest.done();
if (_this4.uploaderEvents[file.id]) {
_this4.uploaderEvents[file.id].remove();
_this4.uploaderEvents[file.id] = null;
}
reject(error);
});
var queuedRequest = _this4.requests.run(function () {
socket.open();
if (file.isPaused) {
socket.send('pause', {});
}
return function () {
return socket.close();
};
});
}).catch(function (err) {
_this4.uppy.emit('upload-error', file, err);
reject(err);
});
});
};
return MiniXHRUpload;
}();
},{"@uppy/companion-client":75,"@uppy/utils/lib/EventTracker":213,"@uppy/utils/lib/NetworkError":215,"@uppy/utils/lib/ProgressTimeout":216,"@uppy/utils/lib/emitSocketProgress":222,"@uppy/utils/lib/getSocketHost":237,"@uppy/utils/lib/isNetworkError":244,"cuid":15}],66:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/**
* This plugin is currently a A Big Hack™! The core reason for that is how this plugin
* interacts with Uppy's current pipeline design. The pipeline can handle files in steps,
* including preprocessing, uploading, and postprocessing steps. This plugin initially
* was designed to do its work in a preprocessing step, and let XHRUpload deal with the
* actual file upload as an uploading step. However, Uppy runs steps on all files at once,
* sequentially: first, all files go through a preprocessing step, then, once they are all
* done, they go through the uploading step.
*
* For S3, this causes severely broken behaviour when users upload many files. The
* preprocessing step will request S3 upload URLs that are valid for a short time only,
* but it has to do this for _all_ files, which can take a long time if there are hundreds
* or even thousands of files. By the time the uploader step starts, the first URLs may
* already have expired. If not, the uploading might take such a long time that later URLs
* will expire before some files can be uploaded.
*
* The long-term solution to this problem is to change the upload pipeline so that files
* can be sent to the next step individually. That requires a breaking change, so it is
* planned for some future Uppy version.
*
* In the mean time, this plugin is stuck with a hackier approach: the necessary parts
* of the XHRUpload implementation were copied into this plugin, as the MiniXHRUpload
* class, and this plugin calls into it immediately once it receives an upload URL.
* This isn't as nicely modular as we'd like and requires us to maintain two copies of
* the XHRUpload code, but at least it's not horrifically broken :)
*/
// If global `URL` constructor is available, use it
var URL_ = typeof URL === 'function' ? URL : require('url-parse');
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue');
var settle = require('@uppy/utils/lib/settle');
var hasProperty = require('@uppy/utils/lib/hasProperty');
var _require2 = require('@uppy/companion-client'),
RequestClient = _require2.RequestClient;
var qsStringify = require('qs-stringify');
var MiniXHRUpload = require('./MiniXHRUpload');
var isXml = require('./isXml');
function resolveUrl(origin, link) {
return origin ? new URL_(link, origin).toString() : new URL_(link).toString();
}
/**
* Get the contents of a named tag in an XML source string.
*
* @param {string} source - The XML source string.
* @param {string} tagName - The name of the tag.
* @returns {string} The contents of the tag, or the empty string if the tag does not exist.
*/
function getXmlValue(source, tagName) {
var start = source.indexOf("<" + tagName + ">");
var end = source.indexOf("</" + tagName + ">", start);
return start !== -1 && end !== -1 ? source.slice(start + tagName.length + 2, end) : '';
}
function assertServerError(res) {
if (res && res.error) {
var error = new Error(res.message);
_extends(error, res.error);
throw error;
}
return res;
} // warning deduplication flag: see `getResponseData()` XHRUpload option definition
var warnedSuccessActionStatus = false;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(AwsS3, _Plugin);
function AwsS3(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'uploader';
_this.id = _this.opts.id || 'AwsS3';
_this.title = 'AWS S3';
_this.defaultLocale = {
strings: {
timedOut: 'Upload stalled for %{seconds} seconds, aborting.'
}
};
var defaultOptions = {
timeout: 30 * 1000,
limit: 0,
metaFields: [],
// have to opt in
getUploadParameters: _this.getUploadParameters.bind(_assertThisInitialized(_this))
};
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this.client = new RequestClient(uppy, opts);
_this.handleUpload = _this.handleUpload.bind(_assertThisInitialized(_this));
_this.requests = new RateLimitedQueue(_this.opts.limit);
return _this;
}
var _proto = AwsS3.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.getUploadParameters = function getUploadParameters(file) {
if (!this.opts.companionUrl) {
throw new Error('Expected a `companionUrl` option containing a Companion address.');
}
var filename = file.meta.name;
var type = file.meta.type;
var metadata = {};
this.opts.metaFields.forEach(function (key) {
if (file.meta[key] != null) {
metadata[key] = file.meta[key].toString();
}
});
var query = qsStringify({
filename: filename,
type: type,
metadata: metadata
});
return this.client.get("s3/params?" + query).then(assertServerError);
};
_proto.validateParameters = function validateParameters(file, params) {
var valid = typeof params === 'object' && params && typeof params.url === 'string' && (typeof params.fields === 'object' || params.fields == null);
if (!valid) {
var err = new TypeError("AwsS3: got incorrect result from 'getUploadParameters()' for file '" + file.name + "', expected an object '{ url, method, fields, headers }' but got '" + JSON.stringify(params) + "' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.");
console.error(err);
throw err;
}
var methodIsValid = params.method == null || /^(put|post)$/i.test(params.method);
if (!methodIsValid) {
var _err = new TypeError("AwsS3: got incorrect method from 'getUploadParameters()' for file '" + file.name + "', expected 'put' or 'post' but got '" + params.method + "' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.");
console.error(_err);
throw _err;
}
};
_proto.handleUpload = function handleUpload(fileIDs) {
var _this2 = this;
/**
* keep track of `getUploadParameters()` responses
* so we can cancel the calls individually using just a file ID
*
* @type {object.<string, Promise>}
*/
var paramsPromises = Object.create(null);
function onremove(file) {
var id = file.id;
if (hasProperty(paramsPromises, id)) {
paramsPromises[id].abort();
}
}
this.uppy.on('file-removed', onremove);
fileIDs.forEach(function (id) {
var file = _this2.uppy.getFile(id);
_this2.uppy.emit('upload-started', file);
});
var getUploadParameters = this.requests.wrapPromiseFunction(function (file) {
return _this2.opts.getUploadParameters(file);
});
var numberOfFiles = fileIDs.length;
return settle(fileIDs.map(function (id, index) {
paramsPromises[id] = getUploadParameters(_this2.uppy.getFile(id));
return paramsPromises[id].then(function (params) {
delete paramsPromises[id];
var file = _this2.uppy.getFile(id);
_this2.validateParameters(file, params);
var _params$method = params.method,
method = _params$method === void 0 ? 'post' : _params$method,
url = params.url,
fields = params.fields,
headers = params.headers;
var xhrOpts = {
method: method,
formData: method.toLowerCase() === 'post',
endpoint: url,
metaFields: fields ? Object.keys(fields) : []
};
if (headers) {
xhrOpts.headers = headers;
}
_this2.uppy.setFileState(file.id, {
meta: _extends({}, file.meta, fields),
xhrUpload: xhrOpts
});
return _this2._uploader.uploadFile(file.id, index, numberOfFiles);
}).catch(function (error) {
delete paramsPromises[id];
var file = _this2.uppy.getFile(id);
_this2.uppy.emit('upload-error', file, error);
});
})).then(function (settled) {
// cleanup.
_this2.uppy.off('file-removed', onremove);
return settled;
});
};
_proto.install = function install() {
var uppy = this.uppy;
this.uppy.addUploader(this.handleUpload); // Get the response data from a successful XMLHttpRequest instance.
// `content` is the S3 response as a string.
// `xhr` is the XMLHttpRequest instance.
function defaultGetResponseData(content, xhr) {
var opts = this; // If no response, we've hopefully done a PUT request to the file
// in the bucket on its full URL.
if (!isXml(content, xhr)) {
if (opts.method.toUpperCase() === 'POST') {
if (!warnedSuccessActionStatus) {
uppy.log('[AwsS3] No response data found, make sure to set the success_action_status AWS SDK option to 201. See https://uppy.io/docs/aws-s3/#POST-Uploads', 'warning');
warnedSuccessActionStatus = true;
} // The responseURL won't contain the object key. Give up.
return {
location: null
};
} // responseURL is not available in older browsers.
if (!xhr.responseURL) {
return {
location: null
};
} // Trim the query string because it's going to be a bunch of presign
// parameters for a PUT request—doing a GET request with those will
// always result in an error
return {
location: xhr.responseURL.replace(/\?.*$/, '')
};
}
return {
// Some S3 alternatives do not reply with an absolute URL.
// Eg DigitalOcean Spaces uses /$bucketName/xyz
location: resolveUrl(xhr.responseURL, getXmlValue(content, 'Location')),
bucket: getXmlValue(content, 'Bucket'),
key: getXmlValue(content, 'Key'),
etag: getXmlValue(content, 'ETag')
};
} // Get the error data from a failed XMLHttpRequest instance.
// `content` is the S3 response as a string.
// `xhr` is the XMLHttpRequest instance.
function defaultGetResponseError(content, xhr) {
// If no response, we don't have a specific error message, use the default.
if (!isXml(content, xhr)) {
return;
}
var error = getXmlValue(content, 'Message');
return new Error(error);
}
var xhrOptions = {
fieldName: 'file',
responseUrlFieldName: 'location',
timeout: this.opts.timeout,
// Share the rate limiting queue with XHRUpload.
__queue: this.requests,
responseType: 'text',
getResponseData: this.opts.getResponseData || defaultGetResponseData,
getResponseError: defaultGetResponseError
}; // Only for MiniXHRUpload, remove once we can depend on XHRUpload directly again
xhrOptions.i18n = this.i18n; // Revert to `this.uppy.use(XHRUpload)` once the big comment block at the top of
// this file is solved
this._uploader = new MiniXHRUpload(this.uppy, xhrOptions);
};
_proto.uninstall = function uninstall() {
this.uppy.removeUploader(this.handleUpload);
};
return AwsS3;
}(Plugin), _class.VERSION = "1.8.0", _temp);
},{"./MiniXHRUpload":65,"./isXml":67,"@uppy/companion-client":75,"@uppy/core":78,"@uppy/utils/lib/RateLimitedQueue":217,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/hasProperty":241,"@uppy/utils/lib/settle":251,"qs-stringify":40,"url-parse":59}],67:[function(require,module,exports){
/**
* Remove parameters like `charset=utf-8` from the end of a mime type string.
*
* @param {string} mimeType - The mime type string that may have optional parameters.
* @returns {string} The "base" mime type, i.e. only 'category/type'.
*/
function removeMimeParameters(mimeType) {
return mimeType.replace(/;.*$/, '');
}
/**
* Check if a response contains XML based on the response object and its text content.
*
* @param {string} content - The text body of the response.
* @param {object|XMLHttpRequest} xhr - The XHR object or response object from Companion.
* @returns {bool} Whether the content is (probably) XML.
*/
function isXml(content, xhr) {
var rawContentType = xhr.headers ? xhr.headers['content-type'] : xhr.getResponseHeader('Content-Type');
if (typeof rawContentType === 'string') {
var contentType = removeMimeParameters(rawContentType).toLowerCase();
if (contentType === 'application/xml' || contentType === 'text/xml') {
return true;
} // GCS uses text/html for some reason
// https://github.com/transloadit/uppy/issues/896
if (contentType === 'text/html' && /^<\?xml /.test(content)) {
return true;
}
}
return false;
}
module.exports = isXml;
},{}],68:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider;
var _require3 = require('@uppy/provider-views'),
ProviderViews = _require3.ProviderViews;
var _require4 = require('preact'),
h = _require4.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Box, _Plugin);
function Box(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'Box';
Provider.initPlugin(_assertThisInitialized(_this), opts);
_this.title = _this.opts.title || 'Box';
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#0061D5",
width: "32",
height: "32",
rx: "16"
}), h("g", {
fill: "#fff",
fillRule: "nonzero"
}, h("path", {
d: "m16.4 13.5c-1.6 0-3 0.9-3.7 2.2-0.7-1.3-2.1-2.2-3.7-2.2-1 0-1.8 0.3-2.5 0.8v-3.6c-0.1-0.3-0.5-0.7-1-0.7s-0.8 0.4-0.8 0.8v7c0 2.3 1.9 4.2 4.2 4.2 1.6 0 3-0.9 3.7-2.2 0.7 1.3 2.1 2.2 3.7 2.2 2.3 0 4.2-1.9 4.2-4.2 0.1-2.4-1.8-4.3-4.1-4.3m-7.5 6.8c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5m7.5 0c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5"
}), h("path", {
d: "m27.2 20.6l-2.3-2.8 2.3-2.8c0.3-0.4 0.2-0.9-0.2-1.2s-1-0.2-1.3 0.2l-2 2.4-2-2.4c-0.3-0.4-0.9-0.4-1.3-0.2-0.4 0.3-0.5 0.8-0.2 1.2l2.3 2.8-2.3 2.8c-0.3 0.4-0.2 0.9 0.2 1.2s1 0.2 1.3-0.2l2-2.4 2 2.4c0.3 0.4 0.9 0.4 1.3 0.2 0.4-0.3 0.4-0.8 0.2-1.2"
}))));
};
_this.provider = new Provider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionKeysParams: _this.opts.companionKeysParams,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'box',
pluginId: _this.id
});
_this.onFirstRender = _this.onFirstRender.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Box.prototype;
_proto.install = function install() {
this.view = new ProviderViews(this, {
provider: this.provider
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.view.tearDown();
this.unmount();
};
_proto.onFirstRender = function onFirstRender() {
return this.view.getFolder();
};
_proto.render = function render(state) {
return this.view.render(state);
};
return Box;
}(Plugin), _class.VERSION = "0.3.12", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/provider-views":155,"preact":69}],69:[function(require,module,exports){
!function() {
'use strict';
function VNode() {}
function h(nodeName, attributes) {
var lastSimple, child, simple, i, children = EMPTY_CHILDREN;
for (i = arguments.length; i-- > 2; ) stack.push(arguments[i]);
if (attributes && null != attributes.children) {
if (!stack.length) stack.push(attributes.children);
delete attributes.children;
}
while (stack.length) if ((child = stack.pop()) && void 0 !== child.pop) for (i = child.length; i--; ) stack.push(child[i]); else {
if ('boolean' == typeof child) child = null;
if (simple = 'function' != typeof nodeName) if (null == child) child = ''; else if ('number' == typeof child) child = String(child); else if ('string' != typeof child) simple = !1;
if (simple && lastSimple) children[children.length - 1] += child; else if (children === EMPTY_CHILDREN) children = [ child ]; else children.push(child);
lastSimple = simple;
}
var p = new VNode();
p.nodeName = nodeName;
p.children = children;
p.attributes = null == attributes ? void 0 : attributes;
p.key = null == attributes ? void 0 : attributes.key;
if (void 0 !== options.vnode) options.vnode(p);
return p;
}
function extend(obj, props) {
for (var i in props) obj[i] = props[i];
return obj;
}
function cloneElement(vnode, props) {
return h(vnode.nodeName, extend(extend({}, vnode.attributes), props), arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children);
}
function enqueueRender(component) {
if (!component.__d && (component.__d = !0) && 1 == items.push(component)) (options.debounceRendering || defer)(rerender);
}
function rerender() {
var p, list = items;
items = [];
while (p = list.pop()) if (p.__d) renderComponent(p);
}
function isSameNodeType(node, vnode, hydrating) {
if ('string' == typeof vnode || 'number' == typeof vnode) return void 0 !== node.splitText;
if ('string' == typeof vnode.nodeName) return !node._componentConstructor && isNamedNode(node, vnode.nodeName); else return hydrating || node._componentConstructor === vnode.nodeName;
}
function isNamedNode(node, nodeName) {
return node.__n === nodeName || node.nodeName.toLowerCase() === nodeName.toLowerCase();
}
function getNodeProps(vnode) {
var props = extend({}, vnode.attributes);
props.children = vnode.children;
var defaultProps = vnode.nodeName.defaultProps;
if (void 0 !== defaultProps) for (var i in defaultProps) if (void 0 === props[i]) props[i] = defaultProps[i];
return props;
}
function createNode(nodeName, isSvg) {
var node = isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName);
node.__n = nodeName;
return node;
}
function removeNode(node) {
var parentNode = node.parentNode;
if (parentNode) parentNode.removeChild(node);
}
function setAccessor(node, name, old, value, isSvg) {
if ('className' === name) name = 'class';
if ('key' === name) ; else if ('ref' === name) {
if (old) old(null);
if (value) value(node);
} else if ('class' === name && !isSvg) node.className = value || ''; else if ('style' === name) {
if (!value || 'string' == typeof value || 'string' == typeof old) node.style.cssText = value || '';
if (value && 'object' == typeof value) {
if ('string' != typeof old) for (var i in old) if (!(i in value)) node.style[i] = '';
for (var i in value) node.style[i] = 'number' == typeof value[i] && !1 === IS_NON_DIMENSIONAL.test(i) ? value[i] + 'px' : value[i];
}
} else if ('dangerouslySetInnerHTML' === name) {
if (value) node.innerHTML = value.__html || '';
} else if ('o' == name[0] && 'n' == name[1]) {
var useCapture = name !== (name = name.replace(/Capture$/, ''));
name = name.toLowerCase().substring(2);
if (value) {
if (!old) node.addEventListener(name, eventProxy, useCapture);
} else node.removeEventListener(name, eventProxy, useCapture);
(node.__l || (node.__l = {}))[name] = value;
} else if ('list' !== name && 'type' !== name && !isSvg && name in node) {
setProperty(node, name, null == value ? '' : value);
if (null == value || !1 === value) node.removeAttribute(name);
} else {
var ns = isSvg && name !== (name = name.replace(/^xlink:?/, ''));
if (null == value || !1 === value) if (ns) node.removeAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase()); else node.removeAttribute(name); else if ('function' != typeof value) if (ns) node.setAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase(), value); else node.setAttribute(name, value);
}
}
function setProperty(node, name, value) {
try {
node[name] = value;
} catch (e) {}
}
function eventProxy(e) {
return this.__l[e.type](options.event && options.event(e) || e);
}
function flushMounts() {
var c;
while (c = mounts.pop()) {
if (options.afterMount) options.afterMount(c);
if (c.componentDidMount) c.componentDidMount();
}
}
function diff(dom, vnode, context, mountAll, parent, componentRoot) {
if (!diffLevel++) {
isSvgMode = null != parent && void 0 !== parent.ownerSVGElement;
hydrating = null != dom && !('__preactattr_' in dom);
}
var ret = idiff(dom, vnode, context, mountAll, componentRoot);
if (parent && ret.parentNode !== parent) parent.appendChild(ret);
if (!--diffLevel) {
hydrating = !1;
if (!componentRoot) flushMounts();
}
return ret;
}
function idiff(dom, vnode, context, mountAll, componentRoot) {
var out = dom, prevSvgMode = isSvgMode;
if (null == vnode || 'boolean' == typeof vnode) vnode = '';
if ('string' == typeof vnode || 'number' == typeof vnode) {
if (dom && void 0 !== dom.splitText && dom.parentNode && (!dom._component || componentRoot)) {
if (dom.nodeValue != vnode) dom.nodeValue = vnode;
} else {
out = document.createTextNode(vnode);
if (dom) {
if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
recollectNodeTree(dom, !0);
}
}
out.__preactattr_ = !0;
return out;
}
var vnodeName = vnode.nodeName;
if ('function' == typeof vnodeName) return buildComponentFromVNode(dom, vnode, context, mountAll);
isSvgMode = 'svg' === vnodeName ? !0 : 'foreignObject' === vnodeName ? !1 : isSvgMode;
vnodeName = String(vnodeName);
if (!dom || !isNamedNode(dom, vnodeName)) {
out = createNode(vnodeName, isSvgMode);
if (dom) {
while (dom.firstChild) out.appendChild(dom.firstChild);
if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
recollectNodeTree(dom, !0);
}
}
var fc = out.firstChild, props = out.__preactattr_, vchildren = vnode.children;
if (null == props) {
props = out.__preactattr_ = {};
for (var a = out.attributes, i = a.length; i--; ) props[a[i].name] = a[i].value;
}
if (!hydrating && vchildren && 1 === vchildren.length && 'string' == typeof vchildren[0] && null != fc && void 0 !== fc.splitText && null == fc.nextSibling) {
if (fc.nodeValue != vchildren[0]) fc.nodeValue = vchildren[0];
} else if (vchildren && vchildren.length || null != fc) innerDiffNode(out, vchildren, context, mountAll, hydrating || null != props.dangerouslySetInnerHTML);
diffAttributes(out, vnode.attributes, props);
isSvgMode = prevSvgMode;
return out;
}
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) {
var j, c, f, vchild, child, originalChildren = dom.childNodes, children = [], keyed = {}, keyedLen = 0, min = 0, len = originalChildren.length, childrenLen = 0, vlen = vchildren ? vchildren.length : 0;
if (0 !== len) for (var i = 0; i < len; i++) {
var _child = originalChildren[i], props = _child.__preactattr_, key = vlen && props ? _child._component ? _child._component.__k : props.key : null;
if (null != key) {
keyedLen++;
keyed[key] = _child;
} else if (props || (void 0 !== _child.splitText ? isHydrating ? _child.nodeValue.trim() : !0 : isHydrating)) children[childrenLen++] = _child;
}
if (0 !== vlen) for (var i = 0; i < vlen; i++) {
vchild = vchildren[i];
child = null;
var key = vchild.key;
if (null != key) {
if (keyedLen && void 0 !== keyed[key]) {
child = keyed[key];
keyed[key] = void 0;
keyedLen--;
}
} else if (!child && min < childrenLen) for (j = min; j < childrenLen; j++) if (void 0 !== children[j] && isSameNodeType(c = children[j], vchild, isHydrating)) {
child = c;
children[j] = void 0;
if (j === childrenLen - 1) childrenLen--;
if (j === min) min++;
break;
}
child = idiff(child, vchild, context, mountAll);
f = originalChildren[i];
if (child && child !== dom && child !== f) if (null == f) dom.appendChild(child); else if (child === f.nextSibling) removeNode(f); else dom.insertBefore(child, f);
}
if (keyedLen) for (var i in keyed) if (void 0 !== keyed[i]) recollectNodeTree(keyed[i], !1);
while (min <= childrenLen) if (void 0 !== (child = children[childrenLen--])) recollectNodeTree(child, !1);
}
function recollectNodeTree(node, unmountOnly) {
var component = node._component;
if (component) unmountComponent(component); else {
if (null != node.__preactattr_ && node.__preactattr_.ref) node.__preactattr_.ref(null);
if (!1 === unmountOnly || null == node.__preactattr_) removeNode(node);
removeChildren(node);
}
}
function removeChildren(node) {
node = node.lastChild;
while (node) {
var next = node.previousSibling;
recollectNodeTree(node, !0);
node = next;
}
}
function diffAttributes(dom, attrs, old) {
var name;
for (name in old) if ((!attrs || null == attrs[name]) && null != old[name]) setAccessor(dom, name, old[name], old[name] = void 0, isSvgMode);
for (name in attrs) if (!('children' === name || 'innerHTML' === name || name in old && attrs[name] === ('value' === name || 'checked' === name ? dom[name] : old[name]))) setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
}
function collectComponent(component) {
var name = component.constructor.name;
(components[name] || (components[name] = [])).push(component);
}
function createComponent(Ctor, props, context) {
var inst, list = components[Ctor.name];
if (Ctor.prototype && Ctor.prototype.render) {
inst = new Ctor(props, context);
Component.call(inst, props, context);
} else {
inst = new Component(props, context);
inst.constructor = Ctor;
inst.render = doRender;
}
if (list) for (var i = list.length; i--; ) if (list[i].constructor === Ctor) {
inst.__b = list[i].__b;
list.splice(i, 1);
break;
}
return inst;
}
function doRender(props, state, context) {
return this.constructor(props, context);
}
function setComponentProps(component, props, opts, context, mountAll) {
if (!component.__x) {
component.__x = !0;
if (component.__r = props.ref) delete props.ref;
if (component.__k = props.key) delete props.key;
if (!component.base || mountAll) {
if (component.componentWillMount) component.componentWillMount();
} else if (component.componentWillReceiveProps) component.componentWillReceiveProps(props, context);
if (context && context !== component.context) {
if (!component.__c) component.__c = component.context;
component.context = context;
}
if (!component.__p) component.__p = component.props;
component.props = props;
component.__x = !1;
if (0 !== opts) if (1 === opts || !1 !== options.syncComponentUpdates || !component.base) renderComponent(component, 1, mountAll); else enqueueRender(component);
if (component.__r) component.__r(component);
}
}
function renderComponent(component, opts, mountAll, isChild) {
if (!component.__x) {
var rendered, inst, cbase, props = component.props, state = component.state, context = component.context, previousProps = component.__p || props, previousState = component.__s || state, previousContext = component.__c || context, isUpdate = component.base, nextBase = component.__b, initialBase = isUpdate || nextBase, initialChildComponent = component._component, skip = !1;
if (isUpdate) {
component.props = previousProps;
component.state = previousState;
component.context = previousContext;
if (2 !== opts && component.shouldComponentUpdate && !1 === component.shouldComponentUpdate(props, state, context)) skip = !0; else if (component.componentWillUpdate) component.componentWillUpdate(props, state, context);
component.props = props;
component.state = state;
component.context = context;
}
component.__p = component.__s = component.__c = component.__b = null;
component.__d = !1;
if (!skip) {
rendered = component.render(props, state, context);
if (component.getChildContext) context = extend(extend({}, context), component.getChildContext());
var toUnmount, base, childComponent = rendered && rendered.nodeName;
if ('function' == typeof childComponent) {
var childProps = getNodeProps(rendered);
inst = initialChildComponent;
if (inst && inst.constructor === childComponent && childProps.key == inst.__k) setComponentProps(inst, childProps, 1, context, !1); else {
toUnmount = inst;
component._component = inst = createComponent(childComponent, childProps, context);
inst.__b = inst.__b || nextBase;
inst.__u = component;
setComponentProps(inst, childProps, 0, context, !1);
renderComponent(inst, 1, mountAll, !0);
}
base = inst.base;
} else {
cbase = initialBase;
toUnmount = initialChildComponent;
if (toUnmount) cbase = component._component = null;
if (initialBase || 1 === opts) {
if (cbase) cbase._component = null;
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, !0);
}
}
if (initialBase && base !== initialBase && inst !== initialChildComponent) {
var baseParent = initialBase.parentNode;
if (baseParent && base !== baseParent) {
baseParent.replaceChild(base, initialBase);
if (!toUnmount) {
initialBase._component = null;
recollectNodeTree(initialBase, !1);
}
}
}
if (toUnmount) unmountComponent(toUnmount);
component.base = base;
if (base && !isChild) {
var componentRef = component, t = component;
while (t = t.__u) (componentRef = t).base = base;
base._component = componentRef;
base._componentConstructor = componentRef.constructor;
}
}
if (!isUpdate || mountAll) mounts.unshift(component); else if (!skip) {
if (component.componentDidUpdate) component.componentDidUpdate(previousProps, previousState, previousContext);
if (options.afterUpdate) options.afterUpdate(component);
}
if (null != component.__h) while (component.__h.length) component.__h.pop().call(component);
if (!diffLevel && !isChild) flushMounts();
}
}
function buildComponentFromVNode(dom, vnode, context, mountAll) {
var c = dom && dom._component, originalComponent = c, oldDom = dom, isDirectOwner = c && dom._componentConstructor === vnode.nodeName, isOwner = isDirectOwner, props = getNodeProps(vnode);
while (c && !isOwner && (c = c.__u)) isOwner = c.constructor === vnode.nodeName;
if (c && isOwner && (!mountAll || c._component)) {
setComponentProps(c, props, 3, context, mountAll);
dom = c.base;
} else {
if (originalComponent && !isDirectOwner) {
unmountComponent(originalComponent);
dom = oldDom = null;
}
c = createComponent(vnode.nodeName, props, context);
if (dom && !c.__b) {
c.__b = dom;
oldDom = null;
}
setComponentProps(c, props, 1, context, mountAll);
dom = c.base;
if (oldDom && dom !== oldDom) {
oldDom._component = null;
recollectNodeTree(oldDom, !1);
}
}
return dom;
}
function unmountComponent(component) {
if (options.beforeUnmount) options.beforeUnmount(component);
var base = component.base;
component.__x = !0;
if (component.componentWillUnmount) component.componentWillUnmount();
component.base = null;
var inner = component._component;
if (inner) unmountComponent(inner); else if (base) {
if (base.__preactattr_ && base.__preactattr_.ref) base.__preactattr_.ref(null);
component.__b = base;
removeNode(base);
collectComponent(component);
removeChildren(base);
}
if (component.__r) component.__r(null);
}
function Component(props, context) {
this.__d = !0;
this.context = context;
this.props = props;
this.state = this.state || {};
}
function render(vnode, parent, merge) {
return diff(merge, vnode, {}, !1, parent, !1);
}
var options = {};
var stack = [];
var EMPTY_CHILDREN = [];
var defer = 'function' == typeof Promise ? Promise.resolve().then.bind(Promise.resolve()) : setTimeout;
var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
var items = [];
var mounts = [];
var diffLevel = 0;
var isSvgMode = !1;
var hydrating = !1;
var components = {};
extend(Component.prototype, {
setState: function(state, callback) {
var s = this.state;
if (!this.__s) this.__s = extend({}, s);
extend(s, 'function' == typeof state ? state(s, this.props) : state);
if (callback) (this.__h = this.__h || []).push(callback);
enqueueRender(this);
},
forceUpdate: function(callback) {
if (callback) (this.__h = this.__h || []).push(callback);
renderComponent(this, 2);
},
render: function() {}
});
var preact = {
h: h,
createElement: h,
cloneElement: cloneElement,
Component: Component,
render: render,
rerender: rerender,
options: options
};
if ('undefined' != typeof module) module.exports = preact; else self.preact = preact;
}();
},{}],70:[function(require,module,exports){
'use strict';
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var AuthError = /*#__PURE__*/function (_Error) {
_inheritsLoose(AuthError, _Error);
function AuthError() {
var _this;
_this = _Error.call(this, 'Authorization required') || this;
_this.name = 'AuthError';
_this.isAuthError = true;
return _this;
}
return AuthError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
module.exports = AuthError;
},{}],71:[function(require,module,exports){
'use strict';
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var qsStringify = require('qs-stringify');
var URL = require('url-parse');
var RequestClient = require('./RequestClient');
var tokenStorage = require('./tokenStorage');
var _getName = function _getName(id) {
return id.split('-').map(function (s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}).join(' ');
};
module.exports = /*#__PURE__*/function (_RequestClient) {
_inheritsLoose(Provider, _RequestClient);
function Provider(uppy, opts) {
var _this;
_this = _RequestClient.call(this, uppy, opts) || this;
_this.provider = opts.provider;
_this.id = _this.provider;
_this.name = _this.opts.name || _getName(_this.id);
_this.pluginId = _this.opts.pluginId;
_this.tokenKey = "companion-" + _this.pluginId + "-auth-token";
_this.companionKeysParams = _this.opts.companionKeysParams;
_this.preAuthToken = null;
return _this;
}
var _proto = Provider.prototype;
_proto.headers = function headers() {
var _this2 = this;
return Promise.all([_RequestClient.prototype.headers.call(this), this.getAuthToken()]).then(function (_ref) {
var headers = _ref[0],
token = _ref[1];
var authHeaders = {};
if (token) {
authHeaders['uppy-auth-token'] = token;
}
if (_this2.companionKeysParams) {
authHeaders['uppy-credentials-params'] = btoa(JSON.stringify({
params: _this2.companionKeysParams
}));
}
return _extends({}, headers, authHeaders);
});
};
_proto.onReceiveResponse = function onReceiveResponse(response) {
response = _RequestClient.prototype.onReceiveResponse.call(this, response);
var plugin = this.uppy.getPlugin(this.pluginId);
var oldAuthenticated = plugin.getPluginState().authenticated;
var authenticated = oldAuthenticated ? response.status !== 401 : response.status < 400;
plugin.setPluginState({
authenticated: authenticated
});
return response;
} // @todo(i.olarewaju) consider whether or not this method should be exposed
;
_proto.setAuthToken = function setAuthToken(token) {
return this.uppy.getPlugin(this.pluginId).storage.setItem(this.tokenKey, token);
};
_proto.getAuthToken = function getAuthToken() {
return this.uppy.getPlugin(this.pluginId).storage.getItem(this.tokenKey);
};
_proto.authUrl = function authUrl(queries) {
if (queries === void 0) {
queries = {};
}
if (this.preAuthToken) {
queries.uppyPreAuthToken = this.preAuthToken;
}
var strigifiedQueries = qsStringify(queries);
strigifiedQueries = strigifiedQueries ? "?" + strigifiedQueries : strigifiedQueries;
return this.hostname + "/" + this.id + "/connect" + strigifiedQueries;
};
_proto.fileUrl = function fileUrl(id) {
return this.hostname + "/" + this.id + "/get/" + id;
};
_proto.fetchPreAuthToken = function fetchPreAuthToken() {
var _this3 = this;
if (!this.companionKeysParams) {
return Promise.resolve();
}
return this.post(this.id + "/preauth/", {
params: this.companionKeysParams
}).then(function (res) {
_this3.preAuthToken = res.token;
}).catch(function (err) {
_this3.uppy.log("[CompanionClient] unable to fetch preAuthToken " + err, 'warning');
});
};
_proto.list = function list(directory) {
return this.get(this.id + "/list/" + (directory || ''));
};
_proto.logout = function logout() {
var _this4 = this;
return this.get(this.id + "/logout").then(function (response) {
return Promise.all([response, _this4.uppy.getPlugin(_this4.pluginId).storage.removeItem(_this4.tokenKey)]);
}).then(function (_ref2) {
var response = _ref2[0];
return response;
});
};
Provider.initPlugin = function initPlugin(plugin, opts, defaultOpts) {
plugin.type = 'acquirer';
plugin.files = [];
if (defaultOpts) {
plugin.opts = _extends({}, defaultOpts, opts);
}
if (opts.serverUrl || opts.serverPattern) {
throw new Error('`serverUrl` and `serverPattern` have been renamed to `companionUrl` and `companionAllowedHosts` respectively in the 0.30.5 release. Please consult the docs (for example, https://uppy.io/docs/instagram/ for the Instagram plugin) and use the updated options.`');
}
if (opts.companionAllowedHosts) {
var pattern = opts.companionAllowedHosts; // validate companionAllowedHosts param
if (typeof pattern !== 'string' && !Array.isArray(pattern) && !(pattern instanceof RegExp)) {
throw new TypeError(plugin.id + ": the option \"companionAllowedHosts\" must be one of string, Array, RegExp");
}
plugin.opts.companionAllowedHosts = pattern;
} else {
// does not start with https://
if (/^(?!https?:\/\/).*$/i.test(opts.companionUrl)) {
plugin.opts.companionAllowedHosts = "https://" + opts.companionUrl.replace(/^\/\//, '');
} else {
plugin.opts.companionAllowedHosts = new URL(opts.companionUrl).origin;
}
}
plugin.storage = plugin.opts.storage || tokenStorage;
};
return Provider;
}(RequestClient);
},{"./RequestClient":72,"./tokenStorage":76,"qs-stringify":40,"url-parse":59}],72:[function(require,module,exports){
'use strict';
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
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); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var AuthError = require('./AuthError');
var fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError'); // Remove the trailing slash so we can always safely append /xyz.
function stripSlash(url) {
return url.replace(/\/$/, '');
}
module.exports = (_temp = _class = /*#__PURE__*/function () {
function RequestClient(uppy, opts) {
this.uppy = uppy;
this.opts = opts;
this.onReceiveResponse = this.onReceiveResponse.bind(this);
this.allowedHeaders = ['accept', 'content-type', 'uppy-auth-token'];
this.preflightDone = false;
}
var _proto = RequestClient.prototype;
_proto.headers = function headers() {
var userHeaders = this.opts.companionHeaders || this.opts.serverHeaders || {};
return Promise.resolve(_extends({}, this.defaultHeaders, userHeaders));
};
_proto._getPostResponseFunc = function _getPostResponseFunc(skip) {
var _this = this;
return function (response) {
if (!skip) {
return _this.onReceiveResponse(response);
}
return response;
};
};
_proto.onReceiveResponse = function onReceiveResponse(response) {
var state = this.uppy.getState();
var companion = state.companion || {};
var host = this.opts.companionUrl;
var headers = response.headers; // Store the self-identified domain name for the Companion instance we just hit.
if (headers.has('i-am') && headers.get('i-am') !== companion[host]) {
var _extends2;
this.uppy.setState({
companion: _extends({}, companion, (_extends2 = {}, _extends2[host] = headers.get('i-am'), _extends2))
});
}
return response;
};
_proto._getUrl = function _getUrl(url) {
if (/^(https?:|)\/\//.test(url)) {
return url;
}
return this.hostname + "/" + url;
};
_proto._json = function _json(res) {
if (res.status === 401) {
throw new AuthError();
}
if (res.status < 200 || res.status > 300) {
var errMsg = "Failed request with status: " + res.status + ". " + res.statusText;
return res.json().then(function (errData) {
errMsg = errData.message ? errMsg + " message: " + errData.message : errMsg;
errMsg = errData.requestId ? errMsg + " request-Id: " + errData.requestId : errMsg;
throw new Error(errMsg);
}).catch(function () {
throw new Error(errMsg);
});
}
return res.json();
};
_proto.preflight = function preflight(path) {
var _this2 = this;
if (this.preflightDone) {
return Promise.resolve(this.allowedHeaders.slice());
}
return fetch(this._getUrl(path), {
method: 'OPTIONS'
}).then(function (response) {
if (response.headers.has('access-control-allow-headers')) {
_this2.allowedHeaders = response.headers.get('access-control-allow-headers').split(',').map(function (headerName) {
return headerName.trim().toLowerCase();
});
}
_this2.preflightDone = true;
return _this2.allowedHeaders.slice();
}).catch(function (err) {
_this2.uppy.log("[CompanionClient] unable to make preflight request " + err, 'warning');
_this2.preflightDone = true;
return _this2.allowedHeaders.slice();
});
};
_proto.preflightAndHeaders = function preflightAndHeaders(path) {
var _this3 = this;
return Promise.all([this.preflight(path), this.headers()]).then(function (_ref) {
var allowedHeaders = _ref[0],
headers = _ref[1];
// filter to keep only allowed Headers
Object.keys(headers).forEach(function (header) {
if (allowedHeaders.indexOf(header.toLowerCase()) === -1) {
_this3.uppy.log("[CompanionClient] excluding unallowed header " + header);
delete headers[header];
}
});
return headers;
});
};
_proto.get = function get(path, skipPostResponse) {
var _this4 = this;
return this.preflightAndHeaders(path).then(function (headers) {
return fetchWithNetworkError(_this4._getUrl(path), {
method: 'get',
headers: headers,
credentials: _this4.opts.companionCookiesRule || 'same-origin'
});
}).then(this._getPostResponseFunc(skipPostResponse)).then(function (res) {
return _this4._json(res);
}).catch(function (err) {
if (!err.isAuthError) {
err.message = "Could not get " + _this4._getUrl(path) + ". " + err.message;
}
return Promise.reject(err);
});
};
_proto.post = function post(path, data, skipPostResponse) {
var _this5 = this;
return this.preflightAndHeaders(path).then(function (headers) {
return fetchWithNetworkError(_this5._getUrl(path), {
method: 'post',
headers: headers,
credentials: _this5.opts.companionCookiesRule || 'same-origin',
body: JSON.stringify(data)
});
}).then(this._getPostResponseFunc(skipPostResponse)).then(function (res) {
return _this5._json(res);
}).catch(function (err) {
if (!err.isAuthError) {
err.message = "Could not post " + _this5._getUrl(path) + ". " + err.message;
}
return Promise.reject(err);
});
};
_proto.delete = function _delete(path, data, skipPostResponse) {
var _this6 = this;
return this.preflightAndHeaders(path).then(function (headers) {
return fetchWithNetworkError(_this6.hostname + "/" + path, {
method: 'delete',
headers: headers,
credentials: _this6.opts.companionCookiesRule || 'same-origin',
body: data ? JSON.stringify(data) : null
});
}).then(this._getPostResponseFunc(skipPostResponse)).then(function (res) {
return _this6._json(res);
}).catch(function (err) {
if (!err.isAuthError) {
err.message = "Could not delete " + _this6._getUrl(path) + ". " + err.message;
}
return Promise.reject(err);
});
};
_createClass(RequestClient, [{
key: "hostname",
get: function get() {
var _this$uppy$getState = this.uppy.getState(),
companion = _this$uppy$getState.companion;
var host = this.opts.companionUrl;
return stripSlash(companion && companion[host] ? companion[host] : host);
}
}, {
key: "defaultHeaders",
get: function get() {
return {
Accept: 'application/json',
'Content-Type': 'application/json',
'Uppy-Versions': "@uppy/companion-client=" + RequestClient.VERSION
};
}
}]);
return RequestClient;
}(), _class.VERSION = "1.10.2", _temp);
},{"./AuthError":70,"@uppy/utils/lib/fetchWithNetworkError":223}],73:[function(require,module,exports){
'use strict';
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var RequestClient = require('./RequestClient');
var _getName = function _getName(id) {
return id.split('-').map(function (s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}).join(' ');
};
module.exports = /*#__PURE__*/function (_RequestClient) {
_inheritsLoose(SearchProvider, _RequestClient);
function SearchProvider(uppy, opts) {
var _this;
_this = _RequestClient.call(this, uppy, opts) || this;
_this.provider = opts.provider;
_this.id = _this.provider;
_this.name = _this.opts.name || _getName(_this.id);
_this.pluginId = _this.opts.pluginId;
return _this;
}
var _proto = SearchProvider.prototype;
_proto.fileUrl = function fileUrl(id) {
return this.hostname + "/search/" + this.id + "/get/" + id;
};
_proto.search = function search(text, queries) {
queries = queries ? "&" + queries : '';
return this.get("search/" + this.id + "/list?q=" + encodeURIComponent(text) + queries);
};
return SearchProvider;
}(RequestClient);
},{"./RequestClient":72}],74:[function(require,module,exports){
var ee = require('namespace-emitter');
module.exports = /*#__PURE__*/function () {
function UppySocket(opts) {
this.opts = opts;
this._queued = [];
this.isOpen = false;
this.emitter = ee();
this._handleMessage = this._handleMessage.bind(this);
this.close = this.close.bind(this);
this.emit = this.emit.bind(this);
this.on = this.on.bind(this);
this.once = this.once.bind(this);
this.send = this.send.bind(this);
if (!opts || opts.autoOpen !== false) {
this.open();
}
}
var _proto = UppySocket.prototype;
_proto.open = function open() {
var _this = this;
this.socket = new WebSocket(this.opts.target);
this.socket.onopen = function (e) {
_this.isOpen = true;
while (_this._queued.length > 0 && _this.isOpen) {
var first = _this._queued[0];
_this.send(first.action, first.payload);
_this._queued = _this._queued.slice(1);
}
};
this.socket.onclose = function (e) {
_this.isOpen = false;
};
this.socket.onmessage = this._handleMessage;
};
_proto.close = function close() {
if (this.socket) {
this.socket.close();
}
};
_proto.send = function send(action, payload) {
// attach uuid
if (!this.isOpen) {
this._queued.push({
action: action,
payload: payload
});
return;
}
this.socket.send(JSON.stringify({
action: action,
payload: payload
}));
};
_proto.on = function on(action, handler) {
this.emitter.on(action, handler);
};
_proto.emit = function emit(action, payload) {
this.emitter.emit(action, payload);
};
_proto.once = function once(action, handler) {
this.emitter.once(action, handler);
};
_proto._handleMessage = function _handleMessage(e) {
try {
var message = JSON.parse(e.data);
this.emit(message.action, message.payload);
} catch (err) {
console.log(err);
}
};
return UppySocket;
}();
},{"namespace-emitter":38}],75:[function(require,module,exports){
'use strict';
/**
* Manages communications with Companion
*/
var RequestClient = require('./RequestClient');
var Provider = require('./Provider');
var SearchProvider = require('./SearchProvider');
var Socket = require('./Socket');
module.exports = {
RequestClient: RequestClient,
Provider: Provider,
SearchProvider: SearchProvider,
Socket: Socket
};
},{"./Provider":71,"./RequestClient":72,"./SearchProvider":73,"./Socket":74}],76:[function(require,module,exports){
'use strict';
/**
* This module serves as an Async wrapper for LocalStorage
*/
module.exports.setItem = function (key, value) {
return new Promise(function (resolve) {
localStorage.setItem(key, value);
resolve();
});
};
module.exports.getItem = function (key) {
return Promise.resolve(localStorage.getItem(key));
};
module.exports.removeItem = function (key) {
return new Promise(function (resolve) {
localStorage.removeItem(key);
resolve();
});
};
},{}],77:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var preact = require('preact');
var findDOMElement = require('@uppy/utils/lib/findDOMElement');
/**
* Defer a frequent call to the microtask queue.
*/
function debounce(fn) {
var calling = null;
var latestArgs = null;
return function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
latestArgs = args;
if (!calling) {
calling = Promise.resolve().then(function () {
calling = null; // At this point `args` may be different from the most
// recent state, if multiple calls happened since this task
// was queued. So we use the `latestArgs`, which definitely
// is the most recent call.
return fn.apply(void 0, latestArgs);
});
}
return calling;
};
}
/**
* Boilerplate that all Plugins share - and should not be used
* directly. It also shows which methods final plugins should implement/override,
* this deciding on structure.
*
* @param {object} main Uppy core object
* @param {object} object with plugin options
* @returns {Array|string} files or success/fail message
*/
module.exports = /*#__PURE__*/function () {
function Plugin(uppy, opts) {
this.uppy = uppy;
this.opts = opts || {};
this.update = this.update.bind(this);
this.mount = this.mount.bind(this);
this.install = this.install.bind(this);
this.uninstall = this.uninstall.bind(this);
}
var _proto = Plugin.prototype;
_proto.getPluginState = function getPluginState() {
var _this$uppy$getState = this.uppy.getState(),
plugins = _this$uppy$getState.plugins;
return plugins[this.id] || {};
};
_proto.setPluginState = function setPluginState(update) {
var _extends2;
var _this$uppy$getState2 = this.uppy.getState(),
plugins = _this$uppy$getState2.plugins;
this.uppy.setState({
plugins: _extends({}, plugins, (_extends2 = {}, _extends2[this.id] = _extends({}, plugins[this.id], update), _extends2))
});
};
_proto.setOptions = function setOptions(newOpts) {
this.opts = _extends({}, this.opts, newOpts);
this.setPluginState(); // so that UI re-renders with new options
};
_proto.update = function update(state) {
if (typeof this.el === 'undefined') {
return;
}
if (this._updateUI) {
this._updateUI(state);
}
} // Called after every state update, after everything's mounted. Debounced.
;
_proto.afterUpdate = function afterUpdate() {}
/**
* Called when plugin is mounted, whether in DOM or into another plugin.
* Needed because sometimes plugins are mounted separately/after `install`,
* so this.el and this.parent might not be available in `install`.
* This is the case with @uppy/react plugins, for example.
*/
;
_proto.onMount = function onMount() {}
/**
* Check if supplied `target` is a DOM element or an `object`.
* If it’s an object — target is a plugin, and we search `plugins`
* for a plugin with same name and return its target.
*
* @param {string|object} target
*
*/
;
_proto.mount = function mount(target, plugin) {
var _this = this;
var callerPluginName = plugin.id;
var targetElement = findDOMElement(target);
if (targetElement) {
this.isTargetDOMEl = true; // API for plugins that require a synchronous rerender.
this.rerender = function (state) {
// plugin could be removed, but this.rerender is debounced below,
// so it could still be called even after uppy.removePlugin or uppy.close
// hence the check
if (!_this.uppy.getPlugin(_this.id)) return;
_this.el = preact.render(_this.render(state), targetElement, _this.el);
_this.afterUpdate();
};
this._updateUI = debounce(this.rerender);
this.uppy.log("Installing " + callerPluginName + " to a DOM element '" + target + "'"); // clear everything inside the target container
if (this.opts.replaceTargetContent) {
targetElement.innerHTML = '';
}
this.el = preact.render(this.render(this.uppy.getState()), targetElement);
this.onMount();
return this.el;
}
var targetPlugin;
if (typeof target === 'object' && target instanceof Plugin) {
// Targeting a plugin *instance*
targetPlugin = target;
} else if (typeof target === 'function') {
// Targeting a plugin type
var Target = target; // Find the target plugin instance.
this.uppy.iteratePlugins(function (plugin) {
if (plugin instanceof Target) {
targetPlugin = plugin;
return false;
}
});
}
if (targetPlugin) {
this.uppy.log("Installing " + callerPluginName + " to " + targetPlugin.id);
this.parent = targetPlugin;
this.el = targetPlugin.addTarget(plugin);
this.onMount();
return this.el;
}
this.uppy.log("Not installing " + callerPluginName);
var message = "Invalid target option given to " + callerPluginName + ".";
if (typeof target === 'function') {
message += ' The given target is not a Plugin class. ' + 'Please check that you\'re not specifying a React Component instead of a plugin. ' + 'If you are using @uppy/* packages directly, make sure you have only 1 version of @uppy/core installed: ' + 'run `npm ls @uppy/core` on the command line and verify that all the versions match and are deduped correctly.';
} else {
message += 'If you meant to target an HTML element, please make sure that the element exists. ' + 'Check that the <script> tag initializing Uppy is right before the closing </body> tag at the end of the page. ' + '(see https://github.com/transloadit/uppy/issues/1042)\n\n' + 'If you meant to target a plugin, please confirm that your `import` statements or `require` calls are correct.';
}
throw new Error(message);
};
_proto.render = function render(state) {
throw new Error('Extend the render method to add your plugin to a DOM element');
};
_proto.addTarget = function addTarget(plugin) {
throw new Error('Extend the addTarget method to add your plugin to another plugin\'s target');
};
_proto.unmount = function unmount() {
if (this.isTargetDOMEl && this.el && this.el.parentNode) {
this.el.parentNode.removeChild(this.el);
}
};
_proto.install = function install() {};
_proto.uninstall = function uninstall() {
this.unmount();
};
return Plugin;
}();
},{"@uppy/utils/lib/findDOMElement":225,"preact":81}],78:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
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); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
/* global AggregateError */
var Translator = require('@uppy/utils/lib/Translator');
var ee = require('namespace-emitter');
var cuid = require('cuid');
var throttle = require('lodash.throttle');
var prettierBytes = require('@transloadit/prettier-bytes');
var match = require('mime-match');
var DefaultStore = require('@uppy/store-default');
var getFileType = require('@uppy/utils/lib/getFileType');
var getFileNameAndExtension = require('@uppy/utils/lib/getFileNameAndExtension');
var generateFileID = require('@uppy/utils/lib/generateFileID');
var findIndex = require('@uppy/utils/lib/findIndex');
var supportsUploadProgress = require('./supportsUploadProgress');
var _require = require('./loggers'),
justErrorsLogger = _require.justErrorsLogger,
debugLogger = _require.debugLogger;
var Plugin = require('./Plugin'); // Exported from here.
var RestrictionError = /*#__PURE__*/function (_Error) {
_inheritsLoose(RestrictionError, _Error);
function RestrictionError() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _Error.call.apply(_Error, [this].concat(args)) || this;
_this.isRestriction = true;
return _this;
}
return RestrictionError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
if (typeof AggregateError === 'undefined') {
// eslint-disable-next-line no-global-assign
AggregateError = /*#__PURE__*/function (_Error2) {
_inheritsLoose(AggregateError, _Error2);
function AggregateError(message, errors) {
var _this2;
_this2 = _Error2.call(this, message) || this;
_this2.errors = errors;
return _this2;
}
return AggregateError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
}
var AggregateRestrictionError = /*#__PURE__*/function (_AggregateError) {
_inheritsLoose(AggregateRestrictionError, _AggregateError);
function AggregateRestrictionError() {
var _this3;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
_this3 = _AggregateError.call.apply(_AggregateError, [this].concat(args)) || this;
_this3.isRestriction = true;
return _this3;
}
return AggregateRestrictionError;
}(AggregateError);
/**
* Uppy Core module.
* Manages plugins, state updates, acts as an event bus,
* adds/removes files and metadata.
*/
var Uppy = /*#__PURE__*/function () {
// eslint-disable-next-line global-require
/**
* Instantiate Uppy
*
* @param {object} opts — Uppy options
*/
function Uppy(opts) {
var _this4 = this;
this.defaultLocale = {
strings: {
addBulkFilesFailed: {
0: 'Failed to add %{smart_count} file due to an internal error',
1: 'Failed to add %{smart_count} files due to internal errors'
},
youCanOnlyUploadX: {
0: 'You can only upload %{smart_count} file',
1: 'You can only upload %{smart_count} files'
},
youHaveToAtLeastSelectX: {
0: 'You have to select at least %{smart_count} file',
1: 'You have to select at least %{smart_count} files'
},
missingRequiredMetaField: 'Missing required meta fields',
missingRequiredMetaFieldOnFile: 'Missing required meta fields in %{fileName}',
// The default `exceedsSize2` string only combines the `exceedsSize` string (%{backwardsCompat}) with the size.
// Locales can override `exceedsSize2` to specify a different word order. This is for backwards compat with
// Uppy 1.9.x and below which did a naive concatenation of `exceedsSize2 + size` instead of using a locale-specific
// substitution.
// TODO: In 2.0 `exceedsSize2` should be removed in and `exceedsSize` updated to use substitution.
exceedsSize2: '%{backwardsCompat} %{size}',
exceedsSize: '%{file} exceeds maximum allowed size of',
inferiorSize: 'This file is smaller than the allowed size of %{size}',
youCanOnlyUploadFileTypes: 'You can only upload: %{types}',
noNewAlreadyUploading: 'Cannot add new files: already uploading',
noDuplicates: 'Cannot add the duplicate file \'%{fileName}\', it already exists',
companionError: 'Connection with Companion failed',
companionUnauthorizeHint: 'To unauthorize to your %{provider} account, please go to %{url}',
failedToUpload: 'Failed to upload %{file}',
noInternetConnection: 'No Internet connection',
connectedToInternet: 'Connected to the Internet',
// Strings for remote providers
noFilesFound: 'You have no files or folders here',
selectX: {
0: 'Select %{smart_count}',
1: 'Select %{smart_count}'
},
selectAllFilesFromFolderNamed: 'Select all files from folder %{name}',
unselectAllFilesFromFolderNamed: 'Unselect all files from folder %{name}',
selectFileNamed: 'Select file %{name}',
unselectFileNamed: 'Unselect file %{name}',
openFolderNamed: 'Open folder %{name}',
cancel: 'Cancel',
logOut: 'Log out',
filter: 'Filter',
resetFilter: 'Reset filter',
loading: 'Loading...',
authenticateWithTitle: 'Please authenticate with %{pluginName} to select files',
authenticateWith: 'Connect to %{pluginName}',
searchImages: 'Search for images',
enterTextToSearch: 'Enter text to search for images',
backToSearch: 'Back to Search',
emptyFolderAdded: 'No files were added from empty folder',
folderAdded: {
0: 'Added %{smart_count} file from %{folder}',
1: 'Added %{smart_count} files from %{folder}'
}
}
};
var defaultOptions = {
id: 'uppy',
autoProceed: false,
allowMultipleUploads: true,
debug: false,
restrictions: {
maxFileSize: null,
minFileSize: null,
maxTotalFileSize: null,
maxNumberOfFiles: null,
minNumberOfFiles: null,
allowedFileTypes: null,
requiredMetaFields: []
},
meta: {},
onBeforeFileAdded: function onBeforeFileAdded(currentFile) {
return currentFile;
},
onBeforeUpload: function onBeforeUpload(files) {
return files;
},
store: DefaultStore(),
logger: justErrorsLogger,
infoTimeout: 5000
}; // Merge default options with the ones set by user,
// making sure to merge restrictions too
this.opts = _extends({}, defaultOptions, opts, {
restrictions: _extends({}, defaultOptions.restrictions, opts && opts.restrictions)
}); // Support debug: true for backwards-compatability, unless logger is set in opts
// opts instead of this.opts to avoid comparing objects — we set logger: justErrorsLogger in defaultOptions
if (opts && opts.logger && opts.debug) {
this.log('You are using a custom `logger`, but also set `debug: true`, which uses built-in logger to output logs to console. Ignoring `debug: true` and using your custom `logger`.', 'warning');
} else if (opts && opts.debug) {
this.opts.logger = debugLogger;
}
this.log("Using Core v" + this.constructor.VERSION);
if (this.opts.restrictions.allowedFileTypes && this.opts.restrictions.allowedFileTypes !== null && !Array.isArray(this.opts.restrictions.allowedFileTypes)) {
throw new TypeError('`restrictions.allowedFileTypes` must be an array');
}
this.i18nInit(); // Container for different types of plugins
this.plugins = {};
this.getState = this.getState.bind(this);
this.getPlugin = this.getPlugin.bind(this);
this.setFileMeta = this.setFileMeta.bind(this);
this.setFileState = this.setFileState.bind(this);
this.log = this.log.bind(this);
this.info = this.info.bind(this);
this.hideInfo = this.hideInfo.bind(this);
this.addFile = this.addFile.bind(this);
this.removeFile = this.removeFile.bind(this);
this.pauseResume = this.pauseResume.bind(this);
this.validateRestrictions = this.validateRestrictions.bind(this); // ___Why throttle at 500ms?
// - We must throttle at >250ms for superfocus in Dashboard to work well
// (because animation takes 0.25s, and we want to wait for all animations to be over before refocusing).
// [Practical Check]: if thottle is at 100ms, then if you are uploading a file,
// and click 'ADD MORE FILES', - focus won't activate in Firefox.
// - We must throttle at around >500ms to avoid performance lags.
// [Practical Check] Firefox, try to upload a big file for a prolonged period of time. Laptop will start to heat up.
this.calculateProgress = throttle(this.calculateProgress.bind(this), 500, {
leading: true,
trailing: true
});
this.updateOnlineStatus = this.updateOnlineStatus.bind(this);
this.resetProgress = this.resetProgress.bind(this);
this.pauseAll = this.pauseAll.bind(this);
this.resumeAll = this.resumeAll.bind(this);
this.retryAll = this.retryAll.bind(this);
this.cancelAll = this.cancelAll.bind(this);
this.retryUpload = this.retryUpload.bind(this);
this.upload = this.upload.bind(this);
this.emitter = ee();
this.on = this.on.bind(this);
this.off = this.off.bind(this);
this.once = this.emitter.once.bind(this.emitter);
this.emit = this.emitter.emit.bind(this.emitter);
this.preProcessors = [];
this.uploaders = [];
this.postProcessors = [];
this.store = this.opts.store;
this.setState({
plugins: {},
files: {},
currentUploads: {},
allowNewUpload: true,
capabilities: {
uploadProgress: supportsUploadProgress(),
individualCancellation: true,
resumableUploads: false
},
totalProgress: 0,
meta: _extends({}, this.opts.meta),
info: {
isHidden: true,
type: 'info',
message: ''
},
recoveredState: null
});
this.storeUnsubscribe = this.store.subscribe(function (prevState, nextState, patch) {
_this4.emit('state-update', prevState, nextState, patch);
_this4.updateAll(nextState);
}); // Exposing uppy object on window for debugging and testing
if (this.opts.debug && typeof window !== 'undefined') {
window[this.opts.id] = this;
}
this.addListeners(); // Re-enable if we’ll need some capabilities on boot, like isMobileDevice
// this._setCapabilities()
} // _setCapabilities = () => {
// const capabilities = {
// isMobileDevice: isMobileDevice()
// }
// this.setState({
// ...this.getState().capabilities,
// capabilities
// })
// }
var _proto = Uppy.prototype;
_proto.on = function on(event, callback) {
this.emitter.on(event, callback);
return this;
};
_proto.off = function off(event, callback) {
this.emitter.off(event, callback);
return this;
}
/**
* Iterate on all plugins and run `update` on them.
* Called each time state changes.
*
*/
;
_proto.updateAll = function updateAll(state) {
this.iteratePlugins(function (plugin) {
plugin.update(state);
});
}
/**
* Updates state with a patch
*
* @param {object} patch {foo: 'bar'}
*/
;
_proto.setState = function setState(patch) {
this.store.setState(patch);
}
/**
* Returns current state.
*
* @returns {object}
*/
;
_proto.getState = function getState() {
return this.store.getState();
}
/**
* Back compat for when uppy.state is used instead of uppy.getState().
* @deprecated
*/
;
/**
* Shorthand to set state for a specific file.
*/
_proto.setFileState = function setFileState(fileID, state) {
var _extends2;
if (!this.getState().files[fileID]) {
throw new Error("Can\u2019t set state for " + fileID + " (the file could have been removed)");
}
this.setState({
files: _extends({}, this.getState().files, (_extends2 = {}, _extends2[fileID] = _extends({}, this.getState().files[fileID], state), _extends2))
});
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.opts.locale]);
this.locale = this.translator.locale;
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
};
_proto.setOptions = function setOptions(newOpts) {
this.opts = _extends({}, this.opts, newOpts, {
restrictions: _extends({}, this.opts.restrictions, newOpts && newOpts.restrictions)
});
if (newOpts.meta) {
this.setMeta(newOpts.meta);
}
this.i18nInit();
if (newOpts.locale) {
this.iteratePlugins(function (plugin) {
plugin.setOptions();
});
} // Note: this is not the preact `setState`, it's an internal function that has the same name.
this.setState(); // so that UI re-renders with new options
};
_proto.resetProgress = function resetProgress() {
var defaultProgress = {
percentage: 0,
bytesUploaded: 0,
uploadComplete: false,
uploadStarted: null
};
var files = _extends({}, this.getState().files);
var updatedFiles = {};
Object.keys(files).forEach(function (fileID) {
var updatedFile = _extends({}, files[fileID]);
updatedFile.progress = _extends({}, updatedFile.progress, defaultProgress);
updatedFiles[fileID] = updatedFile;
});
this.setState({
files: updatedFiles,
totalProgress: 0
});
this.emit('reset-progress');
};
_proto.addPreProcessor = function addPreProcessor(fn) {
this.preProcessors.push(fn);
};
_proto.removePreProcessor = function removePreProcessor(fn) {
var i = this.preProcessors.indexOf(fn);
if (i !== -1) {
this.preProcessors.splice(i, 1);
}
};
_proto.addPostProcessor = function addPostProcessor(fn) {
this.postProcessors.push(fn);
};
_proto.removePostProcessor = function removePostProcessor(fn) {
var i = this.postProcessors.indexOf(fn);
if (i !== -1) {
this.postProcessors.splice(i, 1);
}
};
_proto.addUploader = function addUploader(fn) {
this.uploaders.push(fn);
};
_proto.removeUploader = function removeUploader(fn) {
var i = this.uploaders.indexOf(fn);
if (i !== -1) {
this.uploaders.splice(i, 1);
}
};
_proto.setMeta = function setMeta(data) {
var updatedMeta = _extends({}, this.getState().meta, data);
var updatedFiles = _extends({}, this.getState().files);
Object.keys(updatedFiles).forEach(function (fileID) {
updatedFiles[fileID] = _extends({}, updatedFiles[fileID], {
meta: _extends({}, updatedFiles[fileID].meta, data)
});
});
this.log('Adding metadata:');
this.log(data);
this.setState({
meta: updatedMeta,
files: updatedFiles
});
};
_proto.setFileMeta = function setFileMeta(fileID, data) {
var updatedFiles = _extends({}, this.getState().files);
if (!updatedFiles[fileID]) {
this.log('Was trying to set metadata for a file that has been removed: ', fileID);
return;
}
var newMeta = _extends({}, updatedFiles[fileID].meta, data);
updatedFiles[fileID] = _extends({}, updatedFiles[fileID], {
meta: newMeta
});
this.setState({
files: updatedFiles
});
}
/**
* Get a file object.
*
* @param {string} fileID The ID of the file object to return.
*/
;
_proto.getFile = function getFile(fileID) {
return this.getState().files[fileID];
}
/**
* Get all files in an array.
*/
;
_proto.getFiles = function getFiles() {
var _this$getState = this.getState(),
files = _this$getState.files;
return Object.keys(files).map(function (fileID) {
return files[fileID];
});
}
/**
* A public wrapper for _checkRestrictions — checks if a file passes a set of restrictions.
* For use in UI pluigins (like Providers), to disallow selecting files that won’t pass restrictions.
*
* @param {object} file object to check
* @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize
* @returns {object} { result: true/false, reason: why file didn’t pass restrictions }
*/
;
_proto.validateRestrictions = function validateRestrictions(file, files) {
try {
this.checkRestrictions(file, files);
return {
result: true
};
} catch (err) {
return {
result: false,
reason: err.message
};
}
}
/**
* Check if file passes a set of restrictions set in options: maxFileSize, minFileSize,
* maxNumberOfFiles and allowedFileTypes.
*
* @param {object} file object to check
* @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize
* @private
*/
;
_proto.checkRestrictions = function checkRestrictions(file, files) {
if (files === void 0) {
files = this.getFiles();
}
var _this$opts$restrictio = this.opts.restrictions,
maxFileSize = _this$opts$restrictio.maxFileSize,
minFileSize = _this$opts$restrictio.minFileSize,
maxTotalFileSize = _this$opts$restrictio.maxTotalFileSize,
maxNumberOfFiles = _this$opts$restrictio.maxNumberOfFiles,
allowedFileTypes = _this$opts$restrictio.allowedFileTypes;
if (maxNumberOfFiles) {
if (files.length + 1 > maxNumberOfFiles) {
throw new RestrictionError("" + this.i18n('youCanOnlyUploadX', {
smart_count: maxNumberOfFiles
}));
}
}
if (allowedFileTypes) {
var isCorrectFileType = allowedFileTypes.some(function (type) {
// check if this is a mime-type
if (type.indexOf('/') > -1) {
if (!file.type) return false;
return match(file.type.replace(/;.*?$/, ''), type);
} // otherwise this is likely an extension
if (type[0] === '.' && file.extension) {
return file.extension.toLowerCase() === type.substr(1).toLowerCase();
}
return false;
});
if (!isCorrectFileType) {
var allowedFileTypesString = allowedFileTypes.join(', ');
throw new RestrictionError(this.i18n('youCanOnlyUploadFileTypes', {
types: allowedFileTypesString
}));
}
} // We can't check maxTotalFileSize if the size is unknown.
if (maxTotalFileSize && file.size != null) {
var totalFilesSize = 0;
totalFilesSize += file.size;
files.forEach(function (f) {
totalFilesSize += f.size;
});
if (totalFilesSize > maxTotalFileSize) {
throw new RestrictionError(this.i18n('exceedsSize2', {
backwardsCompat: this.i18n('exceedsSize'),
size: prettierBytes(maxTotalFileSize),
file: file.name
}));
}
} // We can't check maxFileSize if the size is unknown.
if (maxFileSize && file.size != null) {
if (file.size > maxFileSize) {
throw new RestrictionError(this.i18n('exceedsSize2', {
backwardsCompat: this.i18n('exceedsSize'),
size: prettierBytes(maxFileSize),
file: file.name
}));
}
} // We can't check minFileSize if the size is unknown.
if (minFileSize && file.size != null) {
if (file.size < minFileSize) {
throw new RestrictionError(this.i18n('inferiorSize', {
size: prettierBytes(minFileSize)
}));
}
}
}
/**
* Check if minNumberOfFiles restriction is reached before uploading.
*
* @private
*/
;
_proto.checkMinNumberOfFiles = function checkMinNumberOfFiles(files) {
var minNumberOfFiles = this.opts.restrictions.minNumberOfFiles;
if (Object.keys(files).length < minNumberOfFiles) {
throw new RestrictionError("" + this.i18n('youHaveToAtLeastSelectX', {
smart_count: minNumberOfFiles
}));
}
}
/**
* Check if requiredMetaField restriction is met before uploading.
*
* @private
*/
;
_proto.checkRequiredMetaFields = function checkRequiredMetaFields(files) {
var requiredMetaFields = this.opts.restrictions.requiredMetaFields;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var errors = [];
var fileIDs = Object.keys(files);
for (var i = 0; i < fileIDs.length; i++) {
var file = this.getFile(fileIDs[i]);
for (var _i = 0; _i < requiredMetaFields.length; _i++) {
if (!hasOwnProperty.call(file.meta, requiredMetaFields[_i]) || file.meta[requiredMetaFields[_i]] === '') {
var err = new RestrictionError("" + this.i18n('missingRequiredMetaFieldOnFile', {
fileName: file.name
}));
errors.push(err);
this.showOrLogErrorAndThrow(err, {
file: file,
throwErr: false
});
}
}
}
if (errors.length) {
throw new AggregateRestrictionError("" + this.i18n('missingRequiredMetaField'), errors);
}
}
/**
* Logs an error, sets Informer message, then throws the error.
* Emits a 'restriction-failed' event if it’s a restriction error
*
* @param {object | string} err — Error object or plain string message
* @param {object} [options]
* @param {boolean} [options.showInformer=true] — Sometimes developer might want to show Informer manually
* @param {object} [options.file=null] — File object used to emit the restriction error
* @param {boolean} [options.throwErr=true] — Errors shouldn’t be thrown, for example, in `upload-error` event
* @private
*/
;
_proto.showOrLogErrorAndThrow = function showOrLogErrorAndThrow(err, _temp) {
var _ref = _temp === void 0 ? {} : _temp,
_ref$showInformer = _ref.showInformer,
showInformer = _ref$showInformer === void 0 ? true : _ref$showInformer,
_ref$file = _ref.file,
file = _ref$file === void 0 ? null : _ref$file,
_ref$throwErr = _ref.throwErr,
throwErr = _ref$throwErr === void 0 ? true : _ref$throwErr;
var message = typeof err === 'object' ? err.message : err;
var details = typeof err === 'object' && err.details ? err.details : ''; // Restriction errors should be logged, but not as errors,
// as they are expected and shown in the UI.
var logMessageWithDetails = message;
if (details) {
logMessageWithDetails += " " + details;
}
if (err.isRestriction) {
this.log(logMessageWithDetails);
this.emit('restriction-failed', file, err);
} else {
this.log(logMessageWithDetails, 'error');
} // Sometimes informer has to be shown manually by the developer,
// for example, in `onBeforeFileAdded`.
if (showInformer) {
this.info({
message: message,
details: details
}, 'error', this.opts.infoTimeout);
}
if (throwErr) {
throw typeof err === 'object' ? err : new Error(err);
}
};
_proto.assertNewUploadAllowed = function assertNewUploadAllowed(file) {
var _this$getState2 = this.getState(),
allowNewUpload = _this$getState2.allowNewUpload;
if (allowNewUpload === false) {
this.showOrLogErrorAndThrow(new RestrictionError(this.i18n('noNewAlreadyUploading')), {
file: file
});
}
}
/**
* Create a file state object based on user-provided `addFile()` options.
*
* Note this is extremely side-effectful and should only be done when a file state object will be added to state immediately afterward!
*
* The `files` value is passed in because it may be updated by the caller without updating the store.
*/
;
_proto.checkAndCreateFileStateObject = function checkAndCreateFileStateObject(files, f) {
var fileType = getFileType(f);
var file = f;
file.type = fileType;
var onBeforeFileAddedResult = this.opts.onBeforeFileAdded(file, files);
if (onBeforeFileAddedResult === false) {
// Don’t show UI info for this error, as it should be done by the developer
this.showOrLogErrorAndThrow(new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), {
showInformer: false,
file: file
});
}
if (typeof onBeforeFileAddedResult === 'object' && onBeforeFileAddedResult) {
file = onBeforeFileAddedResult;
}
var fileName;
if (file.name) {
fileName = file.name;
} else if (fileType.split('/')[0] === 'image') {
fileName = fileType.split('/')[0] + "." + fileType.split('/')[1];
} else {
fileName = 'noname';
}
var fileExtension = getFileNameAndExtension(fileName).extension;
var isRemote = file.isRemote || false;
var fileID = generateFileID(file);
if (files[fileID] && !files[fileID].isGhost) {
this.showOrLogErrorAndThrow(new RestrictionError(this.i18n('noDuplicates', {
fileName: fileName
})), {
file: file
});
}
var meta = file.meta || {};
meta.name = fileName;
meta.type = fileType; // `null` means the size is unknown.
var size = isFinite(file.data.size) ? file.data.size : null;
var newFile = {
source: file.source || '',
id: fileID,
name: fileName,
extension: fileExtension || '',
meta: _extends({}, this.getState().meta, meta),
type: fileType,
data: file.data,
progress: {
percentage: 0,
bytesUploaded: 0,
bytesTotal: size,
uploadComplete: false,
uploadStarted: null
},
size: size,
isRemote: isRemote,
remote: file.remote || '',
preview: file.preview
};
try {
var filesArray = Object.keys(files).map(function (i) {
return files[i];
});
this.checkRestrictions(newFile, filesArray);
} catch (err) {
this.showOrLogErrorAndThrow(err, {
file: newFile
});
}
return newFile;
} // Schedule an upload if `autoProceed` is enabled.
;
_proto.startIfAutoProceed = function startIfAutoProceed() {
var _this5 = this;
if (this.opts.autoProceed && !this.scheduledAutoProceed) {
this.scheduledAutoProceed = setTimeout(function () {
_this5.scheduledAutoProceed = null;
_this5.upload().catch(function (err) {
if (!err.isRestriction) {
_this5.log(err.stack || err.message || err);
}
});
}, 4);
}
}
/**
* Add a new file to `state.files`. This will run `onBeforeFileAdded`,
* try to guess file type in a clever way, check file against restrictions,
* and start an upload if `autoProceed === true`.
*
* @param {object} file object to add
* @returns {string} id for the added file
*/
;
_proto.addFile = function addFile(file) {
var _extends3;
this.assertNewUploadAllowed(file);
var _this$getState3 = this.getState(),
files = _this$getState3.files;
var newFile = this.checkAndCreateFileStateObject(files, file); // Users are asked to re-select recovered files without data,
// and to keep the progress, meta and everthing else, we only replace said data
if (files[newFile.id] && files[newFile.id].isGhost) {
newFile = _extends({}, files[newFile.id], {
data: file.data,
isGhost: false
});
this.log("Replaced the blob in the restored ghost file: " + newFile.name + ", " + newFile.id);
}
this.setState({
files: _extends({}, files, (_extends3 = {}, _extends3[newFile.id] = newFile, _extends3))
});
this.emit('file-added', newFile);
this.emit('files-added', [newFile]);
this.log("Added file: " + newFile.name + ", " + newFile.id + ", mime type: " + newFile.type);
this.startIfAutoProceed();
return newFile.id;
}
/**
* Add multiple files to `state.files`. See the `addFile()` documentation.
*
* If an error occurs while adding a file, it is logged and the user is notified.
* This is good for UI plugins, but not for programmatic use.
* Programmatic users should usually still use `addFile()` on individual files.
*/
;
_proto.addFiles = function addFiles(fileDescriptors) {
var _this6 = this;
this.assertNewUploadAllowed(); // create a copy of the files object only once
var files = _extends({}, this.getState().files);
var newFiles = [];
var errors = [];
for (var i = 0; i < fileDescriptors.length; i++) {
try {
var newFile = this.checkAndCreateFileStateObject(files, fileDescriptors[i]); // Users are asked to re-select recovered files without data,
// and to keep the progress, meta and everthing else, we only replace said data
if (files[newFile.id] && files[newFile.id].isGhost) {
newFile = _extends({}, files[newFile.id], {
data: fileDescriptors[i].data,
isGhost: false
});
this.log("Replaced blob in a ghost file: " + newFile.name + ", " + newFile.id);
}
files[newFile.id] = newFile;
newFiles.push(newFile);
} catch (err) {
if (!err.isRestriction) {
errors.push(err);
}
}
}
this.setState({
files: files
});
newFiles.forEach(function (newFile) {
_this6.emit('file-added', newFile);
});
this.emit('files-added', newFiles);
if (newFiles.length > 5) {
this.log("Added batch of " + newFiles.length + " files");
} else {
Object.keys(newFiles).forEach(function (fileID) {
_this6.log("Added file: " + newFiles[fileID].name + "\n id: " + newFiles[fileID].id + "\n type: " + newFiles[fileID].type);
});
}
if (newFiles.length > 0) {
this.startIfAutoProceed();
}
if (errors.length > 0) {
var message = 'Multiple errors occurred while adding files:\n';
errors.forEach(function (subError) {
message += "\n * " + subError.message;
});
this.info({
message: this.i18n('addBulkFilesFailed', {
smart_count: errors.length
}),
details: message
}, 'error', this.opts.infoTimeout);
if (typeof AggregateError === 'function') {
throw new AggregateError(errors, message);
} else {
var err = new Error(message);
err.errors = errors;
throw err;
}
}
};
_proto.removeFiles = function removeFiles(fileIDs, reason) {
var _this7 = this;
var _this$getState4 = this.getState(),
files = _this$getState4.files,
currentUploads = _this$getState4.currentUploads;
var updatedFiles = _extends({}, files);
var updatedUploads = _extends({}, currentUploads);
var removedFiles = Object.create(null);
fileIDs.forEach(function (fileID) {
if (files[fileID]) {
removedFiles[fileID] = files[fileID];
delete updatedFiles[fileID];
}
}); // Remove files from the `fileIDs` list in each upload.
function fileIsNotRemoved(uploadFileID) {
return removedFiles[uploadFileID] === undefined;
}
Object.keys(updatedUploads).forEach(function (uploadID) {
var newFileIDs = currentUploads[uploadID].fileIDs.filter(fileIsNotRemoved); // Remove the upload if no files are associated with it anymore.
if (newFileIDs.length === 0) {
delete updatedUploads[uploadID];
return;
}
updatedUploads[uploadID] = _extends({}, currentUploads[uploadID], {
fileIDs: newFileIDs
});
});
var stateUpdate = {
currentUploads: updatedUploads,
files: updatedFiles
}; // If all files were removed - allow new uploads,
// and clear recoveredState
if (Object.keys(updatedFiles).length === 0) {
stateUpdate.allowNewUpload = true;
stateUpdate.error = null;
stateUpdate.recoveredState = null;
}
this.setState(stateUpdate);
this.calculateTotalProgress();
var removedFileIDs = Object.keys(removedFiles);
removedFileIDs.forEach(function (fileID) {
_this7.emit('file-removed', removedFiles[fileID], reason);
});
if (removedFileIDs.length > 5) {
this.log("Removed " + removedFileIDs.length + " files");
} else {
this.log("Removed files: " + removedFileIDs.join(', '));
}
};
_proto.removeFile = function removeFile(fileID, reason) {
if (reason === void 0) {
reason = null;
}
this.removeFiles([fileID], reason);
};
_proto.pauseResume = function pauseResume(fileID) {
if (!this.getState().capabilities.resumableUploads || this.getFile(fileID).uploadComplete) {
return undefined;
}
var wasPaused = this.getFile(fileID).isPaused || false;
var isPaused = !wasPaused;
this.setFileState(fileID, {
isPaused: isPaused
});
this.emit('upload-pause', fileID, isPaused);
return isPaused;
};
_proto.pauseAll = function pauseAll() {
var updatedFiles = _extends({}, this.getState().files);
var inProgressUpdatedFiles = Object.keys(updatedFiles).filter(function (file) {
return !updatedFiles[file].progress.uploadComplete && updatedFiles[file].progress.uploadStarted;
});
inProgressUpdatedFiles.forEach(function (file) {
var updatedFile = _extends({}, updatedFiles[file], {
isPaused: true
});
updatedFiles[file] = updatedFile;
});
this.setState({
files: updatedFiles
});
this.emit('pause-all');
};
_proto.resumeAll = function resumeAll() {
var updatedFiles = _extends({}, this.getState().files);
var inProgressUpdatedFiles = Object.keys(updatedFiles).filter(function (file) {
return !updatedFiles[file].progress.uploadComplete && updatedFiles[file].progress.uploadStarted;
});
inProgressUpdatedFiles.forEach(function (file) {
var updatedFile = _extends({}, updatedFiles[file], {
isPaused: false,
error: null
});
updatedFiles[file] = updatedFile;
});
this.setState({
files: updatedFiles
});
this.emit('resume-all');
};
_proto.retryAll = function retryAll() {
var updatedFiles = _extends({}, this.getState().files);
var filesToRetry = Object.keys(updatedFiles).filter(function (file) {
return updatedFiles[file].error;
});
filesToRetry.forEach(function (file) {
var updatedFile = _extends({}, updatedFiles[file], {
isPaused: false,
error: null
});
updatedFiles[file] = updatedFile;
});
this.setState({
files: updatedFiles,
error: null
});
this.emit('retry-all', filesToRetry);
if (filesToRetry.length === 0) {
return Promise.resolve({
successful: [],
failed: []
});
}
var uploadID = this.createUpload(filesToRetry, {
forceAllowNewUpload: true // create new upload even if allowNewUpload: false
});
return this.runUpload(uploadID);
};
_proto.cancelAll = function cancelAll() {
this.emit('cancel-all');
var _this$getState5 = this.getState(),
files = _this$getState5.files;
var fileIDs = Object.keys(files);
if (fileIDs.length) {
this.removeFiles(fileIDs, 'cancel-all');
}
this.setState({
totalProgress: 0,
error: null,
recoveredState: null
});
};
_proto.retryUpload = function retryUpload(fileID) {
this.setFileState(fileID, {
error: null,
isPaused: false
});
this.emit('upload-retry', fileID);
var uploadID = this.createUpload([fileID], {
forceAllowNewUpload: true // create new upload even if allowNewUpload: false
});
return this.runUpload(uploadID);
};
_proto.reset = function reset() {
this.cancelAll();
};
_proto.logout = function logout() {
this.iteratePlugins(function (plugin) {
if (plugin.provider && plugin.provider.logout) {
plugin.provider.logout();
}
});
};
_proto.calculateProgress = function calculateProgress(file, data) {
if (!this.getFile(file.id)) {
this.log("Not setting progress for a file that has been removed: " + file.id);
return;
} // bytesTotal may be null or zero; in that case we can't divide by it
var canHavePercentage = isFinite(data.bytesTotal) && data.bytesTotal > 0;
this.setFileState(file.id, {
progress: _extends({}, this.getFile(file.id).progress, {
bytesUploaded: data.bytesUploaded,
bytesTotal: data.bytesTotal,
percentage: canHavePercentage // TODO(goto-bus-stop) flooring this should probably be the choice of the UI?
// we get more accurate calculations if we don't round this at all.
? Math.round(data.bytesUploaded / data.bytesTotal * 100) : 0
})
});
this.calculateTotalProgress();
};
_proto.calculateTotalProgress = function calculateTotalProgress() {
// calculate total progress, using the number of files currently uploading,
// multiplied by 100 and the summ of individual progress of each file
var files = this.getFiles();
var inProgress = files.filter(function (file) {
return file.progress.uploadStarted || file.progress.preprocess || file.progress.postprocess;
});
if (inProgress.length === 0) {
this.emit('progress', 0);
this.setState({
totalProgress: 0
});
return;
}
var sizedFiles = inProgress.filter(function (file) {
return file.progress.bytesTotal != null;
});
var unsizedFiles = inProgress.filter(function (file) {
return file.progress.bytesTotal == null;
});
if (sizedFiles.length === 0) {
var progressMax = inProgress.length * 100;
var currentProgress = unsizedFiles.reduce(function (acc, file) {
return acc + file.progress.percentage;
}, 0);
var _totalProgress = Math.round(currentProgress / progressMax * 100);
this.setState({
totalProgress: _totalProgress
});
return;
}
var totalSize = sizedFiles.reduce(function (acc, file) {
return acc + file.progress.bytesTotal;
}, 0);
var averageSize = totalSize / sizedFiles.length;
totalSize += averageSize * unsizedFiles.length;
var uploadedSize = 0;
sizedFiles.forEach(function (file) {
uploadedSize += file.progress.bytesUploaded;
});
unsizedFiles.forEach(function (file) {
uploadedSize += averageSize * (file.progress.percentage || 0) / 100;
});
var totalProgress = totalSize === 0 ? 0 : Math.round(uploadedSize / totalSize * 100); // hot fix, because:
// uploadedSize ended up larger than totalSize, resulting in 1325% total
if (totalProgress > 100) {
totalProgress = 100;
}
this.setState({
totalProgress: totalProgress
});
this.emit('progress', totalProgress);
}
/**
* Registers listeners for all global actions, like:
* `error`, `file-removed`, `upload-progress`
*/
;
_proto.addListeners = function addListeners() {
var _this8 = this;
/**
* @param {Error} error
* @param {object} [file]
* @param {object} [response]
*/
var errorHandler = function errorHandler(error, file, response) {
var errorMsg = error.message || 'Unknown error';
if (error.details) {
errorMsg += " " + error.details;
}
_this8.setState({
error: errorMsg
}); // When a file is also given, we store the error on the file object.
if (file != null && typeof file.id === 'string') {
_this8.setFileState(file.id, {
error: errorMsg,
response: response
});
}
};
this.on('error', errorHandler);
this.on('upload-error', function (file, error, response) {
errorHandler(error, file, response);
if (typeof error === 'object' && error.message) {
var newError = new Error(error.message);
newError.details = error.message;
if (error.details) {
newError.details += " " + error.details;
}
newError.message = _this8.i18n('failedToUpload', {
file: file.name
});
_this8.showOrLogErrorAndThrow(newError, {
throwErr: false
});
} else {
_this8.showOrLogErrorAndThrow(error, {
throwErr: false
});
}
});
this.on('upload', function () {
_this8.setState({
error: null
});
});
this.on('upload-started', function (file) {
if (!_this8.getFile(file.id)) {
_this8.log("Not setting progress for a file that has been removed: " + file.id);
return;
}
_this8.setFileState(file.id, {
progress: {
uploadStarted: Date.now(),
uploadComplete: false,
percentage: 0,
bytesUploaded: 0,
bytesTotal: file.size
}
});
});
this.on('upload-progress', this.calculateProgress);
this.on('upload-success', function (file, uploadResp) {
if (!_this8.getFile(file.id)) {
_this8.log("Not setting progress for a file that has been removed: " + file.id);
return;
}
var currentProgress = _this8.getFile(file.id).progress;
_this8.setFileState(file.id, {
progress: _extends({}, currentProgress, {
postprocess: _this8.postProcessors.length > 0 ? {
mode: 'indeterminate'
} : null,
uploadComplete: true,
percentage: 100,
bytesUploaded: currentProgress.bytesTotal
}),
response: uploadResp,
uploadURL: uploadResp.uploadURL,
isPaused: false
}); // Remote providers sometimes don't tell us the file size,
// but we can know how many bytes we uploaded once the upload is complete.
if (file.size == null) {
_this8.setFileState(file.id, {
size: uploadResp.bytesUploaded || currentProgress.bytesTotal
});
}
_this8.calculateTotalProgress();
});
this.on('preprocess-progress', function (file, progress) {
if (!_this8.getFile(file.id)) {
_this8.log("Not setting progress for a file that has been removed: " + file.id);
return;
}
_this8.setFileState(file.id, {
progress: _extends({}, _this8.getFile(file.id).progress, {
preprocess: progress
})
});
});
this.on('preprocess-complete', function (file) {
if (!_this8.getFile(file.id)) {
_this8.log("Not setting progress for a file that has been removed: " + file.id);
return;
}
var files = _extends({}, _this8.getState().files);
files[file.id] = _extends({}, files[file.id], {
progress: _extends({}, files[file.id].progress)
});
delete files[file.id].progress.preprocess;
_this8.setState({
files: files
});
});
this.on('postprocess-progress', function (file, progress) {
if (!_this8.getFile(file.id)) {
_this8.log("Not setting progress for a file that has been removed: " + file.id);
return;
}
_this8.setFileState(file.id, {
progress: _extends({}, _this8.getState().files[file.id].progress, {
postprocess: progress
})
});
});
this.on('postprocess-complete', function (file) {
if (!_this8.getFile(file.id)) {
_this8.log("Not setting progress for a file that has been removed: " + file.id);
return;
}
var files = _extends({}, _this8.getState().files);
files[file.id] = _extends({}, files[file.id], {
progress: _extends({}, files[file.id].progress)
});
delete files[file.id].progress.postprocess; // TODO should we set some kind of `fullyComplete` property on the file object
// so it's easier to see that the file is upload…fully complete…rather than
// what we have to do now (`uploadComplete && !postprocess`)
_this8.setState({
files: files
});
});
this.on('restored', function () {
// Files may have changed--ensure progress is still accurate.
_this8.calculateTotalProgress();
}); // show informer if offline
if (typeof window !== 'undefined' && window.addEventListener) {
window.addEventListener('online', function () {
return _this8.updateOnlineStatus();
});
window.addEventListener('offline', function () {
return _this8.updateOnlineStatus();
});
setTimeout(function () {
return _this8.updateOnlineStatus();
}, 3000);
}
};
_proto.updateOnlineStatus = function updateOnlineStatus() {
var online = typeof window.navigator.onLine !== 'undefined' ? window.navigator.onLine : true;
if (!online) {
this.emit('is-offline');
this.info(this.i18n('noInternetConnection'), 'error', 0);
this.wasOffline = true;
} else {
this.emit('is-online');
if (this.wasOffline) {
this.emit('back-online');
this.info(this.i18n('connectedToInternet'), 'success', 3000);
this.wasOffline = false;
}
}
};
_proto.getID = function getID() {
return this.opts.id;
}
/**
* Registers a plugin with Core.
*
* @param {object} Plugin object
* @param {object} [opts] object with options to be passed to Plugin
* @returns {object} self for chaining
*/
// eslint-disable-next-line no-shadow
;
_proto.use = function use(Plugin, opts) {
if (typeof Plugin !== 'function') {
var msg = "Expected a plugin class, but got " + (Plugin === null ? 'null' : typeof Plugin) + "." + ' Please verify that the plugin was imported and spelled correctly.';
throw new TypeError(msg);
} // Instantiate
var plugin = new Plugin(this, opts);
var pluginId = plugin.id;
this.plugins[plugin.type] = this.plugins[plugin.type] || [];
if (!pluginId) {
throw new Error('Your plugin must have an id');
}
if (!plugin.type) {
throw new Error('Your plugin must have a type');
}
var existsPluginAlready = this.getPlugin(pluginId);
if (existsPluginAlready) {
var _msg = "Already found a plugin named '" + existsPluginAlready.id + "'. " + ("Tried to use: '" + pluginId + "'.\n") + 'Uppy plugins must have unique `id` options. See https://uppy.io/docs/plugins/#id.';
throw new Error(_msg);
}
if (Plugin.VERSION) {
this.log("Using " + pluginId + " v" + Plugin.VERSION);
}
this.plugins[plugin.type].push(plugin);
plugin.install();
return this;
}
/**
* Find one Plugin by name.
*
* @param {string} id plugin id
* @returns {object|boolean}
*/
;
_proto.getPlugin = function getPlugin(id) {
var foundPlugin = null;
this.iteratePlugins(function (plugin) {
if (plugin.id === id) {
foundPlugin = plugin;
return false;
}
});
return foundPlugin;
}
/**
* Iterate through all `use`d plugins.
*
* @param {Function} method that will be run on each plugin
*/
;
_proto.iteratePlugins = function iteratePlugins(method) {
var _this9 = this;
Object.keys(this.plugins).forEach(function (pluginType) {
_this9.plugins[pluginType].forEach(method);
});
}
/**
* Uninstall and remove a plugin.
*
* @param {object} instance The plugin instance to remove.
*/
;
_proto.removePlugin = function removePlugin(instance) {
var _extends4;
this.log("Removing plugin " + instance.id);
this.emit('plugin-remove', instance);
if (instance.uninstall) {
instance.uninstall();
}
var list = this.plugins[instance.type].slice(); // list.indexOf failed here, because Vue3 converted the plugin instance
// to a Proxy object, which failed the strict comparison test:
// obj !== objProxy
var index = findIndex(list, function (item) {
return item.id === instance.id;
});
if (index !== -1) {
list.splice(index, 1);
this.plugins[instance.type] = list;
}
var state = this.getState();
var updatedState = {
plugins: _extends({}, state.plugins, (_extends4 = {}, _extends4[instance.id] = undefined, _extends4))
};
this.setState(updatedState);
}
/**
* Uninstall all plugins and close down this Uppy instance.
*/
;
_proto.close = function close() {
var _this10 = this;
this.log("Closing Uppy instance " + this.opts.id + ": removing all files and uninstalling plugins");
this.reset();
this.storeUnsubscribe();
this.iteratePlugins(function (plugin) {
_this10.removePlugin(plugin);
});
}
/**
* Set info message in `state.info`, so that UI plugins like `Informer`
* can display the message.
*
* @param {string | object} message Message to be displayed by the informer
* @param {string} [type]
* @param {number} [duration]
*/
;
_proto.info = function info(message, type, duration) {
if (type === void 0) {
type = 'info';
}
if (duration === void 0) {
duration = 3000;
}
var isComplexMessage = typeof message === 'object';
this.setState({
info: {
isHidden: false,
type: type,
message: isComplexMessage ? message.message : message,
details: isComplexMessage ? message.details : null
}
});
this.emit('info-visible');
clearTimeout(this.infoTimeoutID);
if (duration === 0) {
this.infoTimeoutID = undefined;
return;
} // hide the informer after `duration` milliseconds
this.infoTimeoutID = setTimeout(this.hideInfo, duration);
};
_proto.hideInfo = function hideInfo() {
var newInfo = _extends({}, this.getState().info, {
isHidden: true
});
this.setState({
info: newInfo
});
this.emit('info-hidden');
}
/**
* Passes messages to a function, provided in `opts.logger`.
* If `opts.logger: Uppy.debugLogger` or `opts.debug: true`, logs to the browser console.
*
* @param {string|object} message to log
* @param {string} [type] optional `error` or `warning`
*/
;
_proto.log = function log(message, type) {
var logger = this.opts.logger;
switch (type) {
case 'error':
logger.error(message);
break;
case 'warning':
logger.warn(message);
break;
default:
logger.debug(message);
break;
}
}
/**
* Obsolete, event listeners are now added in the constructor.
*/
;
_proto.run = function run() {
this.log('Calling run() is no longer necessary.', 'warning');
return this;
}
/**
* Restore an upload by its ID.
*/
;
_proto.restore = function restore(uploadID) {
this.log("Core: attempting to restore upload \"" + uploadID + "\"");
if (!this.getState().currentUploads[uploadID]) {
this.removeUpload(uploadID);
return Promise.reject(new Error('Nonexistent upload'));
}
return this.runUpload(uploadID);
}
/**
* Create an upload for a bunch of files.
*
* @param {Array<string>} fileIDs File IDs to include in this upload.
* @returns {string} ID of this upload.
*/
;
_proto.createUpload = function createUpload(fileIDs, opts) {
var _extends5;
if (opts === void 0) {
opts = {};
}
// uppy.retryAll sets this to true — when retrying we want to ignore `allowNewUpload: false`
var _opts = opts,
_opts$forceAllowNewUp = _opts.forceAllowNewUpload,
forceAllowNewUpload = _opts$forceAllowNewUp === void 0 ? false : _opts$forceAllowNewUp;
var _this$getState6 = this.getState(),
allowNewUpload = _this$getState6.allowNewUpload,
currentUploads = _this$getState6.currentUploads;
if (!allowNewUpload && !forceAllowNewUpload) {
throw new Error('Cannot create a new upload: already uploading.');
}
var uploadID = cuid();
this.emit('upload', {
id: uploadID,
fileIDs: fileIDs
});
this.setState({
allowNewUpload: this.opts.allowMultipleUploads !== false,
currentUploads: _extends({}, currentUploads, (_extends5 = {}, _extends5[uploadID] = {
fileIDs: fileIDs,
step: 0,
result: {}
}, _extends5))
});
return uploadID;
};
_proto.getUpload = function getUpload(uploadID) {
var _this$getState7 = this.getState(),
currentUploads = _this$getState7.currentUploads;
return currentUploads[uploadID];
}
/**
* Add data to an upload's result object.
*
* @param {string} uploadID The ID of the upload.
* @param {object} data Data properties to add to the result object.
*/
;
_proto.addResultData = function addResultData(uploadID, data) {
var _extends6;
if (!this.getUpload(uploadID)) {
this.log("Not setting result for an upload that has been removed: " + uploadID);
return;
}
var _this$getState8 = this.getState(),
currentUploads = _this$getState8.currentUploads;
var currentUpload = _extends({}, currentUploads[uploadID], {
result: _extends({}, currentUploads[uploadID].result, data)
});
this.setState({
currentUploads: _extends({}, currentUploads, (_extends6 = {}, _extends6[uploadID] = currentUpload, _extends6))
});
}
/**
* Remove an upload, eg. if it has been canceled or completed.
*
* @param {string} uploadID The ID of the upload.
*/
;
_proto.removeUpload = function removeUpload(uploadID) {
var currentUploads = _extends({}, this.getState().currentUploads);
delete currentUploads[uploadID];
this.setState({
currentUploads: currentUploads
});
}
/**
* Run an upload. This picks up where it left off in case the upload is being restored.
*
* @private
*/
;
_proto.runUpload = function runUpload(uploadID) {
var _this11 = this;
var uploadData = this.getState().currentUploads[uploadID];
var restoreStep = uploadData.step;
var steps = [].concat(this.preProcessors, this.uploaders, this.postProcessors);
var lastStep = Promise.resolve();
steps.forEach(function (fn, step) {
// Skip this step if we are restoring and have already completed this step before.
if (step < restoreStep) {
return;
}
lastStep = lastStep.then(function () {
var _extends7;
var _this11$getState = _this11.getState(),
currentUploads = _this11$getState.currentUploads;
var currentUpload = currentUploads[uploadID];
if (!currentUpload) {
return;
}
var updatedUpload = _extends({}, currentUpload, {
step: step
});
_this11.setState({
currentUploads: _extends({}, currentUploads, (_extends7 = {}, _extends7[uploadID] = updatedUpload, _extends7))
}); // TODO give this the `updatedUpload` object as its only parameter maybe?
// Otherwise when more metadata may be added to the upload this would keep getting more parameters
// eslint-disable-next-line consistent-return
return fn(updatedUpload.fileIDs, uploadID);
}).then(function () {
return null;
});
}); // Not returning the `catch`ed promise, because we still want to return a rejected
// promise from this method if the upload failed.
lastStep.catch(function (err) {
_this11.emit('error', err);
_this11.removeUpload(uploadID);
});
return lastStep.then(function () {
// Set result data.
var _this11$getState2 = _this11.getState(),
currentUploads = _this11$getState2.currentUploads;
var currentUpload = currentUploads[uploadID];
if (!currentUpload) {
return;
} // Mark postprocessing step as complete if necessary; this addresses a case where we might get
// stuck in the postprocessing UI while the upload is fully complete.
// If the postprocessing steps do not do any work, they may not emit postprocessing events at
// all, and never mark the postprocessing as complete. This is fine on its own but we
// introduced code in the @uppy/core upload-success handler to prepare postprocessing progress
// state if any postprocessors are registered. That is to avoid a "flash of completed state"
// before the postprocessing plugins can emit events.
//
// So, just in case an upload with postprocessing plugins *has* completed *without* emitting
// postprocessing completion, we do it instead.
currentUpload.fileIDs.forEach(function (fileID) {
var file = _this11.getFile(fileID);
if (file && file.progress.postprocess) {
_this11.emit('postprocess-complete', file);
}
});
var files = currentUpload.fileIDs.map(function (fileID) {
return _this11.getFile(fileID);
});
var successful = files.filter(function (file) {
return !file.error;
});
var failed = files.filter(function (file) {
return file.error;
});
_this11.addResultData(uploadID, {
successful: successful,
failed: failed,
uploadID: uploadID
});
}).then(function () {
// Emit completion events.
// This is in a separate function so that the `currentUploads` variable
// always refers to the latest state. In the handler right above it refers
// to an outdated object without the `.result` property.
var _this11$getState3 = _this11.getState(),
currentUploads = _this11$getState3.currentUploads;
if (!currentUploads[uploadID]) {
return;
}
var currentUpload = currentUploads[uploadID];
var result = currentUpload.result;
_this11.emit('complete', result);
_this11.removeUpload(uploadID); // eslint-disable-next-line consistent-return
return result;
}).then(function (result) {
if (result == null) {
_this11.log("Not setting result for an upload that has been removed: " + uploadID);
}
return result;
});
}
/**
* Start an upload for all the files that are not currently being uploaded.
*
* @returns {Promise}
*/
;
_proto.upload = function upload() {
var _this12 = this;
if (!this.plugins.uploader) {
this.log('No uploader type plugins are used', 'warning');
}
var _this$getState9 = this.getState(),
files = _this$getState9.files;
var onBeforeUploadResult = this.opts.onBeforeUpload(files);
if (onBeforeUploadResult === false) {
return Promise.reject(new Error('Not starting the upload because onBeforeUpload returned false'));
}
if (onBeforeUploadResult && typeof onBeforeUploadResult === 'object') {
files = onBeforeUploadResult; // Updating files in state, because uploader plugins receive file IDs,
// and then fetch the actual file object from state
this.setState({
files: files
});
}
return Promise.resolve().then(function () {
_this12.checkMinNumberOfFiles(files);
_this12.checkRequiredMetaFields(files);
}).catch(function (err) {
_this12.showOrLogErrorAndThrow(err);
}).then(function () {
var _this12$getState = _this12.getState(),
currentUploads = _this12$getState.currentUploads; // get a list of files that are currently assigned to uploads
var currentlyUploadingFiles = Object.keys(currentUploads).reduce(function (prev, curr) {
return prev.concat(currentUploads[curr].fileIDs);
}, []);
var waitingFileIDs = [];
Object.keys(files).forEach(function (fileID) {
var file = _this12.getFile(fileID); // if the file hasn't started uploading and hasn't already been assigned to an upload..
if (!file.progress.uploadStarted && currentlyUploadingFiles.indexOf(fileID) === -1) {
waitingFileIDs.push(file.id);
}
});
var uploadID = _this12.createUpload(waitingFileIDs);
return _this12.runUpload(uploadID);
}).catch(function (err) {
_this12.showOrLogErrorAndThrow(err, {
showInformer: false
});
});
};
_createClass(Uppy, [{
key: "state",
get: function get() {
// Here, state is a non-enumerable property.
return this.getState();
}
}]);
return Uppy;
}();
Uppy.VERSION = "1.20.1";
module.exports = function core(opts) {
return new Uppy(opts);
}; // Expose class constructor.
module.exports.Uppy = Uppy;
module.exports.Plugin = Plugin;
module.exports.debugLogger = debugLogger;
},{"./Plugin":77,"./loggers":79,"./supportsUploadProgress":80,"@transloadit/prettier-bytes":1,"@uppy/store-default":170,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/findIndex":226,"@uppy/utils/lib/generateFileID":227,"@uppy/utils/lib/getFileNameAndExtension":234,"@uppy/utils/lib/getFileType":235,"cuid":15,"lodash.throttle":34,"mime-match":37,"namespace-emitter":38}],79:[function(require,module,exports){
var getTimeStamp = require('@uppy/utils/lib/getTimeStamp'); // Swallow all logs, except errors.
// default if logger is not set or debug: false
var justErrorsLogger = {
debug: function debug() {},
warn: function warn() {},
error: function error() {
var _console;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return (_console = console).error.apply(_console, ["[Uppy] [" + getTimeStamp() + "]"].concat(args));
}
}; // Print logs to console with namespace + timestamp,
// set by logger: Uppy.debugLogger or debug: true
var debugLogger = {
debug: function debug() {
// IE 10 doesn’t support console.debug
var debug = console.debug || console.log;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
debug.call.apply(debug, [console, "[Uppy] [" + getTimeStamp() + "]"].concat(args));
},
warn: function warn() {
var _console2;
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return (_console2 = console).warn.apply(_console2, ["[Uppy] [" + getTimeStamp() + "]"].concat(args));
},
error: function error() {
var _console3;
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return (_console3 = console).error.apply(_console3, ["[Uppy] [" + getTimeStamp() + "]"].concat(args));
}
};
module.exports = {
justErrorsLogger: justErrorsLogger,
debugLogger: debugLogger
};
},{"@uppy/utils/lib/getTimeStamp":240}],80:[function(require,module,exports){
// Edge 15.x does not fire 'progress' events on uploads.
// See https://github.com/transloadit/uppy/issues/945
// And https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12224510/
module.exports = function supportsUploadProgress(userAgent) {
// Allow passing in userAgent for tests
if (userAgent == null) {
userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : null;
} // Assume it works because basically everything supports progress events.
if (!userAgent) return true;
var m = /Edge\/(\d+\.\d+)/.exec(userAgent);
if (!m) return true;
var edgeVersion = m[1];
var _edgeVersion$split = edgeVersion.split('.'),
major = _edgeVersion$split[0],
minor = _edgeVersion$split[1];
major = parseInt(major, 10);
minor = parseInt(minor, 10); // Worked before:
// Edge 40.15063.0.0
// Microsoft EdgeHTML 15.15063
if (major < 15 || major === 15 && minor < 15063) {
return true;
} // Fixed in:
// Microsoft EdgeHTML 18.18218
if (major > 18 || major === 18 && minor >= 18218) {
return true;
} // other versions don't work.
return false;
};
},{}],81:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],82:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var AddFiles = /*#__PURE__*/function (_Component) {
_inheritsLoose(AddFiles, _Component);
function AddFiles() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _Component.call.apply(_Component, [this].concat(args)) || this;
_this.triggerFileInputClick = function () {
_this.fileInput.click();
};
_this.triggerFolderInputClick = function () {
_this.folderInput.click();
};
_this.onFileInputChange = function (event) {
_this.props.handleInputChange(event); // We clear the input after a file is selected, because otherwise
// change event is not fired in Chrome and Safari when a file
// with the same name is selected.
// ___Why not use value="" on <input/> instead?
// Because if we use that method of clearing the input,
// Chrome will not trigger change if we drop the same file twice (Issue #768).
event.target.value = null;
};
_this.renderHiddenInput = function (isFolder, refCallback) {
return h("input", {
className: "uppy-Dashboard-input",
hidden: true,
"aria-hidden": "true",
tabIndex: -1,
webkitdirectory: isFolder,
type: "file",
name: "files[]",
multiple: _this.props.maxNumberOfFiles !== 1,
onChange: _this.onFileInputChange,
accept: _this.props.allowedFileTypes,
ref: refCallback
});
};
_this.renderMyDeviceAcquirer = function () {
return h("div", {
className: "uppy-DashboardTab",
role: "presentation",
"data-uppy-acquirer-id": "MyDevice"
}, h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn",
role: "tab",
tabIndex: 0,
"data-uppy-super-focusable": true,
onClick: _this.triggerFileInputClick
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
width: "32",
height: "32",
rx: "16",
fill: "#2275D7"
}), h("path", {
d: "M21.973 21.152H9.863l-1.108-5.087h14.464l-1.246 5.087zM9.935 11.37h3.958l.886 1.444a.673.673 0 0 0 .585.316h6.506v1.37H9.935v-3.13zm14.898 3.44a.793.793 0 0 0-.616-.31h-.978v-2.126c0-.379-.275-.613-.653-.613H15.75l-.886-1.445a.673.673 0 0 0-.585-.316H9.232c-.378 0-.667.209-.667.587V14.5h-.782a.793.793 0 0 0-.61.303.795.795 0 0 0-.155.663l1.45 6.633c.078.36.396.618.764.618h13.354c.36 0 .674-.246.76-.595l1.631-6.636a.795.795 0 0 0-.144-.675z",
fill: "#FFF"
}))), h("div", {
className: "uppy-DashboardTab-name"
}, _this.props.i18n('myDevice'))));
};
_this.renderBrowseButton = function (text, onClickFn) {
var numberOfAcquirers = _this.props.acquirers.length;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-Dashboard-browse",
onClick: onClickFn,
"data-uppy-super-focusable": numberOfAcquirers === 0
}, text);
};
_this.renderDropPasteBrowseTagline = function () {
var numberOfAcquirers = _this.props.acquirers.length; // in order to keep the i18n CamelCase and options lower (as are defaults) we will want to transform a lower
// to Camel
var lowerFMSelectionType = _this.props.fileManagerSelectionType;
var camelFMSelectionType = lowerFMSelectionType.charAt(0).toUpperCase() + lowerFMSelectionType.slice(1); // For backwards compatibility, we need to support both 'browse' and 'browseFiles'/'browseFolders' as strings here.
var browseText = 'browse';
var browseFilesText = 'browse';
var browseFoldersText = 'browse';
if (lowerFMSelectionType === 'files') {
try {
browseText = _this.props.i18n('browse');
browseFilesText = _this.props.i18n('browse');
browseFoldersText = _this.props.i18n('browse');
} catch (_unused) {// Ignore, hopefully we can use the 'browseFiles' / 'browseFolders' strings
}
}
try {
browseFilesText = _this.props.i18n('browseFiles');
browseFoldersText = _this.props.i18n('browseFolders');
} catch (_unused2) {// Ignore, use the 'browse' string
}
var browse = _this.renderBrowseButton(browseText, _this.triggerFileInputClick);
var browseFiles = _this.renderBrowseButton(browseFilesText, _this.triggerFileInputClick);
var browseFolders = _this.renderBrowseButton(browseFoldersText, _this.triggerFolderInputClick); // Before the `fileManagerSelectionType` feature existed, we had two possible
// strings here, but now we have six. We use the new-style strings by default:
var titleText;
if (numberOfAcquirers > 0) {
titleText = _this.props.i18nArray("dropPasteImport" + camelFMSelectionType, {
browseFiles: browseFiles,
browseFolders: browseFolders,
browse: browse
});
} else {
titleText = _this.props.i18nArray("dropPaste" + camelFMSelectionType, {
browseFiles: browseFiles,
browseFolders: browseFolders,
browse: browse
});
} // We use the old-style strings if available: this implies that the user has
// manually specified them, so they should take precedence over the new-style
// defaults.
if (lowerFMSelectionType === 'files') {
try {
if (numberOfAcquirers > 0) {
titleText = _this.props.i18nArray('dropPasteImport', {
browse: browse
});
} else {
titleText = _this.props.i18nArray('dropPaste', {
browse: browse
});
}
} catch (_unused3) {// Ignore, the new-style strings will be used.
}
}
if (_this.props.disableLocalFiles) {
titleText = _this.props.i18n('importFiles');
}
return h("div", {
className: "uppy-Dashboard-AddFiles-title"
}, titleText);
};
_this.renderAcquirer = function (acquirer) {
return h("div", {
className: "uppy-DashboardTab",
role: "presentation",
"data-uppy-acquirer-id": acquirer.id
}, h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn",
role: "tab",
tabIndex: 0,
"aria-controls": "uppy-DashboardContent-panel--" + acquirer.id,
"aria-selected": _this.props.activePickerPanel.id === acquirer.id,
"data-uppy-super-focusable": true,
onClick: function onClick() {
return _this.props.showPanel(acquirer.id);
}
}, acquirer.icon(), h("div", {
className: "uppy-DashboardTab-name"
}, acquirer.name)));
};
_this.renderAcquirers = function (acquirers, disableLocalFiles) {
// Group last two buttons, so we don’t end up with
// just one button on a new line
var acquirersWithoutLastTwo = [].concat(acquirers);
var lastTwoAcquirers = acquirersWithoutLastTwo.splice(acquirers.length - 2, acquirers.length);
return h("div", {
className: "uppy-Dashboard-AddFiles-list",
role: "tablist"
}, !disableLocalFiles && _this.renderMyDeviceAcquirer(), acquirersWithoutLastTwo.map(function (acquirer) {
return _this.renderAcquirer(acquirer);
}), h("span", {
role: "presentation",
style: "white-space: nowrap;"
}, lastTwoAcquirers.map(function (acquirer) {
return _this.renderAcquirer(acquirer);
})));
};
return _this;
}
var _proto = AddFiles.prototype;
_proto.renderPoweredByUppy = function renderPoweredByUppy() {
var uppyBranding = h("span", null, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon uppy-Dashboard-poweredByIcon",
width: "11",
height: "11",
viewBox: "0 0 11 11"
}, h("path", {
d: "M7.365 10.5l-.01-4.045h2.612L5.5.806l-4.467 5.65h2.604l.01 4.044h3.718z",
fillRule: "evenodd"
})), h("span", {
className: "uppy-Dashboard-poweredByUppy"
}, "Uppy")); // Support both the old word-order-insensitive string `poweredBy` and the new word-order-sensitive string `poweredBy2`
var linkText = this.props.i18nArray('poweredBy2', {
backwardsCompat: this.props.i18n('poweredBy'),
uppy: uppyBranding
});
return h("a", {
tabIndex: "-1",
href: "https://uppy.io",
rel: "noreferrer noopener",
target: "_blank",
className: "uppy-Dashboard-poweredBy"
}, linkText);
};
_proto.render = function render() {
var _this2 = this;
return h("div", {
className: "uppy-Dashboard-AddFiles"
}, this.renderHiddenInput(false, function (ref) {
_this2.fileInput = ref;
}), this.renderHiddenInput(true, function (ref) {
_this2.folderInput = ref;
}), this.renderDropPasteBrowseTagline(), this.props.acquirers.length > 0 && this.renderAcquirers(this.props.acquirers, this.props.disableLocalFiles), h("div", {
className: "uppy-Dashboard-AddFiles-info"
}, this.props.note && h("div", {
className: "uppy-Dashboard-note"
}, this.props.note), this.props.proudlyDisplayPoweredByUppy && this.renderPoweredByUppy(this.props)));
};
return AddFiles;
}(Component);
module.exports = AddFiles;
},{"preact":105}],83:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var classNames = require('classnames');
var AddFiles = require('./AddFiles');
var AddFilesPanel = function AddFilesPanel(props) {
return h("div", {
className: classNames('uppy-Dashboard-AddFilesPanel', props.className),
"data-uppy-panelType": "AddFiles",
"aria-hidden": props.showAddFilesPanel
}, h("div", {
className: "uppy-DashboardContent-bar"
}, h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, props.i18n('addingMoreFiles')), h("button", {
className: "uppy-DashboardContent-back",
type: "button",
onClick: function onClick(ev) {
return props.toggleAddFilesPanel(false);
}
}, props.i18n('back'))), h(AddFiles, props));
};
module.exports = AddFilesPanel;
},{"./AddFiles":82,"classnames":11,"preact":105}],84:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('preact'),
h = _require.h;
var classNames = require('classnames');
var FileList = require('./FileList');
var AddFiles = require('./AddFiles');
var AddFilesPanel = require('./AddFilesPanel');
var PickerPanelContent = require('./PickerPanelContent');
var EditorPanel = require('./EditorPanel');
var PanelTopBar = require('./PickerPanelTopBar');
var FileCard = require('./FileCard');
var Slide = require('./Slide');
var isDragDropSupported = require('@uppy/utils/lib/isDragDropSupported'); // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog
// https://github.com/ghosh/micromodal
var WIDTH_XL = 900;
var WIDTH_LG = 700;
var WIDTH_MD = 576;
var HEIGHT_MD = 400;
module.exports = function Dashboard(props) {
var noFiles = props.totalFileCount === 0;
var isSizeMD = props.containerWidth > WIDTH_MD;
var wrapperClassName = classNames({
'uppy-Root': props.isTargetDOMEl
});
var dashboardClassName = classNames({
'uppy-Dashboard': true,
'uppy-Dashboard--isDisabled': props.disabled,
'uppy-Dashboard--animateOpenClose': props.animateOpenClose,
'uppy-Dashboard--isClosing': props.isClosing,
'uppy-Dashboard--isDraggingOver': props.isDraggingOver,
'uppy-Dashboard--modal': !props.inline,
'uppy-size--md': props.containerWidth > WIDTH_MD,
'uppy-size--lg': props.containerWidth > WIDTH_LG,
'uppy-size--xl': props.containerWidth > WIDTH_XL,
'uppy-size--height-md': props.containerHeight > HEIGHT_MD,
'uppy-Dashboard--isAddFilesPanelVisible': props.showAddFilesPanel,
'uppy-Dashboard--isInnerWrapVisible': props.areInsidesReadyToBeVisible
}); // Important: keep these in sync with the percent width values in `src/components/FileItem/index.scss`.
var itemsPerRow = 1; // mobile
if (props.containerWidth > WIDTH_XL) {
itemsPerRow = 5;
} else if (props.containerWidth > WIDTH_LG) {
itemsPerRow = 4;
} else if (props.containerWidth > WIDTH_MD) {
itemsPerRow = 3;
}
var showFileList = props.showSelectedFiles && !noFiles;
var numberOfFilesForRecovery = props.recoveredState ? Object.keys(props.recoveredState.files).length : null;
var numberOfGhosts = props.files ? Object.keys(props.files).filter(function (fileID) {
return props.files[fileID].isGhost;
}).length : null;
var renderRestoredText = function renderRestoredText() {
if (numberOfGhosts > 0) {
return props.i18n('recoveredXFiles', {
smart_count: numberOfGhosts
});
}
return props.i18n('recoveredAllFiles');
};
var dashboard = h("div", {
className: dashboardClassName,
"data-uppy-theme": props.theme,
"data-uppy-num-acquirers": props.acquirers.length,
"data-uppy-drag-drop-supported": !props.disableLocalFiles && isDragDropSupported(),
"aria-hidden": props.inline ? 'false' : props.isHidden,
"aria-disabled": props.disabled,
"aria-label": !props.inline ? props.i18n('dashboardWindowTitle') : props.i18n('dashboardTitle'),
onPaste: props.handlePaste,
onDragOver: props.handleDragOver,
onDragLeave: props.handleDragLeave,
onDrop: props.handleDrop
}, h("div", {
className: "uppy-Dashboard-overlay",
tabIndex: -1,
onClick: props.handleClickOutside
}), h("div", {
className: "uppy-Dashboard-inner",
"aria-modal": !props.inline && 'true',
role: !props.inline && 'dialog',
style: {
width: props.inline && props.width ? props.width : '',
height: props.inline && props.height ? props.height : ''
}
}, !props.inline ? h("button", {
className: "uppy-u-reset uppy-Dashboard-close",
type: "button",
"aria-label": props.i18n('closeModal'),
title: props.i18n('closeModal'),
onClick: props.closeModal
}, h("span", {
"aria-hidden": "true"
}, "\xD7")) : null, h("div", {
className: "uppy-Dashboard-innerWrap"
}, h("div", {
className: "uppy-Dashboard-dropFilesHereHint"
}, props.i18n('dropHint')), showFileList && h(PanelTopBar, props), numberOfFilesForRecovery && h("div", {
className: "uppy-Dashboard-serviceMsg"
}, h("svg", {
className: "uppy-Dashboard-serviceMsg-icon",
"aria-hidden": "true",
focusable: "false",
width: "21",
height: "16",
viewBox: "0 0 24 19"
}, h("g", {
transform: "translate(0 -1)",
fill: "none",
fillRule: "evenodd"
}, h("path", {
d: "M12.857 1.43l10.234 17.056A1 1 0 0122.234 20H1.766a1 1 0 01-.857-1.514L11.143 1.429a1 1 0 011.714 0z",
fill: "#FFD300"
}), h("path", {
fill: "#000",
d: "M11 6h2l-.3 8h-1.4z"
}), h("circle", {
fill: "#000",
cx: "12",
cy: "17",
r: "1"
}))), h("strong", {
className: "uppy-Dashboard-serviceMsg-title"
}, props.i18n('sessionRestored')), h("div", {
class: "uppy-Dashboard-serviceMsg-text"
}, renderRestoredText())), showFileList ? h(FileList, _extends({}, props, {
itemsPerRow: itemsPerRow
})) : h(AddFiles, _extends({}, props, {
isSizeMD: isSizeMD
})), h(Slide, null, props.showAddFilesPanel ? h(AddFilesPanel, _extends({
key: "AddFiles"
}, props, {
isSizeMD: isSizeMD
})) : null), h(Slide, null, props.fileCardFor ? h(FileCard, _extends({
key: "FileCard"
}, props)) : null), h(Slide, null, props.activePickerPanel ? h(PickerPanelContent, _extends({
key: "Picker"
}, props)) : null), h(Slide, null, props.showFileEditor ? h(EditorPanel, _extends({
key: "Editor"
}, props)) : null), h("div", {
className: "uppy-Dashboard-progressindicators"
}, props.progressindicators.map(function (target) {
return props.getPlugin(target.id).render(props.state);
})))));
return (// Wrap it for RTL language support
h("div", {
className: wrapperClassName,
dir: props.direction
}, dashboard)
);
};
},{"./AddFiles":82,"./AddFilesPanel":83,"./EditorPanel":85,"./FileCard":86,"./FileList":92,"./PickerPanelContent":94,"./PickerPanelTopBar":95,"./Slide":96,"@uppy/utils/lib/isDragDropSupported":243,"classnames":11,"preact":105}],85:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var classNames = require('classnames');
function EditorPanel(props) {
var file = this.props.files[this.props.fileCardFor];
return h("div", {
className: classNames('uppy-DashboardContent-panel', props.className),
role: "tabpanel",
"data-uppy-panelType": "FileEditor",
id: "uppy-DashboardContent-panel--editor"
}, h("div", {
className: "uppy-DashboardContent-bar"
}, h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, props.i18nArray('editing', {
file: h("span", {
className: "uppy-DashboardContent-titleFile"
}, file.meta ? file.meta.name : file.name)
})), h("button", {
className: "uppy-DashboardContent-back",
type: "button",
onClick: props.hideAllPanels
}, props.i18n('cancel')), h("button", {
className: "uppy-DashboardContent-save",
type: "button",
onClick: props.saveFileEditor
}, props.i18n('save'))), h("div", {
className: "uppy-DashboardContent-panelBody"
}, props.editors.map(function (target) {
return props.getPlugin(target.id).render(props.state);
})));
}
module.exports = EditorPanel;
},{"classnames":11,"preact":105}],86:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var classNames = require('classnames');
var getFileTypeIcon = require('../../utils/getFileTypeIcon');
var ignoreEvent = require('../../utils/ignoreEvent.js');
var FilePreview = require('../FilePreview');
var FileCard = /*#__PURE__*/function (_Component) {
_inheritsLoose(FileCard, _Component);
function FileCard(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.updateMeta = function (newVal, name) {
var _extends2;
_this.setState({
formState: _extends({}, _this.state.formState, (_extends2 = {}, _extends2[name] = newVal, _extends2))
});
};
_this.handleSave = function (e) {
e.preventDefault();
var fileID = _this.props.fileCardFor;
_this.props.saveFileCard(_this.state.formState, fileID);
};
_this.handleCancel = function () {
_this.props.toggleFileCard(false);
};
_this.saveOnEnter = function (ev) {
if (ev.keyCode === 13) {
ev.stopPropagation();
ev.preventDefault();
var file = _this.props.files[_this.props.fileCardFor];
_this.props.saveFileCard(_this.state.formState, file.id);
}
};
_this.renderMetaFields = function () {
var metaFields = _this.getMetaFields() || [];
var fieldCSSClasses = {
text: 'uppy-u-reset uppy-c-textInput uppy-Dashboard-FileCard-input'
};
return metaFields.map(function (field) {
var id = "uppy-Dashboard-FileCard-input-" + field.id;
var required = _this.props.requiredMetaFields.includes(field.id);
return h("fieldset", {
key: field.id,
className: "uppy-Dashboard-FileCard-fieldset"
}, h("label", {
className: "uppy-Dashboard-FileCard-label",
htmlFor: id
}, field.name), field.render !== undefined ? field.render({
value: _this.state.formState[field.id],
onChange: function onChange(newVal) {
return _this.updateMeta(newVal, field.id);
},
fieldCSSClasses: fieldCSSClasses,
required: required
}, h) : h("input", {
className: fieldCSSClasses.text,
id: id,
type: field.type || 'text',
required: required,
value: _this.state.formState[field.id],
placeholder: field.placeholder,
onKeyUp: _this.saveOnEnter,
onKeyDown: _this.saveOnEnter,
onKeyPress: _this.saveOnEnter,
onInput: function onInput(ev) {
return _this.updateMeta(ev.target.value, field.id);
},
"data-uppy-super-focusable": true
}));
});
};
var _file = _this.props.files[_this.props.fileCardFor];
var _metaFields = _this.getMetaFields() || [];
var storedMetaData = {};
_metaFields.forEach(function (field) {
storedMetaData[field.id] = _file.meta[field.id] || '';
});
_this.state = {
formState: storedMetaData
};
return _this;
}
var _proto = FileCard.prototype;
_proto.getMetaFields = function getMetaFields() {
return typeof this.props.metaFields === 'function' ? this.props.metaFields(this.props.files[this.props.fileCardFor]) : this.props.metaFields;
};
_proto.render = function render() {
var _this2 = this;
var file = this.props.files[this.props.fileCardFor];
var showEditButton = this.props.canEditFile(file);
return h("div", {
className: classNames('uppy-Dashboard-FileCard', this.props.className),
"data-uppy-panelType": "FileCard",
onDragOver: ignoreEvent,
onDragLeave: ignoreEvent,
onDrop: ignoreEvent,
onPaste: ignoreEvent
}, h("div", {
className: "uppy-DashboardContent-bar"
}, h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, this.props.i18nArray('editing', {
file: h("span", {
className: "uppy-DashboardContent-titleFile"
}, file.meta ? file.meta.name : file.name)
})), h("button", {
className: "uppy-DashboardContent-back",
type: "button",
title: this.props.i18n('finishEditingFile'),
onClick: this.handleCancel
}, this.props.i18n('cancel'))), h("div", {
className: "uppy-Dashboard-FileCard-inner"
}, h("div", {
className: "uppy-Dashboard-FileCard-preview",
style: {
backgroundColor: getFileTypeIcon(file.type).color
}
}, h(FilePreview, {
file: file
}), showEditButton && h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-Dashboard-FileCard-edit",
onClick: function onClick() {
return _this2.props.openFileEditor(file);
}
}, this.props.i18n('editFile'))), h("div", {
className: "uppy-Dashboard-FileCard-info"
}, this.renderMetaFields()), h("div", {
className: "uppy-Dashboard-FileCard-actions"
}, h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn" // If `form` attribute is not in Preact 8, we can’t trigger the form validation.
// We use a classic button with a onClick event handler.
,
type: "button",
onClick: this.handleSave
}, this.props.i18n('saveChanges')), h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn",
type: "button",
onClick: this.handleCancel
}, this.props.i18n('cancel')))));
};
return FileCard;
}(Component);
module.exports = FileCard;
},{"../../utils/getFileTypeIcon":102,"../../utils/ignoreEvent.js":103,"../FilePreview":93,"classnames":11,"preact":105}],87:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var copyToClipboard = require('../../../utils/copyToClipboard');
function EditButton(_ref) {
var file = _ref.file,
uploadInProgressOrComplete = _ref.uploadInProgressOrComplete,
metaFields = _ref.metaFields,
canEditFile = _ref.canEditFile,
i18n = _ref.i18n,
_onClick = _ref.onClick;
if (!uploadInProgressOrComplete && metaFields && metaFields.length > 0 || !uploadInProgressOrComplete && canEditFile(file)) {
return h("button", {
className: "uppy-u-reset uppy-Dashboard-Item-action uppy-Dashboard-Item-action--edit",
type: "button",
"aria-label": i18n('editFile') + " " + file.meta.name,
title: i18n('editFile'),
onClick: function onClick() {
return _onClick();
}
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "14",
height: "14",
viewBox: "0 0 14 14"
}, h("g", {
fillRule: "evenodd"
}, h("path", {
d: "M1.5 10.793h2.793A1 1 0 0 0 5 10.5L11.5 4a1 1 0 0 0 0-1.414L9.707.793a1 1 0 0 0-1.414 0l-6.5 6.5A1 1 0 0 0 1.5 8v2.793zm1-1V8L9 1.5l1.793 1.793-6.5 6.5H2.5z",
fillRule: "nonzero"
}), h("rect", {
x: "1",
y: "12.293",
width: "11",
height: "1",
rx: ".5"
}), h("path", {
fillRule: "nonzero",
d: "M6.793 2.5L9.5 5.207l.707-.707L7.5 1.793z"
}))));
}
return null;
}
function RemoveButton(_ref2) {
var i18n = _ref2.i18n,
_onClick2 = _ref2.onClick;
return h("button", {
className: "uppy-u-reset uppy-Dashboard-Item-action uppy-Dashboard-Item-action--remove",
type: "button",
"aria-label": i18n('removeFile'),
title: i18n('removeFile'),
onClick: function onClick() {
return _onClick2();
}
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "18",
height: "18",
viewBox: "0 0 18 18"
}, h("path", {
d: "M9 0C4.034 0 0 4.034 0 9s4.034 9 9 9 9-4.034 9-9-4.034-9-9-9z"
}), h("path", {
fill: "#FFF",
d: "M13 12.222l-.778.778L9 9.778 5.778 13 5 12.222 8.222 9 5 5.778 5.778 5 9 8.222 12.222 5l.778.778L9.778 9z"
})));
}
var copyLinkToClipboard = function copyLinkToClipboard(event, props) {
copyToClipboard(props.file.uploadURL, props.i18n('copyLinkToClipboardFallback')).then(function () {
props.log('Link copied to clipboard.');
props.info(props.i18n('copyLinkToClipboardSuccess'), 'info', 3000);
}).catch(props.log) // avoid losing focus
.then(function () {
return event.target.focus({
preventScroll: true
});
});
};
function CopyLinkButton(props) {
return h("button", {
className: "uppy-u-reset uppy-Dashboard-Item-action uppy-Dashboard-Item-action--copyLink",
type: "button",
"aria-label": props.i18n('copyLink'),
title: props.i18n('copyLink'),
onClick: function onClick(event) {
return copyLinkToClipboard(event, props);
}
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "14",
height: "14",
viewBox: "0 0 14 12"
}, h("path", {
d: "M7.94 7.703a2.613 2.613 0 0 1-.626 2.681l-.852.851a2.597 2.597 0 0 1-1.849.766A2.616 2.616 0 0 1 2.764 7.54l.852-.852a2.596 2.596 0 0 1 2.69-.625L5.267 7.099a1.44 1.44 0 0 0-.833.407l-.852.851a1.458 1.458 0 0 0 1.03 2.486c.39 0 .755-.152 1.03-.426l.852-.852c.231-.231.363-.522.406-.824l1.04-1.038zm4.295-5.937A2.596 2.596 0 0 0 10.387 1c-.698 0-1.355.272-1.849.766l-.852.851a2.614 2.614 0 0 0-.624 2.688l1.036-1.036c.041-.304.173-.6.407-.833l.852-.852c.275-.275.64-.426 1.03-.426a1.458 1.458 0 0 1 1.03 2.486l-.852.851a1.442 1.442 0 0 1-.824.406l-1.04 1.04a2.596 2.596 0 0 0 2.683-.628l.851-.85a2.616 2.616 0 0 0 0-3.697zm-6.88 6.883a.577.577 0 0 0 .82 0l3.474-3.474a.579.579 0 1 0-.819-.82L5.355 7.83a.579.579 0 0 0 0 .819z"
})));
}
module.exports = function Buttons(props) {
var file = props.file,
uploadInProgressOrComplete = props.uploadInProgressOrComplete,
canEditFile = props.canEditFile,
metaFields = props.metaFields,
showLinkToFileUploadResult = props.showLinkToFileUploadResult,
showRemoveButton = props.showRemoveButton,
i18n = props.i18n,
removeFile = props.removeFile,
toggleFileCard = props.toggleFileCard,
openFileEditor = props.openFileEditor,
log = props.log,
info = props.info;
var editAction = function editAction() {
if (metaFields && metaFields.length > 0) {
toggleFileCard(true, file.id);
} else {
openFileEditor(file);
}
};
return h("div", {
className: "uppy-Dashboard-Item-actionWrapper"
}, h(EditButton, {
i18n: i18n,
file: file,
uploadInProgressOrComplete: uploadInProgressOrComplete,
canEditFile: canEditFile,
metaFields: metaFields,
onClick: editAction
}), showLinkToFileUploadResult && file.uploadURL ? h(CopyLinkButton, {
file: file,
i18n: i18n,
info: info,
log: log
}) : null, showRemoveButton ? h(RemoveButton, {
i18n: i18n,
info: props.info,
log: props.log,
onClick: function onClick() {
return removeFile(file.id, 'removed-by-user');
}
}) : null);
};
},{"../../../utils/copyToClipboard":99,"preact":105}],88:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var prettierBytes = require('@transloadit/prettier-bytes');
var truncateString = require('@uppy/utils/lib/truncateString');
var renderAcquirerIcon = function renderAcquirerIcon(acquirer, props) {
return h("span", {
title: props.i18n('fileSource', {
name: acquirer.name
})
}, acquirer.icon());
};
var renderFileName = function renderFileName(props) {
// Take up at most 2 lines on any screen
var maxNameLength; // For very small mobile screens
if (props.containerWidth <= 352) {
maxNameLength = 35; // For regular mobile screens
} else if (props.containerWidth <= 576) {
maxNameLength = 60; // For desktops
} else {
maxNameLength = 30;
}
return h("div", {
className: "uppy-Dashboard-Item-name",
title: props.file.meta.name
}, truncateString(props.file.meta.name, maxNameLength));
};
var renderFileSize = function renderFileSize(props) {
return props.file.size && h("div", {
className: "uppy-Dashboard-Item-statusSize"
}, prettierBytes(props.file.size));
};
var ReSelectButton = function ReSelectButton(props) {
return props.file.isGhost && h("span", null, " \u2022 ", h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Dashboard-Item-reSelect",
type: "button",
onClick: props.toggleAddFilesPanel
}, props.i18n('reSelect')));
};
var ErrorButton = function ErrorButton(_ref) {
var file = _ref.file,
onClick = _ref.onClick;
if (file.error) {
return h("span", {
className: "uppy-Dashboard-Item-errorDetails",
"aria-label": file.error,
"data-microtip-position": "bottom",
"data-microtip-size": "medium",
role: "tooltip",
onClick: onClick
}, "?");
}
return null;
};
module.exports = function FileInfo(props) {
return h("div", {
className: "uppy-Dashboard-Item-fileInfo",
"data-uppy-file-source": props.file.source
}, renderFileName(props), h("div", {
className: "uppy-Dashboard-Item-status"
}, renderFileSize(props), ReSelectButton(props), h(ErrorButton, {
file: props.file,
onClick: function onClick() {
alert(props.file.error);
}
})));
};
},{"@transloadit/prettier-bytes":1,"@uppy/utils/lib/truncateString":253,"preact":105}],89:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var FilePreview = require('../../FilePreview');
var getFileTypeIcon = require('../../../utils/getFileTypeIcon');
module.exports = function FilePreviewAndLink(props) {
return h("div", {
className: "uppy-Dashboard-Item-previewInnerWrap",
style: {
backgroundColor: getFileTypeIcon(props.file.type).color
}
}, props.showLinkToFileUploadResult && props.file.uploadURL && h("a", {
className: "uppy-Dashboard-Item-previewLink",
href: props.file.uploadURL,
rel: "noreferrer noopener",
target: "_blank",
"aria-label": props.file.meta.name
}), h(FilePreview, {
file: props.file
}));
};
},{"../../../utils/getFileTypeIcon":102,"../../FilePreview":93,"preact":105}],90:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
function onPauseResumeCancelRetry(props) {
if (props.isUploaded) return;
if (props.error && !props.hideRetryButton) {
props.retryUpload(props.file.id);
return;
}
if (props.resumableUploads && !props.hidePauseResumeButton) {
props.pauseUpload(props.file.id);
} else if (props.individualCancellation && !props.hideCancelButton) {
props.cancelUpload(props.file.id);
}
}
function progressIndicatorTitle(props) {
if (props.isUploaded) {
return props.i18n('uploadComplete');
}
if (props.error) {
return props.i18n('retryUpload');
}
if (props.resumableUploads) {
if (props.file.isPaused) {
return props.i18n('resumeUpload');
}
return props.i18n('pauseUpload');
}
if (props.individualCancellation) {
return props.i18n('cancelUpload');
}
return '';
}
function ProgressIndicatorButton(props) {
return h("div", {
className: "uppy-Dashboard-Item-progress"
}, h("button", {
className: "uppy-u-reset uppy-Dashboard-Item-progressIndicator",
type: "button",
"aria-label": progressIndicatorTitle(props),
title: progressIndicatorTitle(props),
onClick: function onClick() {
return onPauseResumeCancelRetry(props);
}
}, props.children));
}
function ProgressCircleContainer(_ref) {
var children = _ref.children;
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "70",
height: "70",
viewBox: "0 0 36 36",
className: "uppy-c-icon uppy-Dashboard-Item-progressIcon--circle"
}, children);
}
function ProgressCircle(_ref2) {
var progress = _ref2.progress;
// circle length equals 2 * PI * R
var circleLength = 2 * Math.PI * 15;
return h("g", null, h("circle", {
className: "uppy-Dashboard-Item-progressIcon--bg",
r: "15",
cx: "18",
cy: "18",
"stroke-width": "2",
fill: "none"
}), h("circle", {
className: "uppy-Dashboard-Item-progressIcon--progress",
r: "15",
cx: "18",
cy: "18",
transform: "rotate(-90, 18, 18)",
fill: "none",
"stroke-width": "2",
"stroke-dasharray": circleLength,
"stroke-dashoffset": circleLength - circleLength / 100 * progress
}));
}
module.exports = function FileProgress(props) {
// Nothing if upload has not started
if (!props.file.progress.uploadStarted) {
return null;
} // Green checkmark when complete
if (props.isUploaded) {
return h("div", {
className: "uppy-Dashboard-Item-progress"
}, h("div", {
className: "uppy-Dashboard-Item-progressIndicator"
}, h(ProgressCircleContainer, null, h("circle", {
r: "15",
cx: "18",
cy: "18",
fill: "#1bb240"
}), h("polygon", {
className: "uppy-Dashboard-Item-progressIcon--check",
transform: "translate(2, 3)",
points: "14 22.5 7 15.2457065 8.99985857 13.1732815 14 18.3547104 22.9729883 9 25 11.1005634"
}))));
}
if (props.recoveredState) {
return;
} // Retry button for error
if (props.error && !props.hideRetryButton) {
return h(ProgressIndicatorButton, props, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon uppy-Dashboard-Item-progressIcon--retry",
width: "28",
height: "31",
viewBox: "0 0 16 19"
}, h("path", {
d: "M16 11a8 8 0 1 1-8-8v2a6 6 0 1 0 6 6h2z"
}), h("path", {
d: "M7.9 3H10v2H7.9z"
}), h("path", {
d: "M8.536.5l3.535 3.536-1.414 1.414L7.12 1.914z"
}), h("path", {
d: "M10.657 2.621l1.414 1.415L8.536 7.57 7.12 6.157z"
})));
} // Pause/resume button for resumable uploads
if (props.resumableUploads && !props.hidePauseResumeButton) {
return h(ProgressIndicatorButton, props, h(ProgressCircleContainer, null, h(ProgressCircle, {
progress: props.file.progress.percentage
}), props.file.isPaused ? h("polygon", {
className: "uppy-Dashboard-Item-progressIcon--play",
transform: "translate(3, 3)",
points: "12 20 12 10 20 15"
}) : h("g", {
className: "uppy-Dashboard-Item-progressIcon--pause",
transform: "translate(14.5, 13)"
}, h("rect", {
x: "0",
y: "0",
width: "2",
height: "10",
rx: "0"
}), h("rect", {
x: "5",
y: "0",
width: "2",
height: "10",
rx: "0"
}))));
} // Cancel button for non-resumable uploads if individualCancellation is supported (not bundled)
if (!props.resumableUploads && props.individualCancellation && !props.hideCancelButton) {
return h(ProgressIndicatorButton, props, h(ProgressCircleContainer, null, h(ProgressCircle, {
progress: props.file.progress.percentage
}), h("polygon", {
className: "cancel",
transform: "translate(2, 2)",
points: "19.8856516 11.0625 16 14.9481516 12.1019737 11.0625 11.0625 12.1143484 14.9481516 16 11.0625 19.8980263 12.1019737 20.9375 16 17.0518484 19.8856516 20.9375 20.9375 19.8980263 17.0518484 16 20.9375 12"
})));
} // Just progress when buttons are disabled
return h("div", {
className: "uppy-Dashboard-Item-progress"
}, h("div", {
className: "uppy-Dashboard-Item-progressIndicator"
}, h(ProgressCircleContainer, null, h(ProgressCircle, {
progress: props.file.progress.percentage
}))));
};
},{"preact":105}],91:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var classNames = require('classnames');
var shallowEqual = require('is-shallow-equal');
var FilePreviewAndLink = require('./FilePreviewAndLink');
var FileProgress = require('./FileProgress');
var FileInfo = require('./FileInfo');
var Buttons = require('./Buttons');
module.exports = /*#__PURE__*/function (_Component) {
_inheritsLoose(FileItem, _Component);
function FileItem() {
return _Component.apply(this, arguments) || this;
}
var _proto = FileItem.prototype;
_proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps) {
return !shallowEqual(this.props, nextProps);
};
_proto.componentDidMount = function componentDidMount() {
var file = this.props.file;
if (!file.preview) {
this.props.handleRequestThumbnail(file);
}
} // VirtualList mounts FileItems again and they emit `thumbnail:request`
// Otherwise thumbnails are broken or missing after Golden Retriever restores files
;
_proto.componentDidUpdate = function componentDidUpdate() {
var file = this.props.file;
if (!file.preview) {
this.props.handleRequestThumbnail(file);
}
};
_proto.componentWillUnmount = function componentWillUnmount() {
var file = this.props.file;
if (!file.preview) {
this.props.handleCancelThumbnail(file);
}
};
_proto.render = function render() {
var file = this.props.file;
var isProcessing = file.progress.preprocess || file.progress.postprocess;
var isUploaded = file.progress.uploadComplete && !isProcessing && !file.error;
var uploadInProgressOrComplete = file.progress.uploadStarted || isProcessing;
var uploadInProgress = file.progress.uploadStarted && !file.progress.uploadComplete || isProcessing;
var error = file.error || false; // File that Golden Retriever was able to partly restore (only meta, not blob),
// users still need to re-add it, so it’s a ghost
var isGhost = file.isGhost;
var showRemoveButton = this.props.individualCancellation ? !isUploaded : !uploadInProgress && !isUploaded;
if (isUploaded && this.props.showRemoveButtonAfterComplete) {
showRemoveButton = true;
}
var dashboardItemClass = classNames({
'uppy-Dashboard-Item': true,
'is-inprogress': uploadInProgress && !this.props.recoveredState,
'is-processing': isProcessing,
'is-complete': isUploaded,
'is-error': !!error,
'is-resumable': this.props.resumableUploads,
'is-noIndividualCancellation': !this.props.individualCancellation,
'is-ghost': isGhost
});
return h("div", {
className: dashboardItemClass,
id: "uppy_" + file.id,
role: this.props.role
}, h("div", {
className: "uppy-Dashboard-Item-preview"
}, h(FilePreviewAndLink, {
file: file,
showLinkToFileUploadResult: this.props.showLinkToFileUploadResult
}), h(FileProgress, {
file: file,
error: error,
isUploaded: isUploaded,
hideRetryButton: this.props.hideRetryButton,
hideCancelButton: this.props.hideCancelButton,
hidePauseResumeButton: this.props.hidePauseResumeButton,
recoveredState: this.props.recoveredState,
showRemoveButtonAfterComplete: this.props.showRemoveButtonAfterComplete,
resumableUploads: this.props.resumableUploads,
individualCancellation: this.props.individualCancellation,
pauseUpload: this.props.pauseUpload,
cancelUpload: this.props.cancelUpload,
retryUpload: this.props.retryUpload,
i18n: this.props.i18n
})), h("div", {
className: "uppy-Dashboard-Item-fileInfoAndButtons"
}, h(FileInfo, {
file: file,
id: this.props.id,
acquirers: this.props.acquirers,
containerWidth: this.props.containerWidth,
i18n: this.props.i18n,
toggleAddFilesPanel: this.props.toggleAddFilesPanel
}), h(Buttons, {
file: file,
metaFields: this.props.metaFields,
showLinkToFileUploadResult: this.props.showLinkToFileUploadResult,
showRemoveButton: showRemoveButton,
canEditFile: this.props.canEditFile,
uploadInProgressOrComplete: uploadInProgressOrComplete,
removeFile: this.props.removeFile,
toggleFileCard: this.props.toggleFileCard,
openFileEditor: this.props.openFileEditor,
i18n: this.props.i18n,
log: this.props.log,
info: this.props.info
})));
};
return FileItem;
}(Component);
},{"./Buttons":87,"./FileInfo":88,"./FilePreviewAndLink":89,"./FileProgress":90,"classnames":11,"is-shallow-equal":31,"preact":105}],92:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var FileItem = require('./FileItem/index.js');
var VirtualList = require('./VirtualList');
var classNames = require('classnames');
var _require = require('preact'),
h = _require.h;
function chunks(list, size) {
var chunked = [];
var currentChunk = [];
list.forEach(function (item, i) {
if (currentChunk.length < size) {
currentChunk.push(item);
} else {
chunked.push(currentChunk);
currentChunk = [item];
}
});
if (currentChunk.length) chunked.push(currentChunk);
return chunked;
}
module.exports = function (props) {
var noFiles = props.totalFileCount === 0;
var dashboardFilesClass = classNames('uppy-Dashboard-files', {
'uppy-Dashboard-files--noFiles': noFiles
}); // It's not great that this is hardcoded!
// It's ESPECIALLY not great that this is checking against `itemsPerRow`!
var rowHeight = props.itemsPerRow === 1 // Mobile
? 71 // 190px height + 2 * 5px margin
: 200;
var fileProps = {
// FIXME This is confusing, it's actually the Dashboard's plugin ID
id: props.id,
error: props.error,
// TODO move this to context
i18n: props.i18n,
log: props.log,
info: props.info,
// features
acquirers: props.acquirers,
resumableUploads: props.resumableUploads,
individualCancellation: props.individualCancellation,
// visual options
hideRetryButton: props.hideRetryButton,
hidePauseResumeButton: props.hidePauseResumeButton,
hideCancelButton: props.hideCancelButton,
showLinkToFileUploadResult: props.showLinkToFileUploadResult,
showRemoveButtonAfterComplete: props.showRemoveButtonAfterComplete,
isWide: props.isWide,
metaFields: props.metaFields,
recoveredState: props.recoveredState,
// callbacks
retryUpload: props.retryUpload,
pauseUpload: props.pauseUpload,
cancelUpload: props.cancelUpload,
toggleFileCard: props.toggleFileCard,
removeFile: props.removeFile,
handleRequestThumbnail: props.handleRequestThumbnail,
handleCancelThumbnail: props.handleCancelThumbnail
};
var sortByGhostComesFirst = function sortByGhostComesFirst(file1, file2) {
return props.files[file2].isGhost - props.files[file1].isGhost;
}; // Sort files by file.isGhost, ghost files first, only if recoveredState is present
var files = Object.keys(props.files);
if (props.recoveredState) files.sort(sortByGhostComesFirst);
var rows = chunks(files, props.itemsPerRow);
function renderRow(row) {
return (// The `role="presentation` attribute ensures that the list items are properly associated with the `VirtualList` element
// We use the first file ID as the key—this should not change across scroll rerenders
h("div", {
role: "presentation",
key: row[0]
}, row.map(function (fileID) {
return h(FileItem, _extends({
key: fileID
}, fileProps, {
role: "listitem",
openFileEditor: props.openFileEditor,
canEditFile: props.canEditFile,
toggleAddFilesPanel: props.toggleAddFilesPanel,
file: props.files[fileID]
}));
}))
);
}
return h(VirtualList, {
class: dashboardFilesClass,
role: "list",
data: rows,
renderRow: renderRow,
rowHeight: rowHeight
});
};
},{"./FileItem/index.js":91,"./VirtualList":97,"classnames":11,"preact":105}],93:[function(require,module,exports){
var getFileTypeIcon = require('../utils/getFileTypeIcon');
var _require = require('preact'),
h = _require.h;
module.exports = function FilePreview(props) {
var file = props.file;
if (file.preview) {
return h("img", {
className: "uppy-Dashboard-Item-previewImg",
alt: file.name,
src: file.preview
});
}
var _getFileTypeIcon = getFileTypeIcon(file.type),
color = _getFileTypeIcon.color,
icon = _getFileTypeIcon.icon;
return h("div", {
className: "uppy-Dashboard-Item-previewIconWrap"
}, h("span", {
className: "uppy-Dashboard-Item-previewIcon",
style: {
color: color
}
}, icon), h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-Dashboard-Item-previewIconBg",
width: "58",
height: "76",
viewBox: "0 0 58 76"
}, h("rect", {
fill: "#FFF",
width: "58",
height: "76",
rx: "3",
fillRule: "evenodd"
})));
};
},{"../utils/getFileTypeIcon":102,"preact":105}],94:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var classNames = require('classnames');
var ignoreEvent = require('../utils/ignoreEvent.js');
function PickerPanelContent(props) {
return h("div", {
className: classNames('uppy-DashboardContent-panel', props.className),
role: "tabpanel",
"data-uppy-panelType": "PickerPanel",
id: "uppy-DashboardContent-panel--" + props.activePickerPanel.id,
onDragOver: ignoreEvent,
onDragLeave: ignoreEvent,
onDrop: ignoreEvent,
onPaste: ignoreEvent
}, h("div", {
className: "uppy-DashboardContent-bar"
}, h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, props.i18n('importFrom', {
name: props.activePickerPanel.name
})), h("button", {
className: "uppy-DashboardContent-back",
type: "button",
onClick: props.hideAllPanels
}, props.i18n('cancel'))), h("div", {
className: "uppy-DashboardContent-panelBody"
}, props.getPlugin(props.activePickerPanel.id).render(props.state)));
}
module.exports = PickerPanelContent;
},{"../utils/ignoreEvent.js":103,"classnames":11,"preact":105}],95:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var uploadStates = {
STATE_ERROR: 'error',
STATE_WAITING: 'waiting',
STATE_PREPROCESSING: 'preprocessing',
STATE_UPLOADING: 'uploading',
STATE_POSTPROCESSING: 'postprocessing',
STATE_COMPLETE: 'complete',
STATE_PAUSED: 'paused'
};
function getUploadingState(isAllErrored, isAllComplete, isAllPaused, files) {
if (files === void 0) {
files = {};
}
if (isAllErrored) {
return uploadStates.STATE_ERROR;
}
if (isAllComplete) {
return uploadStates.STATE_COMPLETE;
}
if (isAllPaused) {
return uploadStates.STATE_PAUSED;
}
var state = uploadStates.STATE_WAITING;
var fileIDs = Object.keys(files);
for (var i = 0; i < fileIDs.length; i++) {
var progress = files[fileIDs[i]].progress; // If ANY files are being uploaded right now, show the uploading state.
if (progress.uploadStarted && !progress.uploadComplete) {
return uploadStates.STATE_UPLOADING;
} // If files are being preprocessed AND postprocessed at this time, we show the
// preprocess state. If any files are being uploaded we show uploading.
if (progress.preprocess && state !== uploadStates.STATE_UPLOADING) {
state = uploadStates.STATE_PREPROCESSING;
} // If NO files are being preprocessed or uploaded right now, but some files are
// being postprocessed, show the postprocess state.
if (progress.postprocess && state !== uploadStates.STATE_UPLOADING && state !== uploadStates.STATE_PREPROCESSING) {
state = uploadStates.STATE_POSTPROCESSING;
}
}
return state;
}
function UploadStatus(props) {
var uploadingState = getUploadingState(props.isAllErrored, props.isAllComplete, props.isAllPaused, props.files);
switch (uploadingState) {
case 'uploading':
return props.i18n('uploadingXFiles', {
smart_count: props.inProgressNotPausedFiles.length
});
case 'preprocessing':
case 'postprocessing':
return props.i18n('processingXFiles', {
smart_count: props.processingFiles.length
});
case 'paused':
return props.i18n('uploadPaused');
case 'waiting':
return props.i18n('xFilesSelected', {
smart_count: props.newFiles.length
});
case 'complete':
return props.i18n('uploadComplete');
}
}
function PanelTopBar(props) {
var allowNewUpload = props.allowNewUpload; // TODO maybe this should be done in ../index.js, then just pass that down as `allowNewUpload`
if (allowNewUpload && props.maxNumberOfFiles) {
allowNewUpload = props.totalFileCount < props.maxNumberOfFiles;
}
return h("div", {
className: "uppy-DashboardContent-bar"
}, !props.isAllComplete && !props.hideCancelButton ? h("button", {
className: "uppy-DashboardContent-back",
type: "button",
onClick: props.cancelAll
}, props.i18n('cancel')) : h("div", null), h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, h(UploadStatus, props)), allowNewUpload ? h("button", {
className: "uppy-DashboardContent-addMore",
type: "button",
"aria-label": props.i18n('addMoreFiles'),
title: props.i18n('addMoreFiles'),
onClick: function onClick() {
return props.toggleAddFilesPanel(true);
}
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "15",
height: "15",
viewBox: "0 0 15 15"
}, h("path", {
d: "M8 6.5h6a.5.5 0 0 1 .5.5v.5a.5.5 0 0 1-.5.5H8v6a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V8h-6a.5.5 0 0 1-.5-.5V7a.5.5 0 0 1 .5-.5h6v-6A.5.5 0 0 1 7 0h.5a.5.5 0 0 1 .5.5v6z"
})), h("span", {
className: "uppy-DashboardContent-addMoreCaption"
}, props.i18n('addMore'))) : h("div", null));
}
module.exports = PanelTopBar;
},{"preact":105}],96:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
cloneElement = _require.cloneElement,
Component = _require.Component;
var classNames = require('classnames');
var transitionName = 'uppy-transition-slideDownUp';
var duration = 250;
/**
* Vertical slide transition.
*
* This can take a _single_ child component, which _must_ accept a `className` prop.
*
* Currently this is specific to the `uppy-transition-slideDownUp` transition,
* but it should be simple to extend this for any type of single-element
* transition by setting the CSS name and duration as props.
*/
var Slide = /*#__PURE__*/function (_Component) {
_inheritsLoose(Slide, _Component);
function Slide(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.state = {
cachedChildren: null,
className: ''
};
return _this;
}
var _proto = Slide.prototype;
_proto.componentWillUpdate = function componentWillUpdate(nextProps) {
var _this2 = this;
var cachedChildren = this.state.cachedChildren;
var child = nextProps.children[0];
if (cachedChildren === child) return;
var patch = {
cachedChildren: child
}; // Enter transition
if (child && !cachedChildren) {
patch.className = transitionName + "-enter";
cancelAnimationFrame(this.animationFrame);
clearTimeout(this.leaveTimeout);
this.leaveTimeout = undefined;
this.animationFrame = requestAnimationFrame(function () {
// Force it to render before we add the active class
_this2.base.getBoundingClientRect();
_this2.setState({
className: transitionName + "-enter " + transitionName + "-enter-active"
});
_this2.enterTimeout = setTimeout(function () {
_this2.setState({
className: ''
});
}, duration);
});
} // Leave transition
if (cachedChildren && !child && this.leaveTimeout === undefined) {
patch.cachedChildren = cachedChildren;
patch.className = transitionName + "-leave";
cancelAnimationFrame(this.animationFrame);
clearTimeout(this.enterTimeout);
this.enterTimeout = undefined;
this.animationFrame = requestAnimationFrame(function () {
_this2.setState({
className: transitionName + "-leave " + transitionName + "-leave-active"
});
_this2.leaveTimeout = setTimeout(function () {
_this2.setState({
cachedChildren: null,
className: ''
});
}, duration);
});
}
this.setState(patch);
};
_proto.render = function render() {
var _this$state = this.state,
cachedChildren = _this$state.cachedChildren,
className = _this$state.className;
if (!cachedChildren) {
return null;
}
return cloneElement(cachedChildren, {
className: classNames(className, cachedChildren.attributes.className)
});
};
return Slide;
}(Component);
module.exports = Slide;
},{"classnames":11,"preact":105}],97:[function(require,module,exports){
var _excluded = ["data", "rowHeight", "renderRow", "overscanCount", "sync"];
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
/**
* Adapted from preact-virtual-list: https://github.com/developit/preact-virtual-list
*
* © 2016 Jason Miller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Adaptations:
* - Added role=presentation to helper elements
* - Tweaked styles for Uppy's Dashboard use case
*/
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var STYLE_INNER = {
position: 'relative',
// Disabled for our use case: the wrapper elements around FileList already deal with overflow,
// and this additional property would hide things that we want to show.
//
// overflow: 'hidden',
width: '100%',
minHeight: '100%'
};
var STYLE_CONTENT = {
position: 'absolute',
top: 0,
left: 0,
// Because the `top` value gets set to some offset, this `height` being 100% would make the scrollbar
// stretch far beyond the content. For our use case, the content div actually can get its height from
// the elements inside it, so we don't need to specify a `height` property at all.
//
// height: '100%',
width: '100%',
overflow: 'visible'
};
var VirtualList = /*#__PURE__*/function (_Component) {
_inheritsLoose(VirtualList, _Component);
function VirtualList(props) {
var _this;
_this = _Component.call(this, props) || this; // The currently focused node, used to retain focus when the visible rows change.
// To avoid update loops, this should not cause state updates, so it's kept as a plain property.
_this.handleResize = function () {
_this.resize();
};
_this.handleScroll = function () {
_this.setState({
offset: _this.base.scrollTop
});
if (_this.props.sync) {
_this.forceUpdate();
}
};
_this.focusElement = null;
_this.state = {
offset: 0,
height: 0
};
return _this;
}
var _proto = VirtualList.prototype;
_proto.resize = function resize() {
if (this.state.height !== this.base.offsetHeight) {
this.setState({
height: this.base.offsetHeight
});
}
};
_proto.componentWillUpdate = function componentWillUpdate() {
if (this.base.contains(document.activeElement)) {
this.focusElement = document.activeElement;
}
};
_proto.componentDidUpdate = function componentDidUpdate() {
// Maintain focus when rows are added and removed.
if (this.focusElement && this.focusElement.parentNode && document.activeElement !== this.focusElement) {
this.focusElement.focus();
}
this.focusElement = null;
this.resize();
};
_proto.componentDidMount = function componentDidMount() {
this.resize();
window.addEventListener('resize', this.handleResize);
};
_proto.componentWillUnmount = function componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
};
_proto.render = function render(_ref) {
var data = _ref.data,
rowHeight = _ref.rowHeight,
renderRow = _ref.renderRow,
_ref$overscanCount = _ref.overscanCount,
overscanCount = _ref$overscanCount === void 0 ? 10 : _ref$overscanCount,
sync = _ref.sync,
props = _objectWithoutPropertiesLoose(_ref, _excluded);
var _this$state = this.state,
offset = _this$state.offset,
height = _this$state.height; // first visible row index
var start = Math.floor(offset / rowHeight); // actual number of visible rows (without overscan)
var visibleRowCount = Math.floor(height / rowHeight); // Overscan: render blocks of rows modulo an overscan row count
// This dramatically reduces DOM writes during scrolling
if (overscanCount) {
start = Math.max(0, start - start % overscanCount);
visibleRowCount += overscanCount;
} // last visible + overscan row index + padding to allow keyboard focus to travel past the visible area
var end = start + visibleRowCount + 4; // data slice currently in viewport plus overscan items
var selection = data.slice(start, end);
var styleInner = _extends({}, STYLE_INNER, {
height: data.length * rowHeight
});
var styleContent = _extends({}, STYLE_CONTENT, {
top: start * rowHeight
}); // The `role="presentation"` attributes ensure that these wrapper elements are not treated as list
// items by accessibility and outline tools.
return h("div", _extends({
onScroll: this.handleScroll
}, props), h("div", {
role: "presentation",
style: styleInner
}, h("div", {
role: "presentation",
style: styleContent
}, selection.map(renderRow))));
};
return VirtualList;
}(Component);
module.exports = VirtualList;
},{"preact":105}],98:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h;
var _require2 = require('@uppy/core'),
Plugin = _require2.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var DashboardUI = require('./components/Dashboard');
var StatusBar = require('@uppy/status-bar');
var Informer = require('@uppy/informer');
var ThumbnailGenerator = require('@uppy/thumbnail-generator');
var findAllDOMElements = require('@uppy/utils/lib/findAllDOMElements');
var toArray = require('@uppy/utils/lib/toArray');
var getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles');
var getTextDirection = require('@uppy/utils/lib/getTextDirection');
var trapFocus = require('./utils/trapFocus');
var cuid = require('cuid');
var ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill');
var createSuperFocus = require('./utils/createSuperFocus');
var memoize = require('memoize-one').default || require('memoize-one');
var FOCUSABLE_ELEMENTS = require('@uppy/utils/lib/FOCUSABLE_ELEMENTS');
var TAB_KEY = 9;
var ESC_KEY = 27;
function createPromise() {
var o = {};
o.promise = new Promise(function (resolve, reject) {
o.resolve = resolve;
o.reject = reject;
});
return o;
}
function defaultPickerIcon() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "30",
height: "30",
viewBox: "0 0 30 30"
}, h("path", {
d: "M15 30c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15C6.716 0 0 6.716 0 15c0 8.284 6.716 15 15 15zm4.258-12.676v6.846h-8.426v-6.846H5.204l9.82-12.364 9.82 12.364H19.26z"
}));
}
/**
* Dashboard UI with previews, metadata editing, tabs for various services and more
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Dashboard, _Plugin);
function Dashboard(uppy, _opts) {
var _this;
_this = _Plugin.call(this, uppy, _opts) || this;
_this.setOptions = function (newOpts) {
_Plugin.prototype.setOptions.call(_assertThisInitialized(_this), newOpts);
_this.i18nInit();
};
_this.i18nInit = function () {
_this.translator = new Translator([_this.defaultLocale, _this.uppy.locale, _this.opts.locale]);
_this.i18n = _this.translator.translate.bind(_this.translator);
_this.i18nArray = _this.translator.translateArray.bind(_this.translator);
_this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_this.removeTarget = function (plugin) {
var pluginState = _this.getPluginState(); // filter out the one we want to remove
var newTargets = pluginState.targets.filter(function (target) {
return target.id !== plugin.id;
});
_this.setPluginState({
targets: newTargets
});
};
_this.addTarget = function (plugin) {
var callerPluginId = plugin.id || plugin.constructor.name;
var callerPluginName = plugin.title || callerPluginId;
var callerPluginType = plugin.type;
if (callerPluginType !== 'acquirer' && callerPluginType !== 'progressindicator' && callerPluginType !== 'editor') {
var msg = 'Dashboard: can only be targeted by plugins of types: acquirer, progressindicator, editor';
_this.uppy.log(msg, 'error');
return;
}
var target = {
id: callerPluginId,
name: callerPluginName,
type: callerPluginType
};
var state = _this.getPluginState();
var newTargets = state.targets.slice();
newTargets.push(target);
_this.setPluginState({
targets: newTargets
});
return _this.el;
};
_this.hideAllPanels = function () {
var update = {
activePickerPanel: false,
showAddFilesPanel: false,
activeOverlayType: null,
fileCardFor: null,
showFileEditor: false
};
var current = _this.getPluginState();
if (current.activePickerPanel === update.activePickerPanel && current.showAddFilesPanel === update.showAddFilesPanel && current.showFileEditor === update.showFileEditor && current.activeOverlayType === update.activeOverlayType) {
// avoid doing a state update if nothing changed
return;
}
_this.setPluginState(update);
};
_this.showPanel = function (id) {
var _this$getPluginState = _this.getPluginState(),
targets = _this$getPluginState.targets;
var activePickerPanel = targets.filter(function (target) {
return target.type === 'acquirer' && target.id === id;
})[0];
_this.setPluginState({
activePickerPanel: activePickerPanel,
activeOverlayType: 'PickerPanel'
});
};
_this.canEditFile = function (file) {
var _this$getPluginState2 = _this.getPluginState(),
targets = _this$getPluginState2.targets;
var editors = _this._getEditors(targets);
return editors.some(function (target) {
return _this.uppy.getPlugin(target.id).canEditFile(file);
});
};
_this.openFileEditor = function (file) {
var _this$getPluginState3 = _this.getPluginState(),
targets = _this$getPluginState3.targets;
var editors = _this._getEditors(targets);
_this.setPluginState({
showFileEditor: true,
fileCardFor: file.id || null,
activeOverlayType: 'FileEditor'
});
editors.forEach(function (editor) {
_this.uppy.getPlugin(editor.id).selectFile(file);
});
};
_this.saveFileEditor = function () {
var _this$getPluginState4 = _this.getPluginState(),
targets = _this$getPluginState4.targets;
var editors = _this._getEditors(targets);
editors.forEach(function (editor) {
_this.uppy.getPlugin(editor.id).save();
});
_this.hideAllPanels();
};
_this.openModal = function () {
var _createPromise = createPromise(),
promise = _createPromise.promise,
resolve = _createPromise.resolve; // save scroll position
_this.savedScrollPosition = window.pageYOffset; // save active element, so we can restore focus when modal is closed
_this.savedActiveElement = document.activeElement;
if (_this.opts.disablePageScrollWhenModalOpen) {
document.body.classList.add('uppy-Dashboard-isFixed');
}
if (_this.opts.animateOpenClose && _this.getPluginState().isClosing) {
var handler = function handler() {
_this.setPluginState({
isHidden: false
});
_this.el.removeEventListener('animationend', handler, false);
resolve();
};
_this.el.addEventListener('animationend', handler, false);
} else {
_this.setPluginState({
isHidden: false
});
resolve();
}
if (_this.opts.browserBackButtonClose) {
_this.updateBrowserHistory();
} // handle ESC and TAB keys in modal dialog
document.addEventListener('keydown', _this.handleKeyDownInModal);
_this.uppy.emit('dashboard:modal-open');
return promise;
};
_this.closeModal = function (opts) {
if (opts === void 0) {
opts = {};
}
var _opts2 = opts,
_opts2$manualClose = _opts2.manualClose,
manualClose = _opts2$manualClose === void 0 ? true : _opts2$manualClose;
var _this$getPluginState5 = _this.getPluginState(),
isHidden = _this$getPluginState5.isHidden,
isClosing = _this$getPluginState5.isClosing;
if (isHidden || isClosing) {
// short-circuit if animation is ongoing
return;
}
var _createPromise2 = createPromise(),
promise = _createPromise2.promise,
resolve = _createPromise2.resolve;
if (_this.opts.disablePageScrollWhenModalOpen) {
document.body.classList.remove('uppy-Dashboard-isFixed');
}
if (_this.opts.animateOpenClose) {
_this.setPluginState({
isClosing: true
});
var handler = function handler() {
_this.setPluginState({
isHidden: true,
isClosing: false
});
_this.superFocus.cancel();
_this.savedActiveElement.focus();
_this.el.removeEventListener('animationend', handler, false);
resolve();
};
_this.el.addEventListener('animationend', handler, false);
} else {
_this.setPluginState({
isHidden: true
});
_this.superFocus.cancel();
_this.savedActiveElement.focus();
resolve();
} // handle ESC and TAB keys in modal dialog
document.removeEventListener('keydown', _this.handleKeyDownInModal);
if (manualClose) {
if (_this.opts.browserBackButtonClose) {
// Make sure that the latest entry in the history state is our modal name
if (history.state && history.state[_this.modalName]) {
// Go back in history to clear out the entry we created (ultimately closing the modal)
history.go(-1);
}
}
}
_this.uppy.emit('dashboard:modal-closed');
return promise;
};
_this.isModalOpen = function () {
return !_this.getPluginState().isHidden || false;
};
_this.requestCloseModal = function () {
if (_this.opts.onRequestCloseModal) {
return _this.opts.onRequestCloseModal();
}
return _this.closeModal();
};
_this.setDarkModeCapability = function (isDarkModeOn) {
var _this$uppy$getState = _this.uppy.getState(),
capabilities = _this$uppy$getState.capabilities;
_this.uppy.setState({
capabilities: _extends({}, capabilities, {
darkMode: isDarkModeOn
})
});
};
_this.handleSystemDarkModeChange = function (event) {
var isDarkModeOnNow = event.matches;
_this.uppy.log("[Dashboard] Dark mode is " + (isDarkModeOnNow ? 'on' : 'off'));
_this.setDarkModeCapability(isDarkModeOnNow);
};
_this.toggleFileCard = function (show, fileID) {
var file = _this.uppy.getFile(fileID);
if (show) {
_this.uppy.emit('dashboard:file-edit-start', file);
} else {
_this.uppy.emit('dashboard:file-edit-complete', file);
}
_this.setPluginState({
fileCardFor: show ? fileID : null,
activeOverlayType: show ? 'FileCard' : null
});
};
_this.toggleAddFilesPanel = function (show) {
_this.setPluginState({
showAddFilesPanel: show,
activeOverlayType: show ? 'AddFiles' : null
});
};
_this.addFiles = function (files) {
var descriptors = files.map(function (file) {
return {
source: _this.id,
name: file.name,
type: file.type,
data: file,
meta: {
// path of the file relative to the ancestor directory the user selected.
// e.g. 'docs/Old Prague/airbnb.pdf'
relativePath: file.relativePath || null
}
};
});
try {
_this.uppy.addFiles(descriptors);
} catch (err) {
_this.uppy.log(err);
}
};
_this.startListeningToResize = function () {
// Watch for Dashboard container (`.uppy-Dashboard-inner`) resize
// and update containerWidth/containerHeight in plugin state accordingly.
// Emits first event on initialization.
_this.resizeObserver = new ResizeObserver(function (entries, observer) {
var uppyDashboardInnerEl = entries[0];
var _uppyDashboardInnerEl = uppyDashboardInnerEl.contentRect,
width = _uppyDashboardInnerEl.width,
height = _uppyDashboardInnerEl.height;
_this.uppy.log("[Dashboard] resized: " + width + " / " + height, 'debug');
_this.setPluginState({
containerWidth: width,
containerHeight: height,
areInsidesReadyToBeVisible: true
});
});
_this.resizeObserver.observe(_this.el.querySelector('.uppy-Dashboard-inner')); // If ResizeObserver fails to emit an event telling us what size to use - default to the mobile view
_this.makeDashboardInsidesVisibleAnywayTimeout = setTimeout(function () {
var pluginState = _this.getPluginState();
var isModalAndClosed = !_this.opts.inline && pluginState.isHidden;
if ( // if ResizeObserver hasn't yet fired,
!pluginState.areInsidesReadyToBeVisible // and it's not due to the modal being closed
&& !isModalAndClosed) {
_this.uppy.log("[Dashboard] resize event didn't fire on time: defaulted to mobile layout", 'debug');
_this.setPluginState({
areInsidesReadyToBeVisible: true
});
}
}, 1000);
};
_this.stopListeningToResize = function () {
_this.resizeObserver.disconnect();
clearTimeout(_this.makeDashboardInsidesVisibleAnywayTimeout);
};
_this.recordIfFocusedOnUppyRecently = function (event) {
if (_this.el.contains(event.target)) {
_this.ifFocusedOnUppyRecently = true;
} else {
_this.ifFocusedOnUppyRecently = false; // ___Why run this.superFocus.cancel here when it already runs in superFocusOnEachUpdate?
// Because superFocus is debounced, when we move from Uppy to some other element on the page,
// previously run superFocus sometimes hits and moves focus back to Uppy.
_this.superFocus.cancel();
}
};
_this.disableAllFocusableElements = function (disable) {
var focusableNodes = toArray(_this.el.querySelectorAll(FOCUSABLE_ELEMENTS));
if (disable) {
focusableNodes.forEach(function (node) {
// save previous tabindex in a data-attribute, to restore when enabling
var currentTabIndex = node.getAttribute('tabindex');
if (currentTabIndex) {
node.dataset.inertTabindex = currentTabIndex;
}
node.setAttribute('tabindex', '-1');
});
} else {
focusableNodes.forEach(function (node) {
if ('inertTabindex' in node.dataset) {
node.setAttribute('tabindex', node.dataset.inertTabindex);
} else {
node.removeAttribute('tabindex');
}
});
}
_this.dashboardIsDisabled = disable;
};
_this.updateBrowserHistory = function () {
// Ensure history state does not already contain our modal name to avoid double-pushing
if (!history.state || !history.state[_this.modalName]) {
var _extends2;
// Push to history so that the page is not lost on browser back button press
history.pushState(_extends({}, history.state, (_extends2 = {}, _extends2[_this.modalName] = true, _extends2)), '');
} // Listen for back button presses
window.addEventListener('popstate', _this.handlePopState, false);
};
_this.handlePopState = function (event) {
// Close the modal if the history state no longer contains our modal name
if (_this.isModalOpen() && (!event.state || !event.state[_this.modalName])) {
_this.closeModal({
manualClose: false
});
} // When the browser back button is pressed and uppy is now the latest entry in the history but the modal is closed, fix the history by removing the uppy history entry
// This occurs when another entry is added into the history state while the modal is open, and then the modal gets manually closed
// Solves PR #575 (https://github.com/transloadit/uppy/pull/575)
if (!_this.isModalOpen() && event.state && event.state[_this.modalName]) {
history.go(-1);
}
};
_this.handleKeyDownInModal = function (event) {
// close modal on esc key press
if (event.keyCode === ESC_KEY) _this.requestCloseModal(event); // trap focus on tab key press
if (event.keyCode === TAB_KEY) trapFocus.forModal(event, _this.getPluginState().activeOverlayType, _this.el);
};
_this.handleClickOutside = function () {
if (_this.opts.closeModalOnClickOutside) _this.requestCloseModal();
};
_this.handlePaste = function (event) {
// 1. Let any acquirer plugin (Url/Webcam/etc.) handle pastes to the root
_this.uppy.iteratePlugins(function (plugin) {
if (plugin.type === 'acquirer') {
// Every Plugin with .type acquirer can define handleRootPaste(event)
plugin.handleRootPaste && plugin.handleRootPaste(event);
}
}); // 2. Add all dropped files
var files = toArray(event.clipboardData.files);
_this.addFiles(files);
};
_this.handleInputChange = function (event) {
event.preventDefault();
var files = toArray(event.target.files);
_this.addFiles(files);
};
_this.handleDragOver = function (event) {
event.preventDefault();
event.stopPropagation();
if (_this.opts.disabled || _this.opts.disableLocalFiles) {
return;
} // 1. Add a small (+) icon on drop
// (and prevent browsers from interpreting this as files being _moved_ into the browser, https://github.com/transloadit/uppy/issues/1978)
event.dataTransfer.dropEffect = 'copy';
clearTimeout(_this.removeDragOverClassTimeout);
_this.setPluginState({
isDraggingOver: true
});
};
_this.handleDragLeave = function (event) {
event.preventDefault();
event.stopPropagation();
if (_this.opts.disabled || _this.opts.disableLocalFiles) {
return;
}
clearTimeout(_this.removeDragOverClassTimeout); // Timeout against flickering, this solution is taken from drag-drop library. Solution with 'pointer-events: none' didn't work across browsers.
_this.removeDragOverClassTimeout = setTimeout(function () {
_this.setPluginState({
isDraggingOver: false
});
}, 50);
};
_this.handleDrop = function (event, dropCategory) {
event.preventDefault();
event.stopPropagation();
if (_this.opts.disabled || _this.opts.disableLocalFiles) {
return;
}
clearTimeout(_this.removeDragOverClassTimeout); // 2. Remove dragover class
_this.setPluginState({
isDraggingOver: false
}); // 3. Let any acquirer plugin (Url/Webcam/etc.) handle drops to the root
_this.uppy.iteratePlugins(function (plugin) {
if (plugin.type === 'acquirer') {
// Every Plugin with .type acquirer can define handleRootDrop(event)
plugin.handleRootDrop && plugin.handleRootDrop(event);
}
}); // 4. Add all dropped files
var executedDropErrorOnce = false;
var logDropError = function logDropError(error) {
_this.uppy.log(error, 'error'); // In practice all drop errors are most likely the same, so let's just show one to avoid overwhelming the user
if (!executedDropErrorOnce) {
_this.uppy.info(error.message, 'error');
executedDropErrorOnce = true;
}
};
getDroppedFiles(event.dataTransfer, {
logDropError: logDropError
}).then(function (files) {
if (files.length > 0) {
_this.uppy.log('[Dashboard] Files were dropped');
_this.addFiles(files);
}
});
};
_this.handleRequestThumbnail = function (file) {
if (!_this.opts.waitForThumbnailsBeforeUpload) {
_this.uppy.emit('thumbnail:request', file);
}
};
_this.handleCancelThumbnail = function (file) {
if (!_this.opts.waitForThumbnailsBeforeUpload) {
_this.uppy.emit('thumbnail:cancel', file);
}
};
_this.handleKeyDownInInline = function (event) {
// Trap focus on tab key press.
if (event.keyCode === TAB_KEY) trapFocus.forInline(event, _this.getPluginState().activeOverlayType, _this.el);
};
_this.handlePasteOnBody = function (event) {
var isFocusInOverlay = _this.el.contains(document.activeElement);
if (isFocusInOverlay) {
_this.handlePaste(event);
}
};
_this.handleComplete = function (_ref) {
var failed = _ref.failed;
if (_this.opts.closeAfterFinish && failed.length === 0) {
// All uploads are done
_this.requestCloseModal();
}
};
_this.handleCancelRestore = function () {
_this.uppy.emit('restore-canceled');
};
_this._openFileEditorWhenFilesAdded = function (files) {
var firstFile = files[0];
if (_this.canEditFile(firstFile)) {
_this.openFileEditor(firstFile);
}
};
_this.initEvents = function () {
// Modal open button
if (_this.opts.trigger && !_this.opts.inline) {
var showModalTrigger = findAllDOMElements(_this.opts.trigger);
if (showModalTrigger) {
showModalTrigger.forEach(function (trigger) {
return trigger.addEventListener('click', _this.openModal);
});
} else {
_this.uppy.log('Dashboard modal trigger not found. Make sure `trigger` is set in Dashboard options, unless you are planning to call `dashboard.openModal()` method yourself', 'warning');
}
}
_this.startListeningToResize();
document.addEventListener('paste', _this.handlePasteOnBody);
_this.uppy.on('plugin-remove', _this.removeTarget);
_this.uppy.on('file-added', _this.hideAllPanels);
_this.uppy.on('dashboard:modal-closed', _this.hideAllPanels);
_this.uppy.on('file-editor:complete', _this.hideAllPanels);
_this.uppy.on('complete', _this.handleComplete); // ___Why fire on capture?
// Because this.ifFocusedOnUppyRecently needs to change before onUpdate() fires.
document.addEventListener('focus', _this.recordIfFocusedOnUppyRecently, true);
document.addEventListener('click', _this.recordIfFocusedOnUppyRecently, true);
if (_this.opts.inline) {
_this.el.addEventListener('keydown', _this.handleKeyDownInInline);
}
if (_this.opts.autoOpenFileEditor) {
_this.uppy.on('files-added', _this._openFileEditorWhenFilesAdded);
}
};
_this.removeEvents = function () {
var showModalTrigger = findAllDOMElements(_this.opts.trigger);
if (!_this.opts.inline && showModalTrigger) {
showModalTrigger.forEach(function (trigger) {
return trigger.removeEventListener('click', _this.openModal);
});
}
_this.stopListeningToResize();
document.removeEventListener('paste', _this.handlePasteOnBody);
window.removeEventListener('popstate', _this.handlePopState, false);
_this.uppy.off('plugin-remove', _this.removeTarget);
_this.uppy.off('file-added', _this.hideAllPanels);
_this.uppy.off('dashboard:modal-closed', _this.hideAllPanels);
_this.uppy.off('file-editor:complete', _this.hideAllPanels);
_this.uppy.off('complete', _this.handleComplete);
document.removeEventListener('focus', _this.recordIfFocusedOnUppyRecently);
document.removeEventListener('click', _this.recordIfFocusedOnUppyRecently);
if (_this.opts.inline) {
_this.el.removeEventListener('keydown', _this.handleKeyDownInInline);
}
if (_this.opts.autoOpenFileEditor) {
_this.uppy.off('files-added', _this._openFileEditorWhenFilesAdded);
}
};
_this.superFocusOnEachUpdate = function () {
var isFocusInUppy = _this.el.contains(document.activeElement); // When focus is lost on the page (== focus is on body for most browsers, or focus is null for IE11)
var isFocusNowhere = document.activeElement === document.body || document.activeElement === null;
var isInformerHidden = _this.uppy.getState().info.isHidden;
var isModal = !_this.opts.inline;
if ( // If update is connected to showing the Informer - let the screen reader calmly read it.
isInformerHidden && ( // If we are in a modal - always superfocus without concern for other elements on the page (user is unlikely to want to interact with the rest of the page)
isModal // If we are already inside of Uppy, or
|| isFocusInUppy // If we are not focused on anything BUT we have already, at least once, focused on uppy
// 1. We focus when isFocusNowhere, because when the element we were focused on disappears (e.g. an overlay), - focus gets lost. If user is typing something somewhere else on the page, - focus won't be 'nowhere'.
// 2. We only focus when focus is nowhere AND this.ifFocusedOnUppyRecently, to avoid focus jumps if we do something else on the page.
// [Practical check] Without '&& this.ifFocusedOnUppyRecently', in Safari, in inline mode, when file is uploading, - navigate via tab to the checkbox, try to press space multiple times. Focus will jump to Uppy.
|| isFocusNowhere && _this.ifFocusedOnUppyRecently)) {
_this.superFocus(_this.el, _this.getPluginState().activeOverlayType);
} else {
_this.superFocus.cancel();
}
};
_this.afterUpdate = function () {
if (_this.opts.disabled && !_this.dashboardIsDisabled) {
_this.disableAllFocusableElements(true);
return;
}
if (!_this.opts.disabled && _this.dashboardIsDisabled) {
_this.disableAllFocusableElements(false);
}
_this.superFocusOnEachUpdate();
};
_this.cancelUpload = function (fileID) {
_this.uppy.removeFile(fileID);
};
_this.saveFileCard = function (meta, fileID) {
_this.uppy.setFileMeta(fileID, meta);
_this.toggleFileCard(false, fileID);
};
_this._attachRenderFunctionToTarget = function (target) {
var plugin = _this.uppy.getPlugin(target.id);
return _extends({}, target, {
icon: plugin.icon || _this.opts.defaultPickerIcon,
render: plugin.render
});
};
_this._isTargetSupported = function (target) {
var plugin = _this.uppy.getPlugin(target.id); // If the plugin does not provide a `supported` check, assume the plugin works everywhere.
if (typeof plugin.isSupported !== 'function') {
return true;
}
return plugin.isSupported();
};
_this._getAcquirers = memoize(function (targets) {
return targets.filter(function (target) {
return target.type === 'acquirer' && _this._isTargetSupported(target);
}).map(_this._attachRenderFunctionToTarget);
});
_this._getProgressIndicators = memoize(function (targets) {
return targets.filter(function (target) {
return target.type === 'progressindicator';
}).map(_this._attachRenderFunctionToTarget);
});
_this._getEditors = memoize(function (targets) {
return targets.filter(function (target) {
return target.type === 'editor';
}).map(_this._attachRenderFunctionToTarget);
});
_this.render = function (state) {
var pluginState = _this.getPluginState();
var files = state.files,
capabilities = state.capabilities,
allowNewUpload = state.allowNewUpload; // TODO: move this to Core, to share between Status Bar and Dashboard
// (and any other plugin that might need it, too)
var newFiles = Object.keys(files).filter(function (file) {
return !files[file].progress.uploadStarted;
});
var uploadStartedFiles = Object.keys(files).filter(function (file) {
return files[file].progress.uploadStarted;
});
var pausedFiles = Object.keys(files).filter(function (file) {
return files[file].isPaused;
});
var completeFiles = Object.keys(files).filter(function (file) {
return files[file].progress.uploadComplete;
});
var erroredFiles = Object.keys(files).filter(function (file) {
return files[file].error;
});
var inProgressFiles = Object.keys(files).filter(function (file) {
return !files[file].progress.uploadComplete && files[file].progress.uploadStarted;
});
var inProgressNotPausedFiles = inProgressFiles.filter(function (file) {
return !files[file].isPaused;
});
var processingFiles = Object.keys(files).filter(function (file) {
return files[file].progress.preprocess || files[file].progress.postprocess;
});
var isUploadStarted = uploadStartedFiles.length > 0;
var isAllComplete = state.totalProgress === 100 && completeFiles.length === Object.keys(files).length && processingFiles.length === 0;
var isAllErrored = isUploadStarted && erroredFiles.length === uploadStartedFiles.length;
var isAllPaused = inProgressFiles.length !== 0 && pausedFiles.length === inProgressFiles.length;
var acquirers = _this._getAcquirers(pluginState.targets);
var progressindicators = _this._getProgressIndicators(pluginState.targets);
var editors = _this._getEditors(pluginState.targets);
var theme;
if (_this.opts.theme === 'auto') {
theme = capabilities.darkMode ? 'dark' : 'light';
} else {
theme = _this.opts.theme;
}
if (['files', 'folders', 'both'].indexOf(_this.opts.fileManagerSelectionType) < 0) {
_this.opts.fileManagerSelectionType = 'files';
console.error("Unsupported option for \"fileManagerSelectionType\". Using default of \"" + _this.opts.fileManagerSelectionType + "\".");
}
return DashboardUI({
state: state,
isHidden: pluginState.isHidden,
files: files,
newFiles: newFiles,
uploadStartedFiles: uploadStartedFiles,
completeFiles: completeFiles,
erroredFiles: erroredFiles,
inProgressFiles: inProgressFiles,
inProgressNotPausedFiles: inProgressNotPausedFiles,
processingFiles: processingFiles,
isUploadStarted: isUploadStarted,
isAllComplete: isAllComplete,
isAllErrored: isAllErrored,
isAllPaused: isAllPaused,
totalFileCount: Object.keys(files).length,
totalProgress: state.totalProgress,
allowNewUpload: allowNewUpload,
acquirers: acquirers,
theme: theme,
disabled: _this.opts.disabled,
disableLocalFiles: _this.opts.disableLocalFiles,
direction: _this.opts.direction,
activePickerPanel: pluginState.activePickerPanel,
showFileEditor: pluginState.showFileEditor,
saveFileEditor: _this.saveFileEditor,
disableAllFocusableElements: _this.disableAllFocusableElements,
animateOpenClose: _this.opts.animateOpenClose,
isClosing: pluginState.isClosing,
getPlugin: _this.uppy.getPlugin,
progressindicators: progressindicators,
editors: editors,
autoProceed: _this.uppy.opts.autoProceed,
id: _this.id,
closeModal: _this.requestCloseModal,
handleClickOutside: _this.handleClickOutside,
handleInputChange: _this.handleInputChange,
handlePaste: _this.handlePaste,
inline: _this.opts.inline,
showPanel: _this.showPanel,
hideAllPanels: _this.hideAllPanels,
log: _this.uppy.log,
i18n: _this.i18n,
i18nArray: _this.i18nArray,
removeFile: _this.uppy.removeFile,
uppy: _this.uppy,
info: _this.uppy.info,
note: _this.opts.note,
recoveredState: state.recoveredState,
metaFields: pluginState.metaFields,
resumableUploads: capabilities.resumableUploads || false,
individualCancellation: capabilities.individualCancellation,
isMobileDevice: capabilities.isMobileDevice,
pauseUpload: _this.uppy.pauseResume,
retryUpload: _this.uppy.retryUpload,
cancelUpload: _this.cancelUpload,
cancelAll: _this.uppy.cancelAll,
fileCardFor: pluginState.fileCardFor,
toggleFileCard: _this.toggleFileCard,
toggleAddFilesPanel: _this.toggleAddFilesPanel,
showAddFilesPanel: pluginState.showAddFilesPanel,
saveFileCard: _this.saveFileCard,
openFileEditor: _this.openFileEditor,
canEditFile: _this.canEditFile,
width: _this.opts.width,
height: _this.opts.height,
showLinkToFileUploadResult: _this.opts.showLinkToFileUploadResult,
fileManagerSelectionType: _this.opts.fileManagerSelectionType,
proudlyDisplayPoweredByUppy: _this.opts.proudlyDisplayPoweredByUppy,
hideCancelButton: _this.opts.hideCancelButton,
hideRetryButton: _this.opts.hideRetryButton,
hidePauseResumeButton: _this.opts.hidePauseResumeButton,
showRemoveButtonAfterComplete: _this.opts.showRemoveButtonAfterComplete,
containerWidth: pluginState.containerWidth,
containerHeight: pluginState.containerHeight,
areInsidesReadyToBeVisible: pluginState.areInsidesReadyToBeVisible,
isTargetDOMEl: _this.isTargetDOMEl,
parentElement: _this.el,
allowedFileTypes: _this.uppy.opts.restrictions.allowedFileTypes,
maxNumberOfFiles: _this.uppy.opts.restrictions.maxNumberOfFiles,
requiredMetaFields: _this.uppy.opts.restrictions.requiredMetaFields,
showSelectedFiles: _this.opts.showSelectedFiles,
handleCancelRestore: _this.handleCancelRestore,
handleRequestThumbnail: _this.handleRequestThumbnail,
handleCancelThumbnail: _this.handleCancelThumbnail,
// drag props
isDraggingOver: pluginState.isDraggingOver,
handleDragOver: _this.handleDragOver,
handleDragLeave: _this.handleDragLeave,
handleDrop: _this.handleDrop
});
};
_this.discoverProviderPlugins = function () {
_this.uppy.iteratePlugins(function (plugin) {
if (plugin && !plugin.target && plugin.opts && plugin.opts.target === _this.constructor) {
_this.addTarget(plugin);
}
});
};
_this.install = function () {
// Set default state for Dashboard
_this.setPluginState({
isHidden: true,
fileCardFor: null,
activeOverlayType: null,
showAddFilesPanel: false,
activePickerPanel: false,
showFileEditor: false,
metaFields: _this.opts.metaFields,
targets: [],
// We'll make them visible once .containerWidth is determined
areInsidesReadyToBeVisible: false,
isDraggingOver: false
});
var _this$opts = _this.opts,
inline = _this$opts.inline,
closeAfterFinish = _this$opts.closeAfterFinish;
if (inline && closeAfterFinish) {
throw new Error('[Dashboard] `closeAfterFinish: true` cannot be used on an inline Dashboard, because an inline Dashboard cannot be closed at all. Either set `inline: false`, or disable the `closeAfterFinish` option.');
}
var allowMultipleUploads = _this.uppy.opts.allowMultipleUploads;
if (allowMultipleUploads && closeAfterFinish) {
_this.uppy.log('[Dashboard] When using `closeAfterFinish`, we recommended setting the `allowMultipleUploads` option to `false` in the Uppy constructor. See https://uppy.io/docs/uppy/#allowMultipleUploads-true', 'warning');
}
var target = _this.opts.target;
if (target) {
_this.mount(target, _assertThisInitialized(_this));
}
var plugins = _this.opts.plugins || [];
plugins.forEach(function (pluginID) {
var plugin = _this.uppy.getPlugin(pluginID);
if (plugin) {
plugin.mount(_assertThisInitialized(_this), plugin);
}
});
if (!_this.opts.disableStatusBar) {
_this.uppy.use(StatusBar, {
id: _this.id + ":StatusBar",
target: _assertThisInitialized(_this),
hideUploadButton: _this.opts.hideUploadButton,
hideRetryButton: _this.opts.hideRetryButton,
hidePauseResumeButton: _this.opts.hidePauseResumeButton,
hideCancelButton: _this.opts.hideCancelButton,
showProgressDetails: _this.opts.showProgressDetails,
hideAfterFinish: _this.opts.hideProgressAfterFinish,
locale: _this.opts.locale,
doneButtonHandler: _this.opts.doneButtonHandler
});
}
if (!_this.opts.disableInformer) {
_this.uppy.use(Informer, {
id: _this.id + ":Informer",
target: _assertThisInitialized(_this)
});
}
if (!_this.opts.disableThumbnailGenerator) {
_this.uppy.use(ThumbnailGenerator, {
id: _this.id + ":ThumbnailGenerator",
thumbnailWidth: _this.opts.thumbnailWidth,
thumbnailType: _this.opts.thumbnailType,
waitForThumbnailsBeforeUpload: _this.opts.waitForThumbnailsBeforeUpload,
// If we don't block on thumbnails, we can lazily generate them
lazy: !_this.opts.waitForThumbnailsBeforeUpload
});
} // Dark Mode / theme
_this.darkModeMediaQuery = typeof window !== 'undefined' && window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
var isDarkModeOnFromTheStart = _this.darkModeMediaQuery ? _this.darkModeMediaQuery.matches : false;
_this.uppy.log("[Dashboard] Dark mode is " + (isDarkModeOnFromTheStart ? 'on' : 'off'));
_this.setDarkModeCapability(isDarkModeOnFromTheStart);
if (_this.opts.theme === 'auto') {
_this.darkModeMediaQuery.addListener(_this.handleSystemDarkModeChange);
}
_this.discoverProviderPlugins();
_this.initEvents();
};
_this.uninstall = function () {
if (!_this.opts.disableInformer) {
var informer = _this.uppy.getPlugin(_this.id + ":Informer"); // Checking if this plugin exists, in case it was removed by uppy-core
// before the Dashboard was.
if (informer) _this.uppy.removePlugin(informer);
}
if (!_this.opts.disableStatusBar) {
var statusBar = _this.uppy.getPlugin(_this.id + ":StatusBar");
if (statusBar) _this.uppy.removePlugin(statusBar);
}
if (!_this.opts.disableThumbnailGenerator) {
var thumbnail = _this.uppy.getPlugin(_this.id + ":ThumbnailGenerator");
if (thumbnail) _this.uppy.removePlugin(thumbnail);
}
var plugins = _this.opts.plugins || [];
plugins.forEach(function (pluginID) {
var plugin = _this.uppy.getPlugin(pluginID);
if (plugin) plugin.unmount();
});
if (_this.opts.theme === 'auto') {
_this.darkModeMediaQuery.removeListener(_this.handleSystemDarkModeChange);
}
_this.unmount();
_this.removeEvents();
};
_this.id = _this.opts.id || 'Dashboard';
_this.title = 'Dashboard';
_this.type = 'orchestrator';
_this.modalName = "uppy-Dashboard-" + cuid();
_this.defaultLocale = {
strings: {
closeModal: 'Close Modal',
importFrom: 'Import from %{name}',
addingMoreFiles: 'Adding more files',
addMoreFiles: 'Add more files',
dashboardWindowTitle: 'File Uploader Window (Press escape to close)',
dashboardTitle: 'File Uploader',
copyLinkToClipboardSuccess: 'Link copied to clipboard',
copyLinkToClipboardFallback: 'Copy the URL below',
copyLink: 'Copy link',
fileSource: 'File source: %{name}',
back: 'Back',
addMore: 'Add more',
removeFile: 'Remove file',
editFile: 'Edit file',
editing: 'Editing %{file}',
finishEditingFile: 'Finish editing file',
save: 'Save',
saveChanges: 'Save changes',
cancel: 'Cancel',
myDevice: 'My Device',
dropPasteFiles: 'Drop files here or %{browseFiles}',
dropPasteFolders: 'Drop files here or %{browseFolders}',
dropPasteBoth: 'Drop files here, %{browseFiles} or %{browseFolders}',
dropPasteImportFiles: 'Drop files here, %{browseFiles} or import from:',
dropPasteImportFolders: 'Drop files here, %{browseFolders} or import from:',
dropPasteImportBoth: 'Drop files here, %{browseFiles}, %{browseFolders} or import from:',
importFiles: 'Import files from:',
dropHint: 'Drop your files here',
browseFiles: 'browse files',
browseFolders: 'browse folders',
uploadComplete: 'Upload complete',
uploadPaused: 'Upload paused',
resumeUpload: 'Resume upload',
pauseUpload: 'Pause upload',
retryUpload: 'Retry upload',
cancelUpload: 'Cancel upload',
xFilesSelected: {
0: '%{smart_count} file selected',
1: '%{smart_count} files selected'
},
uploadingXFiles: {
0: 'Uploading %{smart_count} file',
1: 'Uploading %{smart_count} files'
},
processingXFiles: {
0: 'Processing %{smart_count} file',
1: 'Processing %{smart_count} files'
},
recoveredXFiles: {
0: 'We could not fully recover 1 file. Please re-select it and resume the upload.',
1: 'We could not fully recover %{smart_count} files. Please re-select them and resume the upload.'
},
recoveredAllFiles: 'We restored all files. You can now resume the upload.',
sessionRestored: 'Session restored',
reSelect: 'Re-select',
// The default `poweredBy2` string only combines the `poweredBy` string (%{backwardsCompat}) with the size.
// Locales can override `poweredBy2` to specify a different word order. This is for backwards compat with
// Uppy 1.9.x and below which did a naive concatenation of `poweredBy2 + size` instead of using a locale-specific
// substitution.
// TODO: In 2.0 `poweredBy2` should be removed in and `poweredBy` updated to use substitution.
poweredBy2: '%{backwardsCompat} %{uppy}',
poweredBy: 'Powered by'
}
}; // set default options
var defaultOptions = {
target: 'body',
metaFields: [],
trigger: '#uppy-select-files',
inline: false,
width: 750,
height: 550,
thumbnailWidth: 280,
thumbnailType: 'image/jpeg',
waitForThumbnailsBeforeUpload: false,
defaultPickerIcon: defaultPickerIcon,
showLinkToFileUploadResult: true,
showProgressDetails: false,
hideUploadButton: false,
hideCancelButton: false,
hideRetryButton: false,
hidePauseResumeButton: false,
hideProgressAfterFinish: false,
doneButtonHandler: function doneButtonHandler() {
_this.uppy.reset();
_this.requestCloseModal();
},
note: null,
closeModalOnClickOutside: false,
closeAfterFinish: false,
disableStatusBar: false,
disableInformer: false,
disableThumbnailGenerator: false,
disablePageScrollWhenModalOpen: true,
animateOpenClose: true,
fileManagerSelectionType: 'files',
proudlyDisplayPoweredByUppy: true,
onRequestCloseModal: function onRequestCloseModal() {
return _this.closeModal();
},
showSelectedFiles: true,
showRemoveButtonAfterComplete: false,
browserBackButtonClose: false,
theme: 'light',
autoOpenFileEditor: false,
disabled: false,
disableLocalFiles: false
}; // merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, _opts);
_this.i18nInit();
_this.superFocus = createSuperFocus();
_this.ifFocusedOnUppyRecently = false; // Timeouts
_this.makeDashboardInsidesVisibleAnywayTimeout = null;
_this.removeDragOverClassTimeout = null;
return _this;
}
var _proto = Dashboard.prototype;
_proto.onMount = function onMount() {
// Set the text direction if the page has not defined one.
var element = this.el;
var direction = getTextDirection(element);
if (!direction) {
element.dir = 'ltr';
}
};
return Dashboard;
}(Plugin), _class.VERSION = "1.21.1", _temp);
},{"./components/Dashboard":84,"./utils/createSuperFocus":100,"./utils/trapFocus":104,"@uppy/core":78,"@uppy/informer":126,"@uppy/status-bar":168,"@uppy/thumbnail-generator":172,"@uppy/utils/lib/FOCUSABLE_ELEMENTS":214,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/findAllDOMElements":224,"@uppy/utils/lib/getDroppedFiles":229,"@uppy/utils/lib/getTextDirection":239,"@uppy/utils/lib/toArray":252,"cuid":15,"memoize-one":36,"preact":105,"resize-observer-polyfill":43}],99:[function(require,module,exports){
/**
* Copies text to clipboard by creating an almost invisible textarea,
* adding text there, then running execCommand('copy').
* Falls back to prompt() when the easy way fails (hello, Safari!)
* From http://stackoverflow.com/a/30810322
*
* @param {string} textToCopy
* @param {string} fallbackString
* @returns {Promise}
*/
module.exports = function copyToClipboard(textToCopy, fallbackString) {
fallbackString = fallbackString || 'Copy the URL below';
return new Promise(function (resolve) {
var textArea = document.createElement('textarea');
textArea.setAttribute('style', {
position: 'fixed',
top: 0,
left: 0,
width: '2em',
height: '2em',
padding: 0,
border: 'none',
outline: 'none',
boxShadow: 'none',
background: 'transparent'
});
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
var magicCopyFailed = function magicCopyFailed() {
document.body.removeChild(textArea);
window.prompt(fallbackString, textToCopy);
resolve();
};
try {
var successful = document.execCommand('copy');
if (!successful) {
return magicCopyFailed('copy command unavailable');
}
document.body.removeChild(textArea);
return resolve();
} catch (err) {
document.body.removeChild(textArea);
return magicCopyFailed(err);
}
});
};
},{}],100:[function(require,module,exports){
var debounce = require('lodash.debounce');
var FOCUSABLE_ELEMENTS = require('@uppy/utils/lib/FOCUSABLE_ELEMENTS');
var getActiveOverlayEl = require('./getActiveOverlayEl');
/*
Focuses on some element in the currently topmost overlay.
1. If there are some [data-uppy-super-focusable] elements rendered already - focuses on the first superfocusable element, and leaves focus up to the control of a user (until currently focused element disappears from the screen [which can happen when overlay changes, or, e.g., when we click on a folder in googledrive]).
2. If there are no [data-uppy-super-focusable] elements yet (or ever) - focuses on the first focusable element, but switches focus if superfocusable elements appear on next render.
*/
module.exports = function createSuperFocus() {
var lastFocusWasOnSuperFocusableEl = false;
var superFocus = function superFocus(dashboardEl, activeOverlayType) {
var overlayEl = getActiveOverlayEl(dashboardEl, activeOverlayType);
var isFocusInOverlay = overlayEl.contains(document.activeElement); // If focus is already in the topmost overlay, AND on last update we focused on the superfocusable element - then leave focus up to the user.
// [Practical check] without this line, typing in the search input in googledrive overlay won't work.
if (isFocusInOverlay && lastFocusWasOnSuperFocusableEl) return;
var superFocusableEl = overlayEl.querySelector('[data-uppy-super-focusable]'); // If we are already in the topmost overlay, AND there are no super focusable elements yet, - leave focus up to the user.
// [Practical check] without this line, if you are in an empty folder in google drive, and something's uploading in the bg, - focus will be jumping to Done all the time.
if (isFocusInOverlay && !superFocusableEl) return;
if (superFocusableEl) {
superFocusableEl.focus({
preventScroll: true
});
lastFocusWasOnSuperFocusableEl = true;
} else {
var firstEl = overlayEl.querySelector(FOCUSABLE_ELEMENTS);
firstEl && firstEl.focus({
preventScroll: true
});
lastFocusWasOnSuperFocusableEl = false;
}
}; // ___Why do we need to debounce?
// 1. To deal with animations: overlay changes via animations, which results in the DOM updating AFTER plugin.update() already executed.
// [Practical check] without debounce, if we open the Url overlay, and click 'Done', Dashboard won't get focused again.
// [Practical check] if we delay 250ms instead of 260ms - IE11 won't get focused in same situation.
// 2. Performance: there can be many state update()s in a second, and this function is called every time.
return debounce(superFocus, 260);
};
},{"./getActiveOverlayEl":101,"@uppy/utils/lib/FOCUSABLE_ELEMENTS":214,"lodash.debounce":33}],101:[function(require,module,exports){
/**
* @returns {HTMLElement} - either dashboard element, or the overlay that's most on top
*/
module.exports = function getActiveOverlayEl(dashboardEl, activeOverlayType) {
if (activeOverlayType) {
var overlayEl = dashboardEl.querySelector("[data-uppy-paneltype=\"" + activeOverlayType + "\"]"); // if an overlay is already mounted
if (overlayEl) return overlayEl;
}
return dashboardEl;
};
},{}],102:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
function iconImage() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("g", {
fill: "#686DE0",
fillRule: "evenodd"
}, h("path", {
d: "M5 7v10h15V7H5zm0-1h15a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1z",
fillRule: "nonzero"
}), h("path", {
d: "M6.35 17.172l4.994-5.026a.5.5 0 0 1 .707 0l2.16 2.16 3.505-3.505a.5.5 0 0 1 .707 0l2.336 2.31-.707.72-1.983-1.97-3.505 3.505a.5.5 0 0 1-.707 0l-2.16-2.159-3.938 3.939-1.409.026z",
fillRule: "nonzero"
}), h("circle", {
cx: "7.5",
cy: "9.5",
r: "1.5"
})));
}
function iconAudio() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("path", {
d: "M9.5 18.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V7.25a.5.5 0 0 1 .379-.485l9-2.25A.5.5 0 0 1 18.5 5v11.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V8.67l-8 2v7.97zm8-11v-2l-8 2v2l8-2zM7 19.64c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1zm9-2c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1z",
fill: "#049BCF",
fillRule: "nonzero"
}));
}
function iconVideo() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("path", {
d: "M16 11.834l4.486-2.691A1 1 0 0 1 22 10v6a1 1 0 0 1-1.514.857L16 14.167V17a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2.834zM15 9H5v8h10V9zm1 4l5 3v-6l-5 3z",
fill: "#19AF67",
fillRule: "nonzero"
}));
}
function iconPDF() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("path", {
d: "M9.766 8.295c-.691-1.843-.539-3.401.747-3.726 1.643-.414 2.505.938 2.39 3.299-.039.79-.194 1.662-.537 3.148.324.49.66.967 1.055 1.51.17.231.382.488.629.757 1.866-.128 3.653.114 4.918.655 1.487.635 2.192 1.685 1.614 2.84-.566 1.133-1.839 1.084-3.416.249-1.141-.604-2.457-1.634-3.51-2.707a13.467 13.467 0 0 0-2.238.426c-1.392 4.051-4.534 6.453-5.707 4.572-.986-1.58 1.38-4.206 4.914-5.375.097-.322.185-.656.264-1.001.08-.353.306-1.31.407-1.737-.678-1.059-1.2-2.031-1.53-2.91zm2.098 4.87c-.033.144-.068.287-.104.427l.033-.01-.012.038a14.065 14.065 0 0 1 1.02-.197l-.032-.033.052-.004a7.902 7.902 0 0 1-.208-.271c-.197-.27-.38-.526-.555-.775l-.006.028-.002-.003c-.076.323-.148.632-.186.8zm5.77 2.978c1.143.605 1.832.632 2.054.187.26-.519-.087-1.034-1.113-1.473-.911-.39-2.175-.608-3.55-.608.845.766 1.787 1.459 2.609 1.894zM6.559 18.789c.14.223.693.16 1.425-.413.827-.648 1.61-1.747 2.208-3.206-2.563 1.064-4.102 2.867-3.633 3.62zm5.345-10.97c.088-1.793-.351-2.48-1.146-2.28-.473.119-.564 1.05-.056 2.405.213.566.52 1.188.908 1.859.18-.858.268-1.453.294-1.984z",
fill: "#E2514A",
fillRule: "nonzero"
}));
}
function iconArchive() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("path", {
d: "M10.45 2.05h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5V2.55a.5.5 0 0 1 .5-.5zm2.05 1.024h1.05a.5.5 0 0 1 .5.5V3.6a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5v-.001zM10.45 0h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5V.5a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.024a.5.5 0 0 1 .5-.5zm-2.05 3.074h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.024a.5.5 0 0 1 .5-.5zm-2.05 1.024h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm-2.05 1.025h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.024a.5.5 0 0 1 .5-.5zm-1.656 3.074l-.82 5.946c.52.302 1.174.458 1.976.458.803 0 1.455-.156 1.975-.458l-.82-5.946h-2.311zm0-1.025h2.312c.512 0 .946.378 1.015.885l.82 5.946c.056.412-.142.817-.501 1.026-.686.398-1.515.597-2.49.597-.974 0-1.804-.199-2.49-.597a1.025 1.025 0 0 1-.5-1.026l.819-5.946c.07-.507.503-.885 1.015-.885zm.545 6.6a.5.5 0 0 1-.397-.561l.143-.999a.5.5 0 0 1 .495-.429h.74a.5.5 0 0 1 .495.43l.143.998a.5.5 0 0 1-.397.561c-.404.08-.819.08-1.222 0z",
fill: "#00C469",
fillRule: "nonzero"
}));
}
function iconFile() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("g", {
fill: "#A7AFB7",
fillRule: "nonzero"
}, h("path", {
d: "M5.5 22a.5.5 0 0 1-.5-.5v-18a.5.5 0 0 1 .5-.5h10.719a.5.5 0 0 1 .367.16l3.281 3.556a.5.5 0 0 1 .133.339V21.5a.5.5 0 0 1-.5.5h-14zm.5-1h13V7.25L16 4H6v17z"
}), h("path", {
d: "M15 4v3a1 1 0 0 0 1 1h3V7h-3V4h-1z"
})));
}
function iconText() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "25",
height: "25",
viewBox: "0 0 25 25"
}, h("path", {
d: "M4.5 7h13a.5.5 0 1 1 0 1h-13a.5.5 0 0 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h10a.5.5 0 1 1 0 1h-10a.5.5 0 1 1 0-1z",
fill: "#5A5E69",
fillRule: "nonzero"
}));
}
module.exports = function getIconByMime(fileType) {
var defaultChoice = {
color: '#838999',
icon: iconFile()
};
if (!fileType) return defaultChoice;
var fileTypeGeneral = fileType.split('/')[0];
var fileTypeSpecific = fileType.split('/')[1]; // Text
if (fileTypeGeneral === 'text') {
return {
color: '#5a5e69',
icon: iconText()
};
} // Image
if (fileTypeGeneral === 'image') {
return {
color: '#686de0',
icon: iconImage()
};
} // Audio
if (fileTypeGeneral === 'audio') {
return {
color: '#068dbb',
icon: iconAudio()
};
} // Video
if (fileTypeGeneral === 'video') {
return {
color: '#19af67',
icon: iconVideo()
};
} // PDF
if (fileTypeGeneral === 'application' && fileTypeSpecific === 'pdf') {
return {
color: '#e25149',
icon: iconPDF()
};
} // Archive
var archiveTypes = ['zip', 'x-7z-compressed', 'x-rar-compressed', 'x-tar', 'x-gzip', 'x-apple-diskimage'];
if (fileTypeGeneral === 'application' && archiveTypes.indexOf(fileTypeSpecific) !== -1) {
return {
color: '#00C469',
icon: iconArchive()
};
}
return defaultChoice;
};
},{"preact":105}],103:[function(require,module,exports){
// ignore drop/paste events if they are not in input or textarea —
// otherwise when Url plugin adds drop/paste listeners to this.el,
// draging UI elements or pasting anything into any field triggers those events —
// Url treats them as URLs that need to be imported
function ignoreEvent(ev) {
var tagName = ev.target.tagName;
if (tagName === 'INPUT' || tagName === 'TEXTAREA') {
ev.stopPropagation();
return;
}
ev.preventDefault();
ev.stopPropagation();
}
module.exports = ignoreEvent;
},{}],104:[function(require,module,exports){
var toArray = require('@uppy/utils/lib/toArray');
var getActiveOverlayEl = require('./getActiveOverlayEl');
var FOCUSABLE_ELEMENTS = require('@uppy/utils/lib/FOCUSABLE_ELEMENTS');
function focusOnFirstNode(event, nodes) {
var node = nodes[0];
if (node) {
node.focus();
event.preventDefault();
}
}
function focusOnLastNode(event, nodes) {
var node = nodes[nodes.length - 1];
if (node) {
node.focus();
event.preventDefault();
}
} // ___Why not just use (focusedItemIndex === -1)?
// Firefox thinks <ul> is focusable, but we don't have <ul>s in our FOCUSABLE_ELEMENTS. Which means that if we tab into the <ul>, code will think that we are not in the active overlay, and we should focusOnFirstNode() of the currently active overlay!
// [Practical check] if we use (focusedItemIndex === -1), instagram provider in firefox will never get focus on its pics in the <ul>.
function isFocusInOverlay(activeOverlayEl) {
return activeOverlayEl.contains(document.activeElement);
}
function trapFocus(event, activeOverlayType, dashboardEl) {
var activeOverlayEl = getActiveOverlayEl(dashboardEl, activeOverlayType);
var focusableNodes = toArray(activeOverlayEl.querySelectorAll(FOCUSABLE_ELEMENTS));
var focusedItemIndex = focusableNodes.indexOf(document.activeElement); // If we pressed tab, and focus is not yet within the current overlay - focus on the first element within the current overlay.
// This is a safety measure (for when user returns from another tab e.g.), most plugins will try to focus on some important element as it loads.
if (!isFocusInOverlay(activeOverlayEl)) {
focusOnFirstNode(event, focusableNodes); // If we pressed shift + tab, and we're on the first element of a modal
} else if (event.shiftKey && focusedItemIndex === 0) {
focusOnLastNode(event, focusableNodes); // If we pressed tab, and we're on the last element of the modal
} else if (!event.shiftKey && focusedItemIndex === focusableNodes.length - 1) {
focusOnFirstNode(event, focusableNodes);
}
}
module.exports = {
// Traps focus inside of the currently open overlay (e.g. Dashboard, or e.g. Instagram), never lets focus disappear from the modal.
forModal: function forModal(event, activeOverlayType, dashboardEl) {
trapFocus(event, activeOverlayType, dashboardEl);
},
// Traps focus inside of the currently open overlay, unless overlay is null - then let the user tab away.
forInline: function forInline(event, activeOverlayType, dashboardEl) {
// ___When we're in the bare 'Drop files here, paste, browse or import from' screen
if (activeOverlayType === null) {// Do nothing and let the browser handle it, user can tab away from Uppy to other elements on the page
// ___When there is some overlay with 'Done' button
} else {
// Trap the focus inside this overlay!
// User can close the overlay (click 'Done') if they want to travel away from Uppy.
trapFocus(event, activeOverlayType, dashboardEl);
}
}
};
},{"./getActiveOverlayEl":101,"@uppy/utils/lib/FOCUSABLE_ELEMENTS":214,"@uppy/utils/lib/toArray":252}],105:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],106:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var toArray = require('@uppy/utils/lib/toArray');
var isDragDropSupported = require('@uppy/utils/lib/isDragDropSupported');
var getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles');
var _require2 = require('preact'),
h = _require2.h;
/**
* Drag & Drop plugin
*
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(DragDrop, _Plugin);
// eslint-disable-next-line global-require
function DragDrop(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'acquirer';
_this.id = _this.opts.id || 'DragDrop';
_this.title = 'Drag & Drop';
_this.defaultLocale = {
strings: {
dropHereOr: 'Drop files here or %{browse}',
browse: 'browse'
}
}; // Default options
var defaultOpts = {
target: null,
inputName: 'files[]',
width: '100%',
height: '100%',
note: null
}; // Merge default options with the ones set by user
_this.opts = _extends({}, defaultOpts, opts); // Check for browser dragDrop support
_this.isDragDropSupported = isDragDropSupported();
_this.removeDragOverClassTimeout = null;
_this.i18nInit(); // Bind `this` to class methods
_this.onInputChange = _this.onInputChange.bind(_assertThisInitialized(_this));
_this.handleDragOver = _this.handleDragOver.bind(_assertThisInitialized(_this));
_this.handleDragLeave = _this.handleDragLeave.bind(_assertThisInitialized(_this));
_this.handleDrop = _this.handleDrop.bind(_assertThisInitialized(_this));
_this.addFiles = _this.addFiles.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = DragDrop.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.addFiles = function addFiles(files) {
var _this2 = this;
var descriptors = files.map(function (file) {
return {
source: _this2.id,
name: file.name,
type: file.type,
data: file,
meta: {
// path of the file relative to the ancestor directory the user selected.
// e.g. 'docs/Old Prague/airbnb.pdf'
relativePath: file.relativePath || null
}
};
});
try {
this.uppy.addFiles(descriptors);
} catch (err) {
this.uppy.log(err);
}
};
_proto.onInputChange = function onInputChange(event) {
this.uppy.log('[DragDrop] Files selected through input');
var files = toArray(event.target.files);
this.addFiles(files); // We clear the input after a file is selected, because otherwise
// change event is not fired in Chrome and Safari when a file
// with the same name is selected.
// ___Why not use value="" on <input/> instead?
// Because if we use that method of clearing the input,
// Chrome will not trigger change if we drop the same file twice (Issue #768).
// eslint-disable-next-line no-param-reassign
event.target.value = null;
};
_proto.handleDrop = function handleDrop(event) {
var _this3 = this;
if (this.opts.onDrop) this.opts.onDrop(event);
event.preventDefault();
event.stopPropagation();
clearTimeout(this.removeDragOverClassTimeout); // 2. Remove dragover class
this.setPluginState({
isDraggingOver: false
}); // 3. Add all dropped files
this.uppy.log('[DragDrop] Files were dropped');
var logDropError = function logDropError(error) {
_this3.uppy.log(error, 'error');
};
getDroppedFiles(event.dataTransfer, {
logDropError: logDropError
}).then(function (files) {
return _this3.addFiles(files);
});
};
_proto.handleDragOver = function handleDragOver(event) {
if (this.opts.onDragOver) this.opts.onDragOver(event);
event.preventDefault();
event.stopPropagation(); // 1. Add a small (+) icon on drop
// (and prevent browsers from interpreting this as files being _moved_ into the browser
// https://github.com/transloadit/uppy/issues/1978)
//
// eslint-disable-next-line no-param-reassign
event.dataTransfer.dropEffect = 'copy';
clearTimeout(this.removeDragOverClassTimeout);
this.setPluginState({
isDraggingOver: true
});
};
_proto.handleDragLeave = function handleDragLeave(event) {
var _this4 = this;
if (this.opts.onDragLeave) this.opts.onDragLeave(event);
event.preventDefault();
event.stopPropagation();
clearTimeout(this.removeDragOverClassTimeout); // Timeout against flickering, this solution is taken from drag-drop library.
// Solution with 'pointer-events: none' didn't work across browsers.
this.removeDragOverClassTimeout = setTimeout(function () {
_this4.setPluginState({
isDraggingOver: false
});
}, 50);
};
_proto.renderHiddenFileInput = function renderHiddenFileInput() {
var _this5 = this;
var restrictions = this.uppy.opts.restrictions;
return h("input", {
className: "uppy-DragDrop-input",
type: "file",
hidden: true,
ref: function ref(_ref) {
_this5.fileInputRef = _ref;
},
name: this.opts.inputName,
multiple: restrictions.maxNumberOfFiles !== 1,
accept: restrictions.allowedFileTypes,
onChange: this.onInputChange
});
};
DragDrop.renderArrowSvg = function renderArrowSvg() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon uppy-DragDrop-arrow",
width: "16",
height: "16",
viewBox: "0 0 16 16"
}, h("path", {
d: "M11 10V0H5v10H2l6 6 6-6h-3zm0 0",
fillRule: "evenodd"
}));
};
_proto.renderLabel = function renderLabel() {
return h("div", {
className: "uppy-DragDrop-label"
}, this.i18nArray('dropHereOr', {
browse: h("span", {
className: "uppy-DragDrop-browse"
}, this.i18n('browse'))
}));
};
_proto.renderNote = function renderNote() {
return h("span", {
className: "uppy-DragDrop-note"
}, this.opts.note);
};
_proto.render = function render() {
var _this6 = this;
var dragDropClass = "uppy-Root\n uppy-u-reset\n uppy-DragDrop-container\n " + (this.isDragDropSupported ? 'uppy-DragDrop--isDragDropSupported' : '') + "\n " + (this.getPluginState().isDraggingOver ? 'uppy-DragDrop--isDraggingOver' : '') + "\n ";
var dragDropStyle = {
width: this.opts.width,
height: this.opts.height
};
return h("button", {
type: "button",
className: dragDropClass,
style: dragDropStyle,
onClick: function onClick() {
return _this6.fileInputRef.click();
},
onDragOver: this.handleDragOver,
onDragLeave: this.handleDragLeave,
onDrop: this.handleDrop
}, this.renderHiddenFileInput(), h("div", {
className: "uppy-DragDrop-inner"
}, DragDrop.renderArrowSvg(), this.renderLabel(), this.renderNote()));
};
_proto.install = function install() {
var target = this.opts.target;
this.setPluginState({
isDraggingOver: false
});
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.unmount();
};
return DragDrop;
}(Plugin), _class.VERSION = "1.4.31", _temp);
},{"@uppy/core":78,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/getDroppedFiles":229,"@uppy/utils/lib/isDragDropSupported":243,"@uppy/utils/lib/toArray":252,"preact":107}],107:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],108:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles');
var toArray = require('@uppy/utils/lib/toArray');
/**
* Drop Target plugin
*
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(DropTarget, _Plugin);
function DropTarget(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.addFiles = function (files) {
var descriptors = files.map(function (file) {
return {
source: _this.id,
name: file.name,
type: file.type,
data: file,
meta: {
// path of the file relative to the ancestor directory the user selected.
// e.g. 'docs/Old Prague/airbnb.pdf'
relativePath: file.relativePath || null
}
};
});
try {
_this.uppy.addFiles(descriptors);
} catch (err) {
_this.uppy.log(err);
}
};
_this.handleDrop = function (event) {
event.preventDefault();
event.stopPropagation();
clearTimeout(_this.removeDragOverClassTimeout); // 2. Remove dragover class
event.currentTarget.classList.remove('uppy-is-drag-over');
_this.setPluginState({
isDraggingOver: false
}); // 3. Add all dropped files
_this.uppy.log('[DropTarget] Files were dropped');
var logDropError = function logDropError(error) {
_this.uppy.log(error, 'error');
};
getDroppedFiles(event.dataTransfer, {
logDropError: logDropError
}).then(function (files) {
return _this.addFiles(files);
});
};
_this.handleDragOver = function (event) {
event.preventDefault();
event.stopPropagation(); // 1. Add a small (+) icon on drop
// (and prevent browsers from interpreting this as files being _moved_ into the browser,
// https://github.com/transloadit/uppy/issues/1978)
event.dataTransfer.dropEffect = 'copy';
clearTimeout(_this.removeDragOverClassTimeout);
event.currentTarget.classList.add('uppy-is-drag-over');
_this.setPluginState({
isDraggingOver: true
});
};
_this.handleDragLeave = function (event) {
event.preventDefault();
event.stopPropagation();
var currentTarget = event.currentTarget;
clearTimeout(_this.removeDragOverClassTimeout); // Timeout against flickering, this solution is taken from drag-drop library.
// Solution with 'pointer-events: none' didn't work across browsers.
_this.removeDragOverClassTimeout = setTimeout(function () {
currentTarget.classList.remove('uppy-is-drag-over');
_this.setPluginState({
isDraggingOver: false
});
}, 50);
};
_this.addListeners = function () {
var target = _this.opts.target;
if (target instanceof Element) {
_this.nodes = [target];
} else if (typeof target === 'string') {
_this.nodes = toArray(document.querySelectorAll(target));
}
if (!_this.nodes && !_this.nodes.length > 0) {
throw new Error("\"" + target + "\" does not match any HTML elements");
}
_this.nodes.forEach(function (node) {
node.addEventListener('dragover', _this.handleDragOver, false);
node.addEventListener('dragleave', _this.handleDragLeave, false);
node.addEventListener('drop', _this.handleDrop, false);
});
};
_this.removeListeners = function () {
if (_this.nodes) {
_this.nodes.forEach(function (node) {
node.removeEventListener('dragover', _this.handleDragOver, false);
node.removeEventListener('dragleave', _this.handleDragLeave, false);
node.removeEventListener('drop', _this.handleDrop, false);
});
}
};
_this.type = 'acquirer';
_this.id = _this.opts.id || 'DropTarget';
_this.title = 'Drop Target'; // Default options
var defaultOpts = {
target: null
}; // Merge default options with the ones set by user
_this.opts = _extends({}, defaultOpts, opts);
_this.removeDragOverClassTimeout = null;
return _this;
}
var _proto = DropTarget.prototype;
_proto.install = function install() {
this.setPluginState({
isDraggingOver: false
});
this.addListeners();
};
_proto.uninstall = function uninstall() {
this.removeListeners();
};
return DropTarget;
}(Plugin), _class.VERSION = "0.2.4", _temp);
},{"@uppy/core":78,"@uppy/utils/lib/getDroppedFiles":229,"@uppy/utils/lib/toArray":252}],109:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider;
var _require3 = require('@uppy/provider-views'),
ProviderViews = _require3.ProviderViews;
var _require4 = require('preact'),
h = _require4.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Dropbox, _Plugin);
function Dropbox(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'Dropbox';
Provider.initPlugin(_assertThisInitialized(_this), opts);
_this.title = _this.opts.title || 'Dropbox';
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#0D2481",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M11 8l5 3.185-5 3.186-5-3.186L11 8zm10 0l5 3.185-5 3.186-5-3.186L21 8zM6 17.556l5-3.185 5 3.185-5 3.186-5-3.186zm15-3.185l5 3.185-5 3.186-5-3.186 5-3.185zm-10 7.432l5-3.185 5 3.185-5 3.186-5-3.186z",
fill: "#FFF",
fillRule: "nonzero"
})));
};
_this.provider = new Provider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionKeysParams: _this.opts.companionKeysParams,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'dropbox',
pluginId: _this.id
});
_this.onFirstRender = _this.onFirstRender.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Dropbox.prototype;
_proto.install = function install() {
this.view = new ProviderViews(this, {
provider: this.provider
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.view.tearDown();
this.unmount();
};
_proto.onFirstRender = function onFirstRender() {
return Promise.all([this.provider.fetchPreAuthToken(), this.view.getFolder()]);
};
_proto.render = function render(state) {
return this.view.render(state);
};
return Dropbox;
}(Plugin), _class.VERSION = "1.5.2", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/provider-views":155,"preact":110}],110:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],111:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider;
var _require3 = require('@uppy/provider-views'),
ProviderViews = _require3.ProviderViews;
var _require4 = require('preact'),
h = _require4.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Facebook, _Plugin);
function Facebook(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'Facebook';
Provider.initPlugin(_assertThisInitialized(_this), opts);
_this.title = _this.opts.title || 'Facebook';
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
width: "32",
height: "32",
rx: "16",
fill: "#3C5A99"
}), h("path", {
d: "M17.842 26v-8.667h2.653l.398-3.377h-3.051v-2.157c0-.978.248-1.644 1.527-1.644H21V7.132A19.914 19.914 0 0 0 18.623 7c-2.352 0-3.963 1.574-3.963 4.465v2.49H12v3.378h2.66V26h3.182z",
fill: "#FFF",
fillRule: "nonzero"
})));
};
_this.provider = new Provider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionKeysParams: _this.opts.companionKeysParams,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'facebook',
pluginId: _this.id
});
_this.onFirstRender = _this.onFirstRender.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Facebook.prototype;
_proto.install = function install() {
this.view = new ProviderViews(this, {
provider: this.provider
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.view.tearDown();
this.unmount();
};
_proto.onFirstRender = function onFirstRender() {
return Promise.all([this.provider.fetchPreAuthToken(), this.view.getFolder()]);
};
_proto.render = function render(state) {
var viewOptions = {};
if (this.getPluginState().files.length && !this.getPluginState().folders.length) {
viewOptions.viewType = 'grid';
viewOptions.showFilter = false;
viewOptions.showTitles = false;
}
return this.view.render(state, viewOptions);
};
return Facebook;
}(Plugin), _class.VERSION = "1.2.2", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/provider-views":155,"preact":112}],112:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],113:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var toArray = require('@uppy/utils/lib/toArray');
var Translator = require('@uppy/utils/lib/Translator');
var _require2 = require('preact'),
h = _require2.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(FileInput, _Plugin);
function FileInput(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'FileInput';
_this.title = 'File Input';
_this.type = 'acquirer';
_this.defaultLocale = {
strings: {
// The same key is used for the same purpose by @uppy/robodog's `form()` API, but our
// locale pack scripts can't access it in Robodog. If it is updated here, it should
// also be updated there!
chooseFiles: 'Choose files'
}
}; // Default options
var defaultOptions = {
target: null,
pretty: true,
inputName: 'files[]'
}; // Merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this.render = _this.render.bind(_assertThisInitialized(_this));
_this.handleInputChange = _this.handleInputChange.bind(_assertThisInitialized(_this));
_this.handleClick = _this.handleClick.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = FileInput.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.addFiles = function addFiles(files) {
var _this2 = this;
var descriptors = files.map(function (file) {
return {
source: _this2.id,
name: file.name,
type: file.type,
data: file
};
});
try {
this.uppy.addFiles(descriptors);
} catch (err) {
this.uppy.log(err);
}
};
_proto.handleInputChange = function handleInputChange(event) {
this.uppy.log('[FileInput] Something selected through input...');
var files = toArray(event.target.files);
this.addFiles(files); // We clear the input after a file is selected, because otherwise
// change event is not fired in Chrome and Safari when a file
// with the same name is selected.
// ___Why not use value="" on <input/> instead?
// Because if we use that method of clearing the input,
// Chrome will not trigger change if we drop the same file twice (Issue #768).
event.target.value = null;
};
_proto.handleClick = function handleClick(ev) {
this.input.click();
};
_proto.render = function render(state) {
var _this3 = this;
/* http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/ */
var hiddenInputStyle = {
width: '0.1px',
height: '0.1px',
opacity: 0,
overflow: 'hidden',
position: 'absolute',
zIndex: -1
};
var restrictions = this.uppy.opts.restrictions;
var accept = restrictions.allowedFileTypes ? restrictions.allowedFileTypes.join(',') : null;
return h("div", {
className: "uppy-Root uppy-FileInput-container"
}, h("input", {
className: "uppy-FileInput-input",
style: this.opts.pretty && hiddenInputStyle,
type: "file",
name: this.opts.inputName,
onChange: this.handleInputChange,
multiple: restrictions.maxNumberOfFiles !== 1,
accept: accept,
ref: function ref(input) {
_this3.input = input;
}
}), this.opts.pretty && h("button", {
className: "uppy-FileInput-btn",
type: "button",
onClick: this.handleClick
}, this.i18n('chooseFiles')));
};
_proto.install = function install() {
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.unmount();
};
return FileInput;
}(Plugin), _class.VERSION = "1.5.2", _temp);
},{"@uppy/core":78,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/toArray":252,"preact":114}],114:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],115:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var findDOMElement = require('@uppy/utils/lib/findDOMElement');
var toArray = require('@uppy/utils/lib/toArray'); // Rollup uses get-form-data's ES modules build, and rollup-plugin-commonjs automatically resolves `.default`.
// So, if we are being built using rollup, this require() won't have a `.default` property.
var getFormData = require('get-form-data').default || require('get-form-data');
/**
* Form
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Form, _Plugin);
function Form(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'acquirer';
_this.id = _this.opts.id || 'Form';
_this.title = 'Form'; // set default options
var defaultOptions = {
target: null,
resultName: 'uppyResult',
getMetaFromForm: true,
addResultToForm: true,
multipleResults: false,
submitOnSuccess: false,
triggerUploadOnSubmit: false
}; // merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, opts);
_this.handleFormSubmit = _this.handleFormSubmit.bind(_assertThisInitialized(_this));
_this.handleUploadStart = _this.handleUploadStart.bind(_assertThisInitialized(_this));
_this.handleSuccess = _this.handleSuccess.bind(_assertThisInitialized(_this));
_this.addResultToForm = _this.addResultToForm.bind(_assertThisInitialized(_this));
_this.getMetaFromForm = _this.getMetaFromForm.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Form.prototype;
_proto.handleUploadStart = function handleUploadStart() {
if (this.opts.getMetaFromForm) {
this.getMetaFromForm();
}
};
_proto.handleSuccess = function handleSuccess(result) {
if (this.opts.addResultToForm) {
this.addResultToForm(result);
}
if (this.opts.submitOnSuccess) {
this.form.submit();
}
};
_proto.handleFormSubmit = function handleFormSubmit(ev) {
var _this2 = this;
if (this.opts.triggerUploadOnSubmit) {
ev.preventDefault();
var elements = toArray(ev.target.elements);
var disabledByUppy = [];
elements.forEach(function (el) {
var isButton = el.tagName === 'BUTTON' || el.tagName === 'INPUT' && el.type === 'submit';
if (isButton && !el.disabled) {
el.disabled = true;
disabledByUppy.push(el);
}
});
this.uppy.upload().then(function () {
disabledByUppy.forEach(function (button) {
button.disabled = false;
});
}, function (err) {
disabledByUppy.forEach(function (button) {
button.disabled = false;
});
return Promise.reject(err);
}).catch(function (err) {
_this2.uppy.log(err.stack || err.message || err);
});
}
};
_proto.addResultToForm = function addResultToForm(result) {
this.uppy.log('[Form] Adding result to the original form:');
this.uppy.log(result);
var resultInput = this.form.querySelector("[name=\"" + this.opts.resultName + "\"]");
if (resultInput) {
if (this.opts.multipleResults) {
// Append new result to the previous result array.
// If the previous result is empty, or not an array,
// set it to an empty array.
var updatedResult;
try {
updatedResult = JSON.parse(resultInput.value);
} catch (err) {// Nothing, since we check for array below anyway
}
if (!Array.isArray(updatedResult)) {
updatedResult = [];
}
updatedResult.push(result);
resultInput.value = JSON.stringify(updatedResult);
} else {
// Replace existing result with the newer result on `complete` event.
// This behavior is not ideal, since you most likely want to always keep
// all results in the input. This is kept for backwards compatability until 2.0.
resultInput.value = JSON.stringify(result);
}
return;
}
resultInput = document.createElement('input');
resultInput.name = this.opts.resultName;
resultInput.type = 'hidden';
if (this.opts.multipleResults) {
// Wrap result in an array so we can have multiple results
resultInput.value = JSON.stringify([result]);
} else {
// Result is an object, kept for backwards compatability until 2.0
resultInput.value = JSON.stringify(result);
}
this.form.appendChild(resultInput);
};
_proto.getMetaFromForm = function getMetaFromForm() {
var formMeta = getFormData(this.form); // We want to exclude meta the the Form plugin itself has added
// See https://github.com/transloadit/uppy/issues/1637
delete formMeta[this.opts.resultName];
this.uppy.setMeta(formMeta);
};
_proto.install = function install() {
this.form = findDOMElement(this.opts.target);
if (!this.form || this.form.nodeName !== 'FORM') {
this.uppy.log('Form plugin requires a <form> target element passed in options to operate, none was found', 'error');
return;
}
this.form.addEventListener('submit', this.handleFormSubmit);
this.uppy.on('upload', this.handleUploadStart);
this.uppy.on('complete', this.handleSuccess);
};
_proto.uninstall = function uninstall() {
this.form.removeEventListener('submit', this.handleFormSubmit);
this.uppy.off('upload', this.handleUploadStart);
this.uppy.off('complete', this.handleSuccess);
};
return Form;
}(Plugin), _class.VERSION = "1.3.31", _temp);
},{"@uppy/core":78,"@uppy/utils/lib/findDOMElement":225,"@uppy/utils/lib/toArray":252,"get-form-data":25}],116:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var prettierBytes = require('@transloadit/prettier-bytes');
var indexedDB = typeof window !== 'undefined' && (window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB);
var isSupported = !!indexedDB;
var DB_NAME = 'uppy-blobs';
var STORE_NAME = 'files'; // maybe have a thumbnail store in the future
var DEFAULT_EXPIRY = 24 * 60 * 60 * 1000; // 24 hours
var DB_VERSION = 3; // Set default `expires` dates on existing stored blobs.
function migrateExpiration(store) {
var request = store.openCursor();
request.onsuccess = function (event) {
var cursor = event.target.result;
if (!cursor) {
return;
}
var entry = cursor.value;
entry.expires = Date.now() + DEFAULT_EXPIRY;
cursor.update(entry);
};
}
function connect(dbName) {
var request = indexedDB.open(dbName, DB_VERSION);
return new Promise(function (resolve, reject) {
request.onupgradeneeded = function (event) {
var db = event.target.result;
var transaction = event.currentTarget.transaction;
if (event.oldVersion < 2) {
// Added in v2: DB structure changed to a single shared object store
var store = db.createObjectStore(STORE_NAME, {
keyPath: 'id'
});
store.createIndex('store', 'store', {
unique: false
});
}
if (event.oldVersion < 3) {
// Added in v3
var _store = transaction.objectStore(STORE_NAME);
_store.createIndex('expires', 'expires', {
unique: false
});
migrateExpiration(_store);
}
transaction.oncomplete = function () {
resolve(db);
};
};
request.onsuccess = function (event) {
resolve(event.target.result);
};
request.onerror = reject;
});
}
function waitForRequest(request) {
return new Promise(function (resolve, reject) {
request.onsuccess = function (event) {
resolve(event.target.result);
};
request.onerror = reject;
});
}
var cleanedUp = false;
var IndexedDBStore = /*#__PURE__*/function () {
function IndexedDBStore(opts) {
var _this = this;
this.opts = _extends({
dbName: DB_NAME,
storeName: 'default',
expires: DEFAULT_EXPIRY,
// 24 hours
maxFileSize: 10 * 1024 * 1024,
// 10 MB
maxTotalSize: 300 * 1024 * 1024
}, opts);
this.name = this.opts.storeName;
var createConnection = function createConnection() {
return connect(_this.opts.dbName);
};
if (!cleanedUp) {
cleanedUp = true;
this.ready = IndexedDBStore.cleanup().then(createConnection, createConnection);
} else {
this.ready = createConnection();
}
}
var _proto = IndexedDBStore.prototype;
_proto.key = function key(fileID) {
return this.name + "!" + fileID;
}
/**
* List all file blobs currently in the store.
*/
;
_proto.list = function list() {
var _this2 = this;
return this.ready.then(function (db) {
var transaction = db.transaction([STORE_NAME], 'readonly');
var store = transaction.objectStore(STORE_NAME);
var request = store.index('store').getAll(IDBKeyRange.only(_this2.name));
return waitForRequest(request);
}).then(function (files) {
var result = {};
files.forEach(function (file) {
result[file.fileID] = file.data;
});
return result;
});
}
/**
* Get one file blob from the store.
*/
;
_proto.get = function get(fileID) {
var _this3 = this;
return this.ready.then(function (db) {
var transaction = db.transaction([STORE_NAME], 'readonly');
var request = transaction.objectStore(STORE_NAME).get(_this3.key(fileID));
return waitForRequest(request);
}).then(function (result) {
return {
id: result.data.fileID,
data: result.data.data
};
});
}
/**
* Get the total size of all stored files.
*
* @private
*/
;
_proto.getSize = function getSize() {
var _this4 = this;
return this.ready.then(function (db) {
var transaction = db.transaction([STORE_NAME], 'readonly');
var store = transaction.objectStore(STORE_NAME);
var request = store.index('store').openCursor(IDBKeyRange.only(_this4.name));
return new Promise(function (resolve, reject) {
var size = 0;
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
size += cursor.value.data.size;
cursor.continue();
} else {
resolve(size);
}
};
request.onerror = function () {
reject(new Error('Could not retrieve stored blobs size'));
};
});
});
}
/**
* Save a file in the store.
*/
;
_proto.put = function put(file) {
var _this5 = this;
if (file.data.size > this.opts.maxFileSize) {
return Promise.reject(new Error('File is too big to store.'));
}
return this.getSize().then(function (size) {
if (size > _this5.opts.maxTotalSize) {
return Promise.reject(new Error('No space left'));
}
return _this5.ready;
}).then(function (db) {
var transaction = db.transaction([STORE_NAME], 'readwrite');
var request = transaction.objectStore(STORE_NAME).add({
id: _this5.key(file.id),
fileID: file.id,
store: _this5.name,
expires: Date.now() + _this5.opts.expires,
data: file.data
});
return waitForRequest(request);
});
}
/**
* Delete a file blob from the store.
*/
;
_proto.delete = function _delete(fileID) {
var _this6 = this;
return this.ready.then(function (db) {
var transaction = db.transaction([STORE_NAME], 'readwrite');
var request = transaction.objectStore(STORE_NAME).delete(_this6.key(fileID));
return waitForRequest(request);
});
}
/**
* Delete all stored blobs that have an expiry date that is before Date.now().
* This is a static method because it deletes expired blobs from _all_ Uppy instances.
*/
;
IndexedDBStore.cleanup = function cleanup() {
return connect(DB_NAME).then(function (db) {
var transaction = db.transaction([STORE_NAME], 'readwrite');
var store = transaction.objectStore(STORE_NAME);
var request = store.index('expires').openCursor(IDBKeyRange.upperBound(Date.now()));
return new Promise(function (resolve, reject) {
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
var entry = cursor.value;
console.log('[IndexedDBStore] Deleting record', entry.fileID, 'of size', prettierBytes(entry.data.size), '- expired on', new Date(entry.expires));
cursor.delete(); // Ignoring return value … it's not terrible if this goes wrong.
cursor.continue();
} else {
resolve(db);
}
};
request.onerror = reject;
});
}).then(function (db) {
db.close();
});
};
return IndexedDBStore;
}();
IndexedDBStore.isSupported = isSupported;
module.exports = IndexedDBStore;
},{"@transloadit/prettier-bytes":1}],117:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/**
* Get uppy instance IDs for which state is stored.
*/
function findUppyInstances() {
var instances = [];
for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
if (/^uppyState:/.test(key)) {
instances.push(key.slice('uppyState:'.length));
}
}
return instances;
}
/**
* Try to JSON-parse a string, return null on failure.
*/
function maybeParse(str) {
try {
return JSON.parse(str);
} catch (err) {
return null;
}
}
var cleanedUp = false;
module.exports = /*#__PURE__*/function () {
function MetaDataStore(opts) {
this.opts = _extends({
expires: 24 * 60 * 60 * 1000
}, opts);
this.name = "uppyState:" + opts.storeName;
if (!cleanedUp) {
cleanedUp = true;
MetaDataStore.cleanup();
}
}
/**
*
*/
var _proto = MetaDataStore.prototype;
_proto.load = function load() {
var savedState = localStorage.getItem(this.name);
if (!savedState) return null;
var data = maybeParse(savedState);
if (!data) return null; // Upgrade pre-0.20.0 uppyState: it used to be just a flat object,
// without `expires`.
if (!data.metadata) {
this.save(data);
return data;
}
return data.metadata;
};
_proto.save = function save(metadata) {
var expires = Date.now() + this.opts.expires;
var state = JSON.stringify({
metadata: metadata,
expires: expires
});
localStorage.setItem(this.name, state);
}
/**
* Remove all expired state.
*/
;
MetaDataStore.cleanup = function cleanup(instanceID) {
if (instanceID) {
localStorage.removeItem("uppyState:" + instanceID);
return;
}
var instanceIDs = findUppyInstances();
var now = Date.now();
instanceIDs.forEach(function (id) {
var data = localStorage.getItem("uppyState:" + id);
if (!data) return null;
var obj = maybeParse(data);
if (!obj) return null;
if (obj.expires && obj.expires < now) {
localStorage.removeItem("uppyState:" + id);
}
});
};
return MetaDataStore;
}();
},{}],118:[function(require,module,exports){
/*eslint-disable */
var isSupported = typeof navigator !== 'undefined' && 'serviceWorker' in navigator;
function waitForServiceWorker() {
return new Promise(function (resolve, reject) {
if (!isSupported) {
reject(new Error('Unsupported'));
} else if (navigator.serviceWorker.controller) {
// A serviceWorker is already registered and active.
resolve();
} else {
navigator.serviceWorker.addEventListener('controllerchange', function () {
resolve();
});
}
});
}
var ServiceWorkerStore = /*#__PURE__*/function () {
function ServiceWorkerStore(opts) {
this.ready = waitForServiceWorker();
this.name = opts.storeName;
}
var _proto = ServiceWorkerStore.prototype;
_proto.list = function list() {
var _this = this;
var defer = {};
var promise = new Promise(function (resolve, reject) {
defer.resolve = resolve;
defer.reject = reject;
});
console.log('Loading stored blobs from Service Worker');
var onMessage = function onMessage(event) {
if (event.data.store !== _this.name) {
return;
}
switch (event.data.type) {
case 'uppy/ALL_FILES':
defer.resolve(event.data.files);
navigator.serviceWorker.removeEventListener('message', onMessage);
break;
}
};
this.ready.then(function () {
navigator.serviceWorker.addEventListener('message', onMessage);
navigator.serviceWorker.controller.postMessage({
type: 'uppy/GET_FILES',
store: _this.name
});
});
return promise;
};
_proto.put = function put(file) {
var _this2 = this;
return this.ready.then(function () {
navigator.serviceWorker.controller.postMessage({
type: 'uppy/ADD_FILE',
store: _this2.name,
file: file
});
});
};
_proto.delete = function _delete(fileID) {
var _this3 = this;
return this.ready.then(function () {
navigator.serviceWorker.controller.postMessage({
type: 'uppy/REMOVE_FILE',
store: _this3.name,
fileID: fileID
});
});
};
return ServiceWorkerStore;
}();
ServiceWorkerStore.isSupported = isSupported;
module.exports = ServiceWorkerStore;
},{}],119:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var throttle = require('lodash.throttle');
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var ServiceWorkerStore = require('./ServiceWorkerStore');
var IndexedDBStore = require('./IndexedDBStore');
var MetaDataStore = require('./MetaDataStore');
/**
* The GoldenRetriever plugin — restores selected files and resumes uploads
* after a closed tab or a browser crash!
*
* Uses localStorage, IndexedDB and ServiceWorker to do its magic, read more:
* https://uppy.io/blog/2017/07/golden-retriever/
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(GoldenRetriever, _Plugin);
function GoldenRetriever(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.addBlobToStores = function (file) {
if (file.isRemote) return;
if (_this.ServiceWorkerStore) {
_this.ServiceWorkerStore.put(file).catch(function (err) {
_this.uppy.log('[GoldenRetriever] Could not store file', 'warning');
_this.uppy.log(err);
});
}
_this.IndexedDBStore.put(file).catch(function (err) {
_this.uppy.log('[GoldenRetriever] Could not store file', 'warning');
_this.uppy.log(err);
});
};
_this.removeBlobFromStores = function (file) {
if (_this.ServiceWorkerStore) {
_this.ServiceWorkerStore.delete(file.id).catch(function (err) {
_this.uppy.log('[GoldenRetriever] Failed to remove file', 'warning');
_this.uppy.log(err);
});
}
_this.IndexedDBStore.delete(file.id).catch(function (err) {
_this.uppy.log('[GoldenRetriever] Failed to remove file', 'warning');
_this.uppy.log(err);
});
};
_this.replaceBlobInStores = function (file) {
_this.removeBlobFromStores(file);
_this.addBlobToStores(file);
};
_this.handleRestoreConfirmed = function () {
_this.uppy.log('[GoldenRetriever] Restore confirmed, proceeding...'); // start all uploads again when file blobs are restored
var _this$uppy$getState = _this.uppy.getState(),
currentUploads = _this$uppy$getState.currentUploads;
if (currentUploads) {
Object.keys(currentUploads).forEach(function (uploadId) {
_this.uppy.restore(uploadId, currentUploads[uploadId]);
});
_this.uppy.resumeAll();
}
_this.uppy.upload();
_this.uppy.setState({
recoveredState: null
});
};
_this.abortRestore = function () {
_this.uppy.log('[GoldenRetriever] Aborting restore...');
var fileIDs = Object.keys(_this.uppy.getState().files);
_this.deleteBlobs(fileIDs).then(function () {
_this.uppy.log("[GoldenRetriever] Removed " + fileIDs.length + " files");
}).catch(function (err) {
_this.uppy.log("[GoldenRetriever] Could not remove " + fileIDs.length + " files", 'warning');
_this.uppy.log(err);
});
_this.uppy.cancelAll();
_this.uppy.setState({
recoveredState: null
});
MetaDataStore.cleanup(_this.uppy.opts.id);
};
_this.handleComplete = function (_ref) {
var successful = _ref.successful;
var fileIDs = successful.map(function (file) {
return file.id;
});
_this.deleteBlobs(fileIDs).then(function () {
_this.uppy.log("[GoldenRetriever] Removed " + successful.length + " files that finished uploading");
}).catch(function (err) {
_this.uppy.log("[GoldenRetriever] Could not remove " + successful.length + " files that finished uploading", 'warning');
_this.uppy.log(err);
});
_this.uppy.setState({
recoveredState: null
});
MetaDataStore.cleanup(_this.uppy.opts.id);
};
_this.restoreBlobs = function () {
if (_this.uppy.getFiles().length > 0) {
Promise.all([_this.loadFileBlobsFromServiceWorker(), _this.loadFileBlobsFromIndexedDB()]).then(function (resultingArrayOfObjects) {
var blobs = _extends({}, resultingArrayOfObjects[0], resultingArrayOfObjects[1]);
_this.onBlobsLoaded(blobs);
});
} else {
_this.uppy.log('[GoldenRetriever] No files need to be loaded, only restoring processing state...');
_this.onBlobsLoaded([]);
}
};
_this.type = 'debugger';
_this.id = _this.opts.id || 'GoldenRetriever';
_this.title = 'Golden Retriever';
var defaultOptions = {
expires: 24 * 60 * 60 * 1000,
// 24 hours
serviceWorker: false
};
_this.opts = _extends({}, defaultOptions, opts);
_this.MetaDataStore = new MetaDataStore({
expires: _this.opts.expires,
storeName: uppy.getID()
});
_this.ServiceWorkerStore = null;
if (_this.opts.serviceWorker) {
_this.ServiceWorkerStore = new ServiceWorkerStore({
storeName: uppy.getID()
});
}
_this.IndexedDBStore = new IndexedDBStore(_extends({
expires: _this.opts.expires
}, _this.opts.indexedDB || {}, {
storeName: uppy.getID()
}));
_this.saveFilesStateToLocalStorage = throttle(_this.saveFilesStateToLocalStorage.bind(_assertThisInitialized(_this)), 500, {
leading: true,
trailing: true
});
_this.restoreState = _this.restoreState.bind(_assertThisInitialized(_this));
_this.loadFileBlobsFromServiceWorker = _this.loadFileBlobsFromServiceWorker.bind(_assertThisInitialized(_this));
_this.loadFileBlobsFromIndexedDB = _this.loadFileBlobsFromIndexedDB.bind(_assertThisInitialized(_this));
_this.onBlobsLoaded = _this.onBlobsLoaded.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = GoldenRetriever.prototype;
_proto.restoreState = function restoreState() {
var savedState = this.MetaDataStore.load();
if (savedState) {
this.uppy.log('[GoldenRetriever] Recovered some state from Local Storage');
this.uppy.setState({
currentUploads: savedState.currentUploads || {},
files: savedState.files || {},
recoveredState: savedState
});
this.savedPluginData = savedState.pluginData;
}
}
/**
* Get file objects that are currently waiting: they've been selected,
* but aren't yet being uploaded.
*/
;
_proto.getWaitingFiles = function getWaitingFiles() {
var waitingFiles = {};
this.uppy.getFiles().forEach(function (file) {
if (!file.progress || !file.progress.uploadStarted) {
waitingFiles[file.id] = file;
}
});
return waitingFiles;
}
/**
* Get file objects that are currently being uploaded. If a file has finished
* uploading, but the other files in the same batch have not, the finished
* file is also returned.
*/
;
_proto.getUploadingFiles = function getUploadingFiles() {
var _this2 = this;
var uploadingFiles = {};
var _this$uppy$getState2 = this.uppy.getState(),
currentUploads = _this$uppy$getState2.currentUploads;
if (currentUploads) {
var uploadIDs = Object.keys(currentUploads);
uploadIDs.forEach(function (uploadID) {
var filesInUpload = currentUploads[uploadID].fileIDs;
filesInUpload.forEach(function (fileID) {
uploadingFiles[fileID] = _this2.uppy.getFile(fileID);
});
});
}
return uploadingFiles;
};
_proto.saveFilesStateToLocalStorage = function saveFilesStateToLocalStorage() {
var filesToSave = _extends({}, this.getWaitingFiles(), this.getUploadingFiles()); // If all files have been removed by the user, clear recovery state
if (Object.keys(filesToSave).length === 0) {
this.uppy.setState({
recoveredState: null
});
MetaDataStore.cleanup(this.uppy.opts.id);
return;
} // We dont’t need to store file.data on local files, because the actual blob will be restored later,
// and we want to avoid having weird properties in the serialized object.
// Also adding file.isRestored to all files, since they will be restored from local storage
var filesToSaveWithoutData = {};
Object.keys(filesToSave).forEach(function (file) {
if (filesToSave[file].isRemote) {
filesToSaveWithoutData[file] = _extends({}, filesToSave[file], {
isRestored: true
});
} else {
filesToSaveWithoutData[file] = _extends({}, filesToSave[file], {
isRestored: true,
data: null,
preview: null
});
}
});
var pluginData = {}; // TODO Find a better way to do this?
// Other plugins can attach a restore:get-data listener that receives this callback.
// Plugins can then use this callback (sync) to provide data to be stored.
this.uppy.emit('restore:get-data', function (data) {
_extends(pluginData, data);
});
var _this$uppy$getState3 = this.uppy.getState(),
currentUploads = _this$uppy$getState3.currentUploads;
this.MetaDataStore.save({
currentUploads: currentUploads,
files: filesToSaveWithoutData,
pluginData: pluginData
});
};
_proto.loadFileBlobsFromServiceWorker = function loadFileBlobsFromServiceWorker() {
var _this3 = this;
if (!this.ServiceWorkerStore) {
return Promise.resolve({});
}
return this.ServiceWorkerStore.list().then(function (blobs) {
var files = _this3.uppy.getFiles();
var localFilesOnly = files.filter(function (file) {
// maybe && !file.progress.uploadComplete
return !file.isRemote;
});
var numberOfFilesRecovered = Object.keys(blobs).length;
var numberOfFilesTryingToRecover = localFilesOnly.length;
if (numberOfFilesRecovered === numberOfFilesTryingToRecover) {
_this3.uppy.log("[GoldenRetriever] Successfully recovered " + numberOfFilesRecovered + " blobs from Service Worker!");
return blobs;
}
_this3.uppy.log('[GoldenRetriever] No blobs found in Service Worker, trying IndexedDB now...');
return {};
}).catch(function (err) {
_this3.uppy.log('[GoldenRetriever] Failed to recover blobs from Service Worker', 'warning');
_this3.uppy.log(err);
return {};
});
};
_proto.loadFileBlobsFromIndexedDB = function loadFileBlobsFromIndexedDB() {
var _this4 = this;
return this.IndexedDBStore.list().then(function (blobs) {
var numberOfFilesRecovered = Object.keys(blobs).length;
if (numberOfFilesRecovered > 0) {
_this4.uppy.log("[GoldenRetriever] Successfully recovered " + numberOfFilesRecovered + " blobs from IndexedDB!");
return blobs;
}
_this4.uppy.log('[GoldenRetriever] No blobs found in IndexedDB');
return {};
}).catch(function (err) {
_this4.uppy.log('[GoldenRetriever] Failed to recover blobs from IndexedDB', 'warning');
_this4.uppy.log(err);
return {};
});
};
_proto.onBlobsLoaded = function onBlobsLoaded(blobs) {
var _this5 = this;
var obsoleteBlobs = [];
var updatedFiles = _extends({}, this.uppy.getState().files); // Loop through blobs that we can restore, add blobs to file objects
Object.keys(blobs).forEach(function (fileID) {
var originalFile = _this5.uppy.getFile(fileID);
if (!originalFile) {
obsoleteBlobs.push(fileID);
return;
}
var cachedData = blobs[fileID];
var updatedFileData = {
data: cachedData,
isRestored: true,
isGhost: false
};
updatedFiles[fileID] = _extends({}, originalFile, updatedFileData);
}); // Loop through files that we can’t restore fully — we only have meta, not blobs,
// set .isGhost on them, also set isRestored to all files
Object.keys(updatedFiles).forEach(function (fileID) {
if (updatedFiles[fileID].data === null) {
updatedFiles[fileID] = _extends({}, updatedFiles[fileID], {
isGhost: true
});
}
});
this.uppy.setState({
files: updatedFiles
});
this.uppy.emit('restored', this.savedPluginData);
if (obsoleteBlobs.length) {
this.deleteBlobs(obsoleteBlobs).then(function () {
_this5.uppy.log("[GoldenRetriever] Cleaned up " + obsoleteBlobs.length + " old files");
}).catch(function (err) {
_this5.uppy.log("[GoldenRetriever] Could not clean up " + obsoleteBlobs.length + " old files", 'warning');
_this5.uppy.log(err);
});
}
};
_proto.deleteBlobs = function deleteBlobs(fileIDs) {
var _this6 = this;
var promises = [];
fileIDs.forEach(function (id) {
if (_this6.ServiceWorkerStore) {
promises.push(_this6.ServiceWorkerStore.delete(id));
}
if (_this6.IndexedDBStore) {
promises.push(_this6.IndexedDBStore.delete(id));
}
});
return Promise.all(promises);
};
_proto.install = function install() {
this.restoreState();
this.restoreBlobs();
this.uppy.on('file-added', this.addBlobToStores);
this.uppy.on('file-editor:complete', this.replaceBlobInStores);
this.uppy.on('file-removed', this.removeBlobFromStores);
this.uppy.on('state-update', this.saveFilesStateToLocalStorage);
this.uppy.on('restore-confirmed', this.handleRestoreConfirmed);
this.uppy.on('restore-canceled', this.abortRestore);
this.uppy.on('complete', this.handleComplete);
};
_proto.uninstall = function uninstall() {
this.uppy.off('file-added', this.addBlobToStores);
this.uppy.off('file-editor:complete', this.replaceBlobInStores);
this.uppy.off('file-removed', this.removeBlobFromStores);
this.uppy.off('state-update', this.saveFilesStateToLocalStorage);
this.uppy.off('restore-confirmed', this.handleRestoreConfirmed);
this.uppy.off('restore-canceled', this.abortRestore);
this.uppy.off('complete', this.handleComplete);
};
return GoldenRetriever;
}(Plugin), _class.VERSION = "1.4.2", _temp);
},{"./IndexedDBStore":116,"./MetaDataStore":117,"./ServiceWorkerStore":118,"@uppy/core":78,"lodash.throttle":34}],120:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/provider-views'),
ProviderViews = _require.ProviderViews;
module.exports = /*#__PURE__*/function (_ProviderViews) {
_inheritsLoose(DriveProviderViews, _ProviderViews);
function DriveProviderViews() {
return _ProviderViews.apply(this, arguments) || this;
}
var _proto = DriveProviderViews.prototype;
_proto.toggleCheckbox = function toggleCheckbox(e, file) {
e.stopPropagation();
e.preventDefault(); // Shared Drives aren't selectable; for all else, defer to the base ProviderView.
// @todo isTeamDrive is left for backward compatibility. We should remove it in the next
// major release.
if (!file.custom.isTeamDrive && !file.custom.isSharedDrive) {
_ProviderViews.prototype.toggleCheckbox.call(this, e, file);
}
};
return DriveProviderViews;
}(ProviderViews);
},{"@uppy/provider-views":155}],121:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider;
var DriveProviderViews = require('./DriveProviderViews');
var _require3 = require('preact'),
h = _require3.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(GoogleDrive, _Plugin);
function GoogleDrive(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'GoogleDrive';
_this.title = _this.opts.title || 'Google Drive';
Provider.initPlugin(_assertThisInitialized(_this), opts);
_this.title = _this.opts.title || 'Google Drive';
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#4285F4",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M10.324 23.3l3-5.1H25l-3 5.1H10.324zM13 18.2l-3 5.1-3-5.1 5.839-9.924 2.999 5.1L13 18.2zm11.838-.276h-6L13 8h6l5.84 9.924h-.002z",
fill: "#FFF"
})));
};
_this.provider = new Provider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionKeysParams: _this.opts.companionKeysParams,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'drive',
pluginId: _this.id
});
_this.onFirstRender = _this.onFirstRender.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = GoogleDrive.prototype;
_proto.install = function install() {
this.view = new DriveProviderViews(this, {
provider: this.provider
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.view.tearDown();
this.unmount();
};
_proto.onFirstRender = function onFirstRender() {
return Promise.all([this.provider.fetchPreAuthToken(), this.view.getFolder('root', '/')]);
};
_proto.render = function render(state) {
return this.view.render(state);
};
return GoogleDrive;
}(Plugin), _class.VERSION = "1.7.2", _temp);
},{"./DriveProviderViews":120,"@uppy/companion-client":75,"@uppy/core":78,"preact":122}],122:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],123:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var Cropper = require('cropperjs');
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
module.exports = /*#__PURE__*/function (_Component) {
_inheritsLoose(Editor, _Component);
function Editor(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.granularRotateOnChange = function (ev) {
var _this$state = _this.state,
rotationAngle = _this$state.rotationAngle,
rotationDelta = _this$state.rotationDelta;
var pendingRotationDelta = Number(ev.target.value) - rotationDelta;
cancelAnimationFrame(_this.granularRotateOnInputNextFrame);
if (pendingRotationDelta !== 0) {
var pendingRotationAngle = rotationAngle + pendingRotationDelta;
_this.granularRotateOnInputNextFrame = requestAnimationFrame(function () {
_this.cropper.rotateTo(pendingRotationAngle);
});
}
};
_this.state = {
rotationAngle: 0,
rotationDelta: 0
};
return _this;
}
var _proto = Editor.prototype;
_proto.componentDidMount = function componentDidMount() {
var _this2 = this;
var _this$props = this.props,
opts = _this$props.opts,
storeCropperInstance = _this$props.storeCropperInstance;
this.cropper = new Cropper(this.imgElement, opts.cropperOptions);
storeCropperInstance(this.cropper);
if (opts.actions.granularRotate) {
this.imgElement.addEventListener('crop', function (ev) {
var rotationAngle = ev.detail.rotate;
_this2.setState({
rotationAngle: rotationAngle,
// 405 == 360 + 45
rotationDelta: (rotationAngle + 405) % 90 - 45
});
});
}
};
_proto.componentWillUnmount = function componentWillUnmount() {
this.cropper.destroy();
};
_proto.renderRevert = function renderRevert() {
var _this3 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('revert'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
_this3.cropper.reset();
_this3.cropper.setAspectRatio(0);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0z",
fill: "none"
}), h("path", {
d: "M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"
})));
};
_proto.renderRotate = function renderRotate() {
var _this4 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
onClick: function onClick() {
return _this4.cropper.rotate(-90);
},
"aria-label": this.props.i18n('rotate'),
"data-microtip-position": "top",
role: "tooltip"
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0V0zm0 0h24v24H0V0z",
fill: "none"
}), h("path", {
d: "M14 10a2 2 0 012 2v7a2 2 0 01-2 2H6a2 2 0 01-2-2v-7a2 2 0 012-2h8zm0 1.75H6a.25.25 0 00-.243.193L5.75 12v7a.25.25 0 00.193.243L6 19.25h8a.25.25 0 00.243-.193L14.25 19v-7a.25.25 0 00-.193-.243L14 11.75zM12 .76V4c2.3 0 4.61.88 6.36 2.64a8.95 8.95 0 012.634 6.025L21 13a1 1 0 01-1.993.117L19 13h-.003a6.979 6.979 0 00-2.047-4.95 6.97 6.97 0 00-4.652-2.044L12 6v3.24L7.76 5 12 .76z"
})));
};
_proto.renderGranularRotate = function renderGranularRotate() {
return h("label", {
"data-microtip-position": "top",
role: "tooltip",
"aria-label": this.state.rotationAngle + "\xBA",
className: "uppy-ImageCropper-rangeWrapper uppy-u-reset"
}, h("input", {
className: "uppy-ImageCropper-range uppy-u-reset",
type: "range",
onInput: this.granularRotateOnChange,
onChange: this.granularRotateOnChange,
value: this.state.rotationDelta,
min: "-45",
max: "44",
"aria-label": this.props.i18n('rotate')
}));
};
_proto.renderFlip = function renderFlip() {
var _this5 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('flipHorizontal'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
return _this5.cropper.scaleX(-_this5.cropper.getData().scaleX || -1);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0z",
fill: "none"
}), h("path", {
d: "M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"
})));
};
_proto.renderZoomIn = function renderZoomIn() {
var _this6 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('zoomIn'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
return _this6.cropper.zoom(0.1);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
height: "24",
viewBox: "0 0 24 24",
width: "24"
}, h("path", {
d: "M0 0h24v24H0V0z",
fill: "none"
}), h("path", {
d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
}), h("path", {
d: "M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"
})));
};
_proto.renderZoomOut = function renderZoomOut() {
var _this7 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('zoomOut'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
return _this7.cropper.zoom(-0.1);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0V0z",
fill: "none"
}), h("path", {
d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"
})));
};
_proto.renderCropSquare = function renderCropSquare() {
var _this8 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('aspectRatioSquare'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
return _this8.cropper.setAspectRatio(1);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0z",
fill: "none"
}), h("path", {
d: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
})));
};
_proto.renderCropWidescreen = function renderCropWidescreen() {
var _this9 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('aspectRatioLandscape'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
return _this9.cropper.setAspectRatio(16 / 9);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M 19,4.9999992 V 17.000001 H 4.9999998 V 6.9999992 H 19 m 0,-2 H 4.9999998 c -1.0999999,0 -1.9999999,0.9000001 -1.9999999,2 V 17.000001 c 0,1.1 0.9,2 1.9999999,2 H 19 c 1.1,0 2,-0.9 2,-2 V 6.9999992 c 0,-1.0999999 -0.9,-2 -2,-2 z"
}), h("path", {
fill: "none",
d: "M0 0h24v24H0z"
})));
};
_proto.renderCropWidescreenVertical = function renderCropWidescreenVertical() {
var _this10 = this;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn",
"aria-label": this.props.i18n('aspectRatioPortrait'),
"data-microtip-position": "top",
role: "tooltip",
onClick: function onClick() {
return _this10.cropper.setAspectRatio(9 / 16);
}
}, h("svg", {
"aria-hidden": "true",
className: "uppy-c-icon",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M 19.000001,19 H 6.999999 V 5 h 10.000002 v 14 m 2,0 V 5 c 0,-1.0999999 -0.9,-1.9999999 -2,-1.9999999 H 6.999999 c -1.1,0 -2,0.9 -2,1.9999999 v 14 c 0,1.1 0.9,2 2,2 h 10.000002 c 1.1,0 2,-0.9 2,-2 z"
}), h("path", {
d: "M0 0h24v24H0z",
fill: "none"
})));
};
_proto.render = function render() {
var _this11 = this;
var _this$props2 = this.props,
currentImage = _this$props2.currentImage,
i18n = _this$props2.i18n,
opts = _this$props2.opts;
var actions = opts.actions; // eslint-disable-next-line compat/compat
var imageURL = URL.createObjectURL(currentImage.data);
return h("div", {
className: "uppy-ImageCropper"
}, h("div", {
className: "uppy-ImageCropper-container"
}, h("img", {
className: "uppy-ImageCropper-image",
alt: currentImage.name,
src: imageURL,
ref: function ref(_ref) {
_this11.imgElement = _ref;
}
})), h("div", {
className: "uppy-ImageCropper-controls"
}, actions.revert && this.renderRevert(), actions.rotate && this.renderRotate(), actions.granularRotate && this.renderGranularRotate(), actions.flip && this.renderFlip(), actions.zoomIn && this.renderZoomIn(), actions.zoomOut && this.renderZoomOut(), actions.cropSquare && this.renderCropSquare(), actions.cropWidescreen && this.renderCropWidescreen(), actions.cropWidescreenVertical && this.renderCropWidescreenVertical()));
};
return Editor;
}(Component);
},{"cropperjs":14,"preact":125}],124:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Editor = require('./Editor');
var Translator = require('@uppy/utils/lib/Translator');
var _require2 = require('preact'),
h = _require2.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(ImageEditor, _Plugin);
function ImageEditor(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.save = function () {
var saveBlobCallback = function saveBlobCallback(blob) {
var _this$getPluginState = _this.getPluginState(),
currentImage = _this$getPluginState.currentImage;
_this.uppy.setFileState(currentImage.id, {
data: blob,
size: blob.size,
preview: null
});
var updatedFile = _this.uppy.getFile(currentImage.id);
_this.uppy.emit('thumbnail:request', updatedFile);
_this.setPluginState({
currentImage: updatedFile
});
_this.uppy.emit('file-editor:complete', updatedFile);
};
var _this$getPluginState2 = _this.getPluginState(),
currentImage = _this$getPluginState2.currentImage;
_this.cropper.getCroppedCanvas().toBlob(saveBlobCallback, currentImage.type, _this.opts.quality);
};
_this.storeCropperInstance = function (cropper) {
_this.cropper = cropper;
};
_this.selectFile = function (file) {
_this.uppy.emit('file-editor:start', file);
_this.setPluginState({
currentImage: file
});
};
_this.id = _this.opts.id || 'ImageEditor';
_this.title = 'Image Editor';
_this.type = 'editor';
_this.defaultLocale = {
strings: {
revert: 'Revert',
rotate: 'Rotate',
zoomIn: 'Zoom in',
zoomOut: 'Zoom out',
flipHorizontal: 'Flip horizontal',
aspectRatioSquare: 'Crop square',
aspectRatioLandscape: 'Crop landscape (16:9)',
aspectRatioPortrait: 'Crop portrait (9:16)'
}
};
var defaultCropperOptions = {
viewMode: 1,
background: false,
autoCropArea: 1,
responsive: true
};
var defaultActions = {
revert: true,
rotate: true,
granularRotate: true,
flip: true,
zoomIn: true,
zoomOut: true,
cropSquare: true,
cropWidescreen: true,
cropWidescreenVertical: true
};
var defaultOptions = {
quality: 0.8
};
_this.opts = _extends({}, defaultOptions, opts, {
actions: _extends({}, defaultActions, opts.actions),
cropperOptions: _extends({}, defaultCropperOptions, opts.cropperOptions)
});
_this.i18nInit();
return _this;
}
var _proto = ImageEditor.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator); // this.i18nArray = this.translator.translateArray.bind(this.translator)
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.canEditFile = function canEditFile(file) {
if (!file.type || file.isRemote) {
return false;
}
var fileTypeSpecific = file.type.split('/')[1];
if (/^(jpe?g|gif|png|bmp|webp)$/.test(fileTypeSpecific)) {
return true;
}
return false;
};
_proto.install = function install() {
this.setPluginState({
currentImage: null
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.unmount();
};
_proto.render = function render() {
var _this$getPluginState3 = this.getPluginState(),
currentImage = _this$getPluginState3.currentImage;
if (currentImage === null || currentImage.isRemote) {
return;
}
return h(Editor, {
currentImage: currentImage,
storeCropperInstance: this.storeCropperInstance,
save: this.save,
opts: this.opts,
i18n: this.i18n
});
};
return ImageEditor;
}(Plugin), _class.VERSION = "0.4.0", _temp);
},{"./Editor":123,"@uppy/core":78,"@uppy/utils/lib/Translator":218,"preact":125}],125:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],126:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('preact'),
h = _require2.h;
/**
* Informer
* Shows rad message bubbles
* used like this: `uppy.info('hello world', 'info', 5000)`
* or for errors: `uppy.info('Error uploading img.jpg', 'error', 5000)`
*
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Informer, _Plugin);
function Informer(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.render = function (state) {
var _state$info = state.info,
isHidden = _state$info.isHidden,
message = _state$info.message,
details = _state$info.details;
function displayErrorAlert() {
var errorMessage = message + " \n\n " + details;
alert(errorMessage);
}
var handleMouseOver = function handleMouseOver() {
clearTimeout(_this.uppy.infoTimeoutID);
};
var handleMouseLeave = function handleMouseLeave() {
_this.uppy.infoTimeoutID = setTimeout(_this.uppy.hideInfo, 2000);
};
return h("div", {
className: "uppy uppy-Informer",
"aria-hidden": isHidden
}, h("p", {
role: "alert"
}, message, ' ', details && h("span", {
"aria-label": details,
"data-microtip-position": "top-left",
"data-microtip-size": "medium",
role: "tooltip",
onClick: displayErrorAlert,
onMouseOver: handleMouseOver,
onMouseLeave: handleMouseLeave
}, "?")));
};
_this.type = 'progressindicator';
_this.id = _this.opts.id || 'Informer';
_this.title = 'Informer'; // set default options
var defaultOptions = {}; // merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, opts);
return _this;
}
var _proto = Informer.prototype;
_proto.install = function install() {
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
return Informer;
}(Plugin), _class.VERSION = "1.6.6", _temp);
},{"@uppy/core":78,"preact":127}],127:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],128:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider;
var _require3 = require('@uppy/provider-views'),
ProviderViews = _require3.ProviderViews;
var _require4 = require('preact'),
h = _require4.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Instagram, _Plugin);
function Instagram(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'Instagram';
Provider.initPlugin(_assertThisInitialized(_this), opts);
_this.title = _this.opts.title || 'Instagram';
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#E1306C",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M16 8.622c2.403 0 2.688.009 3.637.052.877.04 1.354.187 1.67.31.392.144.745.374 1.036.673.299.29.529.644.673 1.035.123.317.27.794.31 1.671.043.95.052 1.234.052 3.637s-.009 2.688-.052 3.637c-.04.877-.187 1.354-.31 1.671a2.98 2.98 0 0 1-1.708 1.708c-.317.123-.794.27-1.671.31-.95.043-1.234.053-3.637.053s-2.688-.01-3.637-.053c-.877-.04-1.354-.187-1.671-.31a2.788 2.788 0 0 1-1.035-.673 2.788 2.788 0 0 1-.673-1.035c-.123-.317-.27-.794-.31-1.671-.043-.949-.052-1.234-.052-3.637s.009-2.688.052-3.637c.04-.877.187-1.354.31-1.67.144-.392.374-.745.673-1.036.29-.299.644-.529 1.035-.673.317-.123.794-.27 1.671-.31.95-.043 1.234-.052 3.637-.052zM16 7c-2.444 0-2.75.01-3.71.054-.959.044-1.613.196-2.185.419-.6.225-1.145.58-1.594 1.038-.458.45-.813.993-1.039 1.594-.222.572-.374 1.226-.418 2.184C7.01 13.25 7 13.556 7 16s.01 2.75.054 3.71c.044.959.196 1.613.419 2.185.226.6.58 1.145 1.038 1.594.45.458.993.813 1.594 1.038.572.223 1.227.375 2.184.419.96.044 1.267.054 3.711.054s2.75-.01 3.71-.054c.959-.044 1.613-.196 2.185-.419a4.602 4.602 0 0 0 2.632-2.632c.223-.572.375-1.226.419-2.184.044-.96.054-1.267.054-3.711s-.01-2.75-.054-3.71c-.044-.959-.196-1.613-.419-2.185A4.412 4.412 0 0 0 23.49 8.51a4.412 4.412 0 0 0-1.594-1.039c-.572-.222-1.226-.374-2.184-.418C18.75 7.01 18.444 7 16 7zm0 4.5a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9zm0 7.421a2.921 2.921 0 1 1 0-5.842 2.921 2.921 0 0 1 0 5.842zm4.875-6.671a1.125 1.125 0 1 1 0-2.25 1.125 1.125 0 0 1 0 2.25z",
fill: "#FFF"
})));
};
_this.provider = new Provider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionKeysParams: _this.opts.companionKeysParams,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'instagram',
pluginId: _this.id
});
_this.onFirstRender = _this.onFirstRender.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Instagram.prototype;
_proto.install = function install() {
this.view = new ProviderViews(this, {
provider: this.provider,
viewType: 'grid',
showTitles: false,
showFilter: false,
showBreadcrumbs: false
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.view.tearDown();
this.unmount();
};
_proto.onFirstRender = function onFirstRender() {
return Promise.all([this.provider.fetchPreAuthToken(), this.view.getFolder('recent')]);
};
_proto.render = function render(state) {
return this.view.render(state);
};
return Instagram;
}(Plugin), _class.VERSION = "1.5.2", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/provider-views":155,"preact":129}],129:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],130:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider;
var _require3 = require('@uppy/provider-views'),
ProviderViews = _require3.ProviderViews;
var _require4 = require('preact'),
h = _require4.h;
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(OneDrive, _Plugin);
function OneDrive(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'OneDrive';
Provider.initPlugin(_assertThisInitialized(_this), opts);
_this.title = _this.opts.title || 'OneDrive';
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
width: "32",
height: "32",
rx: "16",
fill: "#0262C0"
}), h("g", {
fill: "#FFF",
fillRule: "nonzero"
}, h("path", {
d: "M24.157 22s1.492-.205 1.79-1.655a2.624 2.624 0 0 0 .03-.878c-.22-1.64-1.988-2.01-1.988-2.01s.307-1.765-1.312-2.69c-1.62-.925-3.1 0-3.1 0S18.711 13 16.366 13c-3.016 0-3.519 3.448-3.519 3.448S10 16.618 10 19.14c0 2.523 2.597 2.86 2.597 2.86h11.56z"
}), h("path", {
d: "M9.421 19.246c0-2.197 1.606-3.159 2.871-3.472.44-1.477 1.654-3.439 4.135-3.439H16.445c1.721 0 2.79.823 3.368 1.476a3.99 3.99 0 0 1 1.147-.171h.01l.03.002C21.017 13.5 20.691 10 16.757 10c-2.69 0-3.639 2.345-3.639 2.345s-1.95-1.482-3.955.567c-1.028 1.052-.79 2.669-.79 2.669S6 15.824 6 18.412C6 20.757 8.452 21 8.452 21h1.372a3.77 3.77 0 0 1-.403-1.754z"
}))));
};
_this.provider = new Provider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'onedrive',
pluginId: _this.id
});
_this.onFirstRender = _this.onFirstRender.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = OneDrive.prototype;
_proto.install = function install() {
this.view = new ProviderViews(this, {
provider: this.provider
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.view.tearDown();
this.unmount();
};
_proto.onFirstRender = function onFirstRender() {
return Promise.all([this.provider.fetchPreAuthToken(), this.view.getFolder()]);
};
_proto.render = function render(state) {
return this.view.render(state);
};
return OneDrive;
}(Plugin), _class.VERSION = "1.2.2", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/provider-views":155,"preact":131}],131:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],132:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('preact'),
h = _require2.h;
/**
* Progress bar
*
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(ProgressBar, _Plugin);
function ProgressBar(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'ProgressBar';
_this.title = 'Progress Bar';
_this.type = 'progressindicator'; // set default options
var defaultOptions = {
target: 'body',
replaceTargetContent: false,
fixed: false,
hideAfterFinish: true
}; // merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, opts);
_this.render = _this.render.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = ProgressBar.prototype;
_proto.render = function render(state) {
var progress = state.totalProgress || 0; // before starting and after finish should be hidden if specified in the options
var isHidden = (progress === 0 || progress === 100) && this.opts.hideAfterFinish;
return h("div", {
className: "uppy uppy-ProgressBar",
style: {
position: this.opts.fixed ? 'fixed' : 'initial'
},
"aria-hidden": isHidden
}, h("div", {
className: "uppy-ProgressBar-inner",
style: {
width: progress + "%"
}
}), h("div", {
className: "uppy-ProgressBar-percentage"
}, progress));
};
_proto.install = function install() {
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.unmount();
};
return ProgressBar;
}(Plugin), _class.VERSION = "1.3.30", _temp);
},{"@uppy/core":78,"preact":133}],133:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],134:[function(require,module,exports){
var _require = require('preact'),
h = _require.h; // TODO use Fragment when upgrading to preact X
var Breadcrumb = function Breadcrumb(props) {
return h("span", null, h("button", {
type: "button",
className: "uppy-u-reset",
onClick: props.getFolder
}, props.title), !props.isLast ? ' / ' : '');
};
module.exports = function (props) {
return h("div", {
className: "uppy-Provider-breadcrumbs"
}, h("div", {
className: "uppy-Provider-breadcrumbsIcon"
}, props.breadcrumbsIcon), props.directories.map(function (directory, i) {
return h(Breadcrumb, {
key: directory.id,
getFolder: function getFolder() {
return props.getFolder(directory.id);
},
title: i === 0 ? props.title : directory.title,
isLast: i + 1 === props.directories.length
});
}));
};
},{"preact":156}],135:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var classNames = require('classnames');
var Filter = require('./Filter');
var ItemList = require('./ItemList');
var FooterActions = require('./FooterActions');
var _require = require('preact'),
h = _require.h;
var Browser = function Browser(props) {
var currentSelection = props.currentSelection,
folders = props.folders,
files = props.files,
uppyFiles = props.uppyFiles,
filterItems = props.filterItems,
filterInput = props.filterInput;
var filteredFolders = folders;
var filteredFiles = files;
if (filterInput !== '') {
filteredFolders = filterItems(folders);
filteredFiles = filterItems(files);
}
var selected = currentSelection.length;
return h("div", {
className: classNames('uppy-ProviderBrowser', "uppy-ProviderBrowser-viewType--" + props.viewType)
}, h("div", {
className: "uppy-ProviderBrowser-header"
}, h("div", {
className: classNames('uppy-ProviderBrowser-headerBar', !props.showBreadcrumbs && 'uppy-ProviderBrowser-headerBar--simple')
}, props.headerComponent)), props.showFilter && h(Filter, props), h(ItemList, {
columns: [{
name: 'Name',
key: 'title'
}],
folders: filteredFolders,
files: filteredFiles,
sortByTitle: props.sortByTitle,
sortByDate: props.sortByDate,
isChecked: props.isChecked,
handleFolderClick: props.getNextFolder,
toggleCheckbox: props.toggleCheckbox,
handleScroll: props.handleScroll,
title: props.title,
showTitles: props.showTitles,
i18n: props.i18n,
viewType: props.viewType,
validateRestrictions: props.validateRestrictions,
uppyFiles: uppyFiles,
currentSelection: currentSelection
}), selected > 0 && h(FooterActions, _extends({
selected: selected
}, props)));
};
module.exports = Browser;
},{"./Filter":137,"./FooterActions":138,"./ItemList":143,"classnames":11,"preact":156}],136:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
Component = _require.Component;
module.exports = /*#__PURE__*/function (_Component) {
_inheritsLoose(CloseWrapper, _Component);
function CloseWrapper() {
return _Component.apply(this, arguments) || this;
}
var _proto = CloseWrapper.prototype;
_proto.componentWillUnmount = function componentWillUnmount() {
this.props.onUnmount();
};
_proto.render = function render() {
return this.props.children[0];
};
return CloseWrapper;
}(Component);
},{"preact":156}],137:[function(require,module,exports){
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
module.exports = /*#__PURE__*/function (_Component) {
_inheritsLoose(Filter, _Component);
function Filter(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.preventEnterPress = _this.preventEnterPress.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Filter.prototype;
_proto.preventEnterPress = function preventEnterPress(ev) {
if (ev.keyCode === 13) {
ev.stopPropagation();
ev.preventDefault();
}
};
_proto.render = function render() {
var _this2 = this;
return h("div", {
className: "uppy-ProviderBrowser-search"
}, h("input", {
className: "uppy-u-reset uppy-ProviderBrowser-searchInput",
type: "text",
placeholder: this.props.i18n('filter'),
"aria-label": this.props.i18n('filter'),
onKeyUp: this.preventEnterPress,
onKeyDown: this.preventEnterPress,
onKeyPress: this.preventEnterPress,
onInput: function onInput(e) {
return _this2.props.filterQuery(e);
},
value: this.props.filterInput
}), h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon uppy-ProviderBrowser-searchIcon",
width: "12",
height: "12",
viewBox: "0 0 12 12"
}, h("path", {
d: "M8.638 7.99l3.172 3.172a.492.492 0 1 1-.697.697L7.91 8.656a4.977 4.977 0 0 1-2.983.983C2.206 9.639 0 7.481 0 4.819 0 2.158 2.206 0 4.927 0c2.721 0 4.927 2.158 4.927 4.82a4.74 4.74 0 0 1-1.216 3.17zm-3.71.685c2.176 0 3.94-1.726 3.94-3.856 0-2.129-1.764-3.855-3.94-3.855C2.75.964.984 2.69.984 4.819c0 2.13 1.765 3.856 3.942 3.856z"
})), this.props.filterInput && h("button", {
className: "uppy-u-reset uppy-ProviderBrowser-searchClose",
type: "button",
"aria-label": this.props.i18n('resetFilter'),
title: this.props.i18n('resetFilter'),
onClick: this.props.filterQuery
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
viewBox: "0 0 19 19"
}, h("path", {
d: "M17.318 17.232L9.94 9.854 9.586 9.5l-.354.354-7.378 7.378h.707l-.62-.62v.706L9.318 9.94l.354-.354-.354-.354L1.94 1.854v.707l.62-.62h-.706l7.378 7.378.354.354.354-.354 7.378-7.378h-.707l.622.62v-.706L9.854 9.232l-.354.354.354.354 7.378 7.378.708-.707-7.38-7.378v.708l7.38-7.38.353-.353-.353-.353-.622-.622-.353-.353-.354.352-7.378 7.38h.708L2.56 1.23 2.208.88l-.353.353-.622.62-.353.355.352.353 7.38 7.38v-.708l-7.38 7.38-.353.353.352.353.622.622.353.353.354-.353 7.38-7.38h-.708l7.38 7.38z"
}))));
};
return Filter;
}(Component);
},{"preact":156}],138:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
return h("div", {
className: "uppy-ProviderBrowser-footer"
}, h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary",
onClick: props.done
}, props.i18n('selectX', {
smart_count: props.selected
})), h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-link",
onClick: props.cancel
}, props.i18n('cancel')));
};
},{"preact":156}],139:[function(require,module,exports){
var _require = require('preact'),
h = _require.h; // it could be a <li><button class="fake-checkbox"/> <button/></li>
module.exports = function (props) {
return h("li", {
className: props.className,
title: props.isDisabled ? props.restrictionReason : null
}, h("div", {
"aria-hidden": true,
className: "uppy-ProviderBrowserItem-fakeCheckbox " + (props.isChecked ? 'uppy-ProviderBrowserItem-fakeCheckbox--is-checked' : '')
}), h("button", {
type: "button",
className: "uppy-u-reset uppy-ProviderBrowserItem-inner",
onClick: props.toggleCheckbox,
role: "option",
"aria-label": props.isChecked ? props.i18n('unselectFileNamed', {
name: props.title
}) : props.i18n('selectFileNamed', {
name: props.title
}),
"aria-selected": props.isChecked,
"aria-disabled": props.isDisabled,
disabled: props.isDisabled,
"data-uppy-super-focusable": true
}, props.itemIconEl, props.showTitles && props.title));
};
},{"preact":156}],140:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
function FileIcon() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: 11,
height: 14.5,
viewBox: "0 0 44 58"
}, h("path", {
d: "M27.437.517a1 1 0 0 0-.094.03H4.25C2.037.548.217 2.368.217 4.58v48.405c0 2.212 1.82 4.03 4.03 4.03H39.03c2.21 0 4.03-1.818 4.03-4.03V15.61a1 1 0 0 0-.03-.28 1 1 0 0 0 0-.093 1 1 0 0 0-.03-.032 1 1 0 0 0 0-.03 1 1 0 0 0-.032-.063 1 1 0 0 0-.03-.063 1 1 0 0 0-.032 0 1 1 0 0 0-.03-.063 1 1 0 0 0-.032-.03 1 1 0 0 0-.03-.063 1 1 0 0 0-.063-.062l-14.593-14a1 1 0 0 0-.062-.062A1 1 0 0 0 28 .708a1 1 0 0 0-.374-.157 1 1 0 0 0-.156 0 1 1 0 0 0-.03-.03l-.003-.003zM4.25 2.547h22.218v9.97c0 2.21 1.82 4.03 4.03 4.03h10.564v36.438a2.02 2.02 0 0 1-2.032 2.032H4.25c-1.13 0-2.032-.9-2.032-2.032V4.58c0-1.13.902-2.032 2.03-2.032zm24.218 1.345l10.375 9.937.75.718H30.5c-1.13 0-2.032-.9-2.032-2.03V3.89z"
}));
}
function FolderIcon() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
style: {
minWidth: 16,
marginRight: 3
},
viewBox: "0 0 276.157 276.157"
}, h("path", {
d: "M273.08 101.378c-3.3-4.65-8.86-7.32-15.254-7.32h-24.34V67.59c0-10.2-8.3-18.5-18.5-18.5h-85.322c-3.63 0-9.295-2.875-11.436-5.805l-6.386-8.735c-4.982-6.814-15.104-11.954-23.546-11.954H58.73c-9.292 0-18.638 6.608-21.737 15.372l-2.033 5.752c-.958 2.71-4.72 5.37-7.596 5.37H18.5C8.3 49.09 0 57.39 0 67.59v167.07c0 .886.16 1.73.443 2.52.152 3.306 1.18 6.424 3.053 9.064 3.3 4.652 8.86 7.32 15.255 7.32h188.487c11.395 0 23.27-8.425 27.035-19.18l40.677-116.188c2.11-6.035 1.43-12.164-1.87-16.816zM18.5 64.088h8.864c9.295 0 18.64-6.607 21.738-15.37l2.032-5.75c.96-2.712 4.722-5.373 7.597-5.373h29.565c3.63 0 9.295 2.876 11.437 5.806l6.386 8.735c4.982 6.815 15.104 11.954 23.546 11.954h85.322c1.898 0 3.5 1.602 3.5 3.5v26.47H69.34c-11.395 0-23.27 8.423-27.035 19.178L15 191.23V67.59c0-1.898 1.603-3.5 3.5-3.5zm242.29 49.15l-40.676 116.188c-1.674 4.78-7.812 9.135-12.877 9.135H18.75c-1.447 0-2.576-.372-3.02-.997-.442-.625-.422-1.814.057-3.18l40.677-116.19c1.674-4.78 7.812-9.134 12.877-9.134h188.487c1.448 0 2.577.372 3.02.997.443.625.423 1.814-.056 3.18z"
}));
}
function VideoIcon() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
style: {
width: 16,
marginRight: 4
},
viewBox: "0 0 58 58"
}, h("path", {
d: "M36.537 28.156l-11-7a1.005 1.005 0 0 0-1.02-.033C24.2 21.3 24 21.635 24 22v14a1 1 0 0 0 1.537.844l11-7a1.002 1.002 0 0 0 0-1.688zM26 34.18V23.82L34.137 29 26 34.18z"
}), h("path", {
d: "M57 6H1a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h56a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1zM10 28H2v-9h8v9zm-8 2h8v9H2v-9zm10 10V8h34v42H12V40zm44-12h-8v-9h8v9zm-8 2h8v9h-8v-9zm8-22v9h-8V8h8zM2 8h8v9H2V8zm0 42v-9h8v9H2zm54 0h-8v-9h8v9z"
}));
}
module.exports = function (props) {
if (props.itemIconString === null) return;
switch (props.itemIconString) {
case 'file':
return h(FileIcon, null);
case 'folder':
return h(FolderIcon, null);
case 'video':
return h(VideoIcon, null);
default:
return h("img", {
src: props.itemIconString
});
}
};
},{"preact":156}],141:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var getAriaLabelOfCheckbox = function getAriaLabelOfCheckbox(props) {
if (props.type === 'folder') {
if (props.isChecked) {
return props.i18n('unselectAllFilesFromFolderNamed', {
name: props.title
});
}
return props.i18n('selectAllFilesFromFolderNamed', {
name: props.title
});
}
if (props.isChecked) {
return props.i18n('unselectFileNamed', {
name: props.title
});
}
return props.i18n('selectFileNamed', {
name: props.title
});
}; // if folder:
// + checkbox (selects all files from folder)
// + folder name (opens folder)
// if file:
// + checkbox (selects file)
// + file name (selects file)
module.exports = function (props) {
return h("li", {
className: props.className,
title: props.isDisabled ? props.restrictionReason : null
}, !props.isCheckboxDisabled ? h("button", {
type: "button",
className: "uppy-u-reset uppy-ProviderBrowserItem-fakeCheckbox " + (props.isChecked ? 'uppy-ProviderBrowserItem-fakeCheckbox--is-checked' : ''),
onClick: props.toggleCheckbox // for the <label/>
,
id: props.id,
role: "option",
"aria-label": getAriaLabelOfCheckbox(props),
"aria-selected": props.isChecked,
"aria-disabled": props.isDisabled,
disabled: props.isDisabled,
"data-uppy-super-focusable": true
}) : null, props.type === 'file' ? // label for a checkbox
h("label", {
htmlFor: props.id,
className: "uppy-u-reset uppy-ProviderBrowserItem-inner"
}, h("div", {
className: "uppy-ProviderBrowserItem-iconWrap"
}, props.itemIconEl), props.showTitles && props.title) : // button to open a folder
h("button", {
type: "button",
className: "uppy-u-reset uppy-ProviderBrowserItem-inner",
onClick: props.handleFolderClick,
"aria-label": props.i18n('openFolderNamed', {
name: props.title
})
}, h("div", {
className: "uppy-ProviderBrowserItem-iconWrap"
}, props.itemIconEl), props.showTitles && h("span", null, props.title)));
};
},{"preact":156}],142:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('preact'),
h = _require.h;
var classNames = require('classnames');
var ItemIcon = require('./components/ItemIcon');
var GridLi = require('./components/GridLi');
var ListLi = require('./components/ListLi');
module.exports = function (props) {
var itemIconString = props.getItemIcon();
var className = classNames('uppy-ProviderBrowserItem', {
'uppy-ProviderBrowserItem--selected': props.isChecked
}, {
'uppy-ProviderBrowserItem--disabled': props.isDisabled
}, {
'uppy-ProviderBrowserItem--noPreview': itemIconString === 'video'
});
var itemIconEl = h(ItemIcon, {
itemIconString: itemIconString
});
switch (props.viewType) {
case 'grid':
return h(GridLi, _extends({}, props, {
className: className,
itemIconEl: itemIconEl
}));
case 'list':
return h(ListLi, _extends({}, props, {
className: className,
itemIconEl: itemIconEl
}));
default:
throw new Error("There is no such type " + props.viewType);
}
};
},{"./components/GridLi":139,"./components/ItemIcon":140,"./components/ListLi":141,"classnames":11,"preact":156}],143:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('preact'),
h = _require.h;
var remoteFileObjToLocal = require('@uppy/utils/lib/remoteFileObjToLocal');
var Item = require('./Item/index'); // Hopefully this name will not be used by Google
var VIRTUAL_SHARED_DIR = 'shared-with-me';
var getSharedProps = function getSharedProps(fileOrFolder, props) {
return {
id: fileOrFolder.id,
title: fileOrFolder.name,
getItemIcon: function getItemIcon() {
return fileOrFolder.icon;
},
isChecked: props.isChecked(fileOrFolder),
toggleCheckbox: function toggleCheckbox(e) {
return props.toggleCheckbox(e, fileOrFolder);
},
columns: props.columns,
showTitles: props.showTitles,
viewType: props.viewType,
i18n: props.i18n
};
};
module.exports = function (props) {
var folders = props.folders,
files = props.files,
handleScroll = props.handleScroll,
isChecked = props.isChecked;
if (!folders.length && !files.length) {
return h("div", {
className: "uppy-Provider-empty"
}, props.i18n('noFilesFound'));
}
return h("div", {
className: "uppy-ProviderBrowser-body"
}, h("ul", {
className: "uppy-ProviderBrowser-list",
onScroll: handleScroll,
role: "listbox" // making <ul> not focusable for firefox
,
tabIndex: "-1"
}, folders.map(function (folder) {
return Item(_extends({}, getSharedProps(folder, props), {
type: 'folder',
isDisabled: isChecked(folder) ? isChecked(folder).loading : false,
isCheckboxDisabled: folder.id === VIRTUAL_SHARED_DIR,
handleFolderClick: function handleFolderClick() {
return props.handleFolderClick(folder);
}
}));
}), files.map(function (file) {
var validateRestrictions = props.validateRestrictions(remoteFileObjToLocal(file), [].concat(props.uppyFiles, props.currentSelection));
var sharedProps = getSharedProps(file, props);
var restrictionReason = validateRestrictions.reason;
return Item(_extends({}, sharedProps, {
type: 'file',
isDisabled: !validateRestrictions.result && !sharedProps.isChecked,
restrictionReason: restrictionReason
}));
})));
};
},{"./Item/index":142,"@uppy/utils/lib/remoteFileObjToLocal":249,"preact":156}],144:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
return h("div", {
className: "uppy-Provider-loading"
}, h("span", null, props.i18n('loading')));
};
},{"preact":156}],145:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var AuthView = /*#__PURE__*/function (_Component) {
_inheritsLoose(AuthView, _Component);
function AuthView() {
return _Component.apply(this, arguments) || this;
}
var _proto = AuthView.prototype;
_proto.render = function render() {
var pluginNameComponent = h("span", {
className: "uppy-Provider-authTitleName"
}, this.props.pluginName, h("br", null));
return h("div", {
className: "uppy-Provider-auth"
}, h("div", {
className: "uppy-Provider-authIcon"
}, this.props.pluginIcon()), h("div", {
className: "uppy-Provider-authTitle"
}, this.props.i18nArray('authenticateWithTitle', {
pluginName: pluginNameComponent
})), h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Provider-authBtn",
onClick: this.props.handleAuth,
"data-uppy-super-focusable": true
}, this.props.i18nArray('authenticateWith', {
pluginName: this.props.pluginName
})));
};
return AuthView;
}(Component);
module.exports = AuthView;
},{"preact":156}],146:[function(require,module,exports){
var User = require('./User');
var Breadcrumbs = require('../Breadcrumbs');
module.exports = function (props) {
var components = [];
if (props.showBreadcrumbs) {
components.push(Breadcrumbs({
getFolder: props.getFolder,
directories: props.directories,
breadcrumbsIcon: props.pluginIcon && props.pluginIcon(),
title: props.title
}));
}
components.push(User({
logout: props.logout,
username: props.username,
i18n: props.i18n
}));
return components;
};
},{"../Breadcrumbs":134,"./User":148}],147:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('preact'),
h = _require.h;
var AuthView = require('./AuthView');
var Header = require('./Header');
var Browser = require('../Browser');
var LoaderView = require('../Loader');
var generateFileID = require('@uppy/utils/lib/generateFileID');
var getFileType = require('@uppy/utils/lib/getFileType');
var findIndex = require('@uppy/utils/lib/findIndex');
var isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported');
var SharedHandler = require('../SharedHandler');
var CloseWrapper = require('../CloseWrapper'); // location.origin does not exist in IE
function getOrigin() {
if ('origin' in location) {
return location.origin; // eslint-disable-line compat/compat
}
return location.protocol + "//" + location.hostname + (location.port ? ":" + location.port : '');
}
/**
* Class to easily generate generic views for Provider plugins
*/
module.exports = (_temp = _class = /*#__PURE__*/function () {
/**
* @param {object} plugin instance of the plugin
* @param {object} opts
*/
function ProviderView(plugin, opts) {
this.plugin = plugin;
this.provider = opts.provider;
this._sharedHandler = new SharedHandler(plugin); // set default options
var defaultOptions = {
viewType: 'list',
showTitles: true,
showFilter: true,
showBreadcrumbs: true
}; // merge default options with the ones set by user
this.opts = _extends({}, defaultOptions, opts); // Logic
this.addFile = this.addFile.bind(this);
this.filterQuery = this.filterQuery.bind(this);
this.getFolder = this.getFolder.bind(this);
this.getNextFolder = this.getNextFolder.bind(this);
this.logout = this.logout.bind(this);
this.preFirstRender = this.preFirstRender.bind(this);
this.handleAuth = this.handleAuth.bind(this);
this.sortByTitle = this.sortByTitle.bind(this);
this.sortByDate = this.sortByDate.bind(this);
this.handleError = this.handleError.bind(this);
this.handleScroll = this.handleScroll.bind(this);
this.listAllFiles = this.listAllFiles.bind(this);
this.donePicking = this.donePicking.bind(this);
this.cancelPicking = this.cancelPicking.bind(this);
this.clearSelection = this.clearSelection.bind(this); // Visual
this.render = this.render.bind(this);
this.clearSelection(); // Set default state for the plugin
this.plugin.setPluginState({
authenticated: false,
files: [],
folders: [],
directories: [],
filterInput: '',
isSearchVisible: false
});
}
var _proto = ProviderView.prototype;
_proto.tearDown = function tearDown() {// Nothing.
};
_proto._updateFilesAndFolders = function _updateFilesAndFolders(res, files, folders) {
this.nextPagePath = res.nextPagePath;
res.items.forEach(function (item) {
if (item.isFolder) {
folders.push(item);
} else {
files.push(item);
}
});
this.plugin.setPluginState({
folders: folders,
files: files
});
}
/**
* Called only the first time the provider view is rendered.
* Kind of like an init function.
*/
;
_proto.preFirstRender = function preFirstRender() {
this.plugin.setPluginState({
didFirstRender: true
});
this.plugin.onFirstRender();
}
/**
* Based on folder ID, fetch a new folder and update it to state
*
* @param {string} id Folder id
* @returns {Promise} Folders/files in folder
*/
;
_proto.getFolder = function getFolder(id, name) {
var _this = this;
return this._sharedHandler.loaderWrapper(this.provider.list(id), function (res) {
var folders = [];
var files = [];
var updatedDirectories;
var state = _this.plugin.getPluginState();
var index = findIndex(state.directories, function (dir) {
return id === dir.id;
});
if (index !== -1) {
updatedDirectories = state.directories.slice(0, index + 1);
} else {
updatedDirectories = state.directories.concat([{
id: id,
title: name
}]);
}
_this.username = res.username || _this.username;
_this._updateFilesAndFolders(res, files, folders);
_this.plugin.setPluginState({
directories: updatedDirectories
});
}, this.handleError);
}
/**
* Fetches new folder
*
* @param {object} folder
*/
;
_proto.getNextFolder = function getNextFolder(folder) {
this.getFolder(folder.requestPath, folder.name);
this.lastCheckbox = undefined;
};
_proto.addFile = function addFile(file) {
var tagFile = {
id: this.providerFileToId(file),
source: this.plugin.id,
data: file,
name: file.name || file.id,
type: file.mimeType,
isRemote: true,
body: {
fileId: file.id
},
remote: {
companionUrl: this.plugin.opts.companionUrl,
url: "" + this.provider.fileUrl(file.requestPath),
body: {
fileId: file.id
},
providerOptions: this.provider.opts
}
};
var fileType = getFileType(tagFile); // TODO Should we just always use the thumbnail URL if it exists?
if (fileType && isPreviewSupported(fileType)) {
tagFile.preview = file.thumbnail;
}
this.plugin.uppy.log('Adding remote file');
try {
this.plugin.uppy.addFile(tagFile);
return true;
} catch (err) {
if (!err.isRestriction) {
this.plugin.uppy.log(err);
}
return false;
}
}
/**
* Removes session token on client side.
*/
;
_proto.logout = function logout() {
var _this2 = this;
this.provider.logout().then(function (res) {
if (res.ok) {
if (!res.revoked) {
var message = _this2.plugin.uppy.i18n('companionUnauthorizeHint', {
provider: _this2.plugin.title,
url: res.manual_revoke_url
});
_this2.plugin.uppy.info(message, 'info', 7000);
}
var newState = {
authenticated: false,
files: [],
folders: [],
directories: []
};
_this2.plugin.setPluginState(newState);
}
}).catch(this.handleError);
};
_proto.filterQuery = function filterQuery(e) {
var state = this.plugin.getPluginState();
this.plugin.setPluginState(_extends({}, state, {
filterInput: e ? e.target.value : ''
}));
};
_proto.sortByTitle = function sortByTitle() {
var state = _extends({}, this.plugin.getPluginState());
var files = state.files,
folders = state.folders,
sorting = state.sorting;
var sortedFiles = files.sort(function (fileA, fileB) {
if (sorting === 'titleDescending') {
return fileB.name.localeCompare(fileA.name);
}
return fileA.name.localeCompare(fileB.name);
});
var sortedFolders = folders.sort(function (folderA, folderB) {
if (sorting === 'titleDescending') {
return folderB.name.localeCompare(folderA.name);
}
return folderA.name.localeCompare(folderB.name);
});
this.plugin.setPluginState(_extends({}, state, {
files: sortedFiles,
folders: sortedFolders,
sorting: sorting === 'titleDescending' ? 'titleAscending' : 'titleDescending'
}));
};
_proto.sortByDate = function sortByDate() {
var state = _extends({}, this.plugin.getPluginState());
var files = state.files,
folders = state.folders,
sorting = state.sorting;
var sortedFiles = files.sort(function (fileA, fileB) {
var a = new Date(fileA.modifiedDate);
var b = new Date(fileB.modifiedDate);
if (sorting === 'dateDescending') {
return a > b ? -1 : a < b ? 1 : 0;
}
return a > b ? 1 : a < b ? -1 : 0;
});
var sortedFolders = folders.sort(function (folderA, folderB) {
var a = new Date(folderA.modifiedDate);
var b = new Date(folderB.modifiedDate);
if (sorting === 'dateDescending') {
return a > b ? -1 : a < b ? 1 : 0;
}
return a > b ? 1 : a < b ? -1 : 0;
});
this.plugin.setPluginState(_extends({}, state, {
files: sortedFiles,
folders: sortedFolders,
sorting: sorting === 'dateDescending' ? 'dateAscending' : 'dateDescending'
}));
};
_proto.sortBySize = function sortBySize() {
var state = _extends({}, this.plugin.getPluginState());
var files = state.files,
sorting = state.sorting; // check that plugin supports file sizes
if (!files.length || !this.plugin.getItemData(files[0]).size) {
return;
}
var sortedFiles = files.sort(function (fileA, fileB) {
var a = fileA.size;
var b = fileB.size;
if (sorting === 'sizeDescending') {
return a > b ? -1 : a < b ? 1 : 0;
}
return a > b ? 1 : a < b ? -1 : 0;
});
this.plugin.setPluginState(_extends({}, state, {
files: sortedFiles,
sorting: sorting === 'sizeDescending' ? 'sizeAscending' : 'sizeDescending'
}));
}
/**
* Adds all files found inside of specified folder.
*
* Uses separated state while folder contents are being fetched and
* mantains list of selected folders, which are separated from files.
*/
;
_proto.addFolder = function addFolder(folder) {
var _this3 = this;
var folderId = this.providerFileToId(folder);
var state = this.plugin.getPluginState();
var folders = _extends({}, state.selectedFolders);
if (folderId in folders && folders[folderId].loading) {
return;
}
folders[folderId] = {
loading: true,
files: []
};
this.plugin.setPluginState({
selectedFolders: _extends({}, folders)
});
return this.listAllFiles(folder.requestPath).then(function (files) {
var count = 0;
files.forEach(function (file) {
var success = _this3.addFile(file);
if (success) count++;
});
var ids = files.map(_this3.providerFileToId);
folders[folderId] = {
loading: false,
files: ids
};
_this3.plugin.setPluginState({
selectedFolders: folders
});
var message;
if (files.length) {
message = _this3.plugin.uppy.i18n('folderAdded', {
smart_count: count,
folder: folder.name
});
} else {
message = _this3.plugin.uppy.i18n('emptyFolderAdded');
}
_this3.plugin.uppy.info(message);
}).catch(function (e) {
var state = _this3.plugin.getPluginState();
var selectedFolders = _extends({}, state.selectedFolders);
delete selectedFolders[folderId];
_this3.plugin.setPluginState({
selectedFolders: selectedFolders
});
_this3.handleError(e);
});
};
_proto.providerFileToId = function providerFileToId(file) {
return generateFileID({
data: file,
name: file.name || file.id,
type: file.mimeType
});
};
_proto.handleAuth = function handleAuth() {
var _this4 = this;
var authState = btoa(JSON.stringify({
origin: getOrigin()
}));
var clientVersion = "@uppy/provider-views=" + ProviderView.VERSION;
var link = this.provider.authUrl({
state: authState,
uppyVersions: clientVersion
});
var authWindow = window.open(link, '_blank');
var handleToken = function handleToken(e) {
if (!_this4._isOriginAllowed(e.origin, _this4.plugin.opts.companionAllowedHosts) || e.source !== authWindow) {
_this4.plugin.uppy.log("rejecting event from " + e.origin + " vs allowed pattern " + _this4.plugin.opts.companionAllowedHosts);
return;
} // Check if it's a string before doing the JSON.parse to maintain support
// for older Companion versions that used object references
var data = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;
if (!data.token) {
_this4.plugin.uppy.log('did not receive token from auth window');
return;
}
authWindow.close();
window.removeEventListener('message', handleToken);
_this4.provider.setAuthToken(data.token);
_this4.preFirstRender();
};
window.addEventListener('message', handleToken);
};
_proto._isOriginAllowed = function _isOriginAllowed(origin, allowedOrigin) {
var getRegex = function getRegex(value) {
if (typeof value === 'string') {
return new RegExp("^" + value + "$");
}
if (value instanceof RegExp) {
return value;
}
};
var patterns = Array.isArray(allowedOrigin) ? allowedOrigin.map(getRegex) : [getRegex(allowedOrigin)];
return patterns.filter(function (pattern) {
return pattern != null;
}) // loose comparison to catch undefined
.some(function (pattern) {
return pattern.test(origin) || pattern.test(origin + "/");
}); // allowing for trailing '/'
};
_proto.handleError = function handleError(error) {
var uppy = this.plugin.uppy;
uppy.log(error.toString());
if (error.isAuthError) {
return;
}
var message = uppy.i18n('companionError');
uppy.info({
message: message,
details: error.toString()
}, 'error', 5000);
};
_proto.handleScroll = function handleScroll(e) {
var _this5 = this;
var scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight);
var path = this.nextPagePath || null;
if (scrollPos < 50 && path && !this._isHandlingScroll) {
this.provider.list(path).then(function (res) {
var _this5$plugin$getPlug = _this5.plugin.getPluginState(),
files = _this5$plugin$getPlug.files,
folders = _this5$plugin$getPlug.folders;
_this5._updateFilesAndFolders(res, files, folders);
}).catch(this.handleError).then(function () {
_this5._isHandlingScroll = false;
}); // always called
this._isHandlingScroll = true;
}
};
_proto.listAllFiles = function listAllFiles(path, files) {
var _this6 = this;
if (files === void 0) {
files = null;
}
files = files || [];
return new Promise(function (resolve, reject) {
_this6.provider.list(path).then(function (res) {
res.items.forEach(function (item) {
if (!item.isFolder) {
files.push(item);
} else {
_this6.addFolder(item);
}
});
var moreFiles = res.nextPagePath || null;
if (moreFiles) {
return _this6.listAllFiles(moreFiles, files).then(function (files) {
return resolve(files);
}).catch(function (e) {
return reject(e);
});
}
return resolve(files);
}).catch(function (e) {
return reject(e);
});
});
};
_proto.donePicking = function donePicking() {
var _this7 = this;
var _this$plugin$getPlugi = this.plugin.getPluginState(),
currentSelection = _this$plugin$getPlugi.currentSelection;
var promises = currentSelection.map(function (file) {
if (file.isFolder) {
return _this7.addFolder(file);
}
return _this7.addFile(file);
});
this._sharedHandler.loaderWrapper(Promise.all(promises), function () {
_this7.clearSelection();
}, function () {});
};
_proto.cancelPicking = function cancelPicking() {
this.clearSelection();
var dashboard = this.plugin.uppy.getPlugin('Dashboard');
if (dashboard) dashboard.hideAllPanels();
};
_proto.clearSelection = function clearSelection() {
this.plugin.setPluginState({
currentSelection: []
});
};
_proto.render = function render(state, viewOptions) {
if (viewOptions === void 0) {
viewOptions = {};
}
var _this$plugin$getPlugi2 = this.plugin.getPluginState(),
authenticated = _this$plugin$getPlugi2.authenticated,
didFirstRender = _this$plugin$getPlugi2.didFirstRender;
if (!didFirstRender) {
this.preFirstRender();
} // reload pluginState for "loading" attribute because it might
// have changed above.
if (this.plugin.getPluginState().loading) {
return h(CloseWrapper, {
onUnmount: this.clearSelection
}, h(LoaderView, {
i18n: this.plugin.uppy.i18n
}));
}
if (!authenticated) {
return h(CloseWrapper, {
onUnmount: this.clearSelection
}, h(AuthView, {
pluginName: this.plugin.title,
pluginIcon: this.plugin.icon,
handleAuth: this.handleAuth,
i18n: this.plugin.uppy.i18n,
i18nArray: this.plugin.uppy.i18nArray
}));
}
var targetViewOptions = _extends({}, this.opts, viewOptions);
var headerProps = {
showBreadcrumbs: targetViewOptions.showBreadcrumbs,
getFolder: this.getFolder,
directories: this.plugin.getPluginState().directories,
pluginIcon: this.plugin.icon,
title: this.plugin.title,
logout: this.logout,
username: this.username,
i18n: this.plugin.uppy.i18n
};
var browserProps = _extends({}, this.plugin.getPluginState(), {
username: this.username,
getNextFolder: this.getNextFolder,
getFolder: this.getFolder,
filterItems: this._sharedHandler.filterItems,
filterQuery: this.filterQuery,
sortByTitle: this.sortByTitle,
sortByDate: this.sortByDate,
logout: this.logout,
isChecked: this._sharedHandler.isChecked,
toggleCheckbox: this._sharedHandler.toggleCheckbox,
handleScroll: this.handleScroll,
listAllFiles: this.listAllFiles,
done: this.donePicking,
cancel: this.cancelPicking,
headerComponent: Header(headerProps),
title: this.plugin.title,
viewType: targetViewOptions.viewType,
showTitles: targetViewOptions.showTitles,
showFilter: targetViewOptions.showFilter,
showBreadcrumbs: targetViewOptions.showBreadcrumbs,
pluginIcon: this.plugin.icon,
i18n: this.plugin.uppy.i18n,
uppyFiles: this.plugin.uppy.getFiles(),
validateRestrictions: this.plugin.uppy.validateRestrictions
});
return h(CloseWrapper, {
onUnmount: this.clearSelection
}, h(Browser, browserProps));
};
return ProviderView;
}(), _class.VERSION = "1.12.3", _temp);
},{"../Browser":135,"../CloseWrapper":136,"../Loader":144,"../SharedHandler":154,"./AuthView":145,"./Header":146,"@uppy/utils/lib/findIndex":226,"@uppy/utils/lib/generateFileID":227,"@uppy/utils/lib/getFileType":235,"@uppy/utils/lib/isPreviewSupported":246,"preact":156}],148:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
return [h("span", {
className: "uppy-ProviderBrowser-user",
key: "username"
}, props.username), h("button", {
type: "button",
onClick: props.logout,
className: "uppy-u-reset uppy-ProviderBrowser-userLogout",
key: "logout"
}, props.i18n('logOut'))];
};
},{"preact":156}],149:[function(require,module,exports){
module.exports = require('./ProviderView');
},{"./ProviderView":147}],150:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
return h("button", {
type: "button",
onClick: props.triggerSearchInput,
className: "uppy-u-reset uppy-ProviderBrowser-userLogout"
}, props.i18n('backToSearch'));
};
},{"preact":156}],151:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
var input;
var handleKeyPress = function handleKeyPress(ev) {
if (ev.keyCode === 13) {
validateAndSearch();
}
};
var validateAndSearch = function validateAndSearch() {
if (input.value) {
props.search(input.value);
}
};
return h("div", {
className: "uppy-SearchProvider"
}, h("input", {
className: "uppy-u-reset uppy-c-textInput uppy-SearchProvider-input",
type: "text",
"aria-label": props.i18n('enterTextToSearch'),
placeholder: props.i18n('enterTextToSearch'),
onKeyUp: handleKeyPress,
ref: function ref(input_) {
input = input_;
},
"data-uppy-super-focusable": true
}), h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-SearchProvider-searchButton",
type: "button",
onClick: validateAndSearch
}, props.i18n('searchImages')));
};
},{"preact":156}],152:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('preact'),
h = _require.h;
var SearchInput = require('./InputView');
var Browser = require('../Browser');
var LoaderView = require('../Loader');
var generateFileID = require('@uppy/utils/lib/generateFileID');
var getFileType = require('@uppy/utils/lib/getFileType');
var isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported');
var Header = require('./Header');
var SharedHandler = require('../SharedHandler');
var CloseWrapper = require('../CloseWrapper');
/**
* Class to easily generate generic views for Provider plugins
*/
module.exports = (_temp = _class = /*#__PURE__*/function () {
/**
* @param {object} plugin instance of the plugin
* @param {object} opts
*/
function ProviderView(plugin, opts) {
this.plugin = plugin;
this.provider = opts.provider;
this._sharedHandler = new SharedHandler(plugin); // set default options
var defaultOptions = {
viewType: 'grid',
showTitles: false,
showFilter: false,
showBreadcrumbs: false
}; // merge default options with the ones set by user
this.opts = _extends({}, defaultOptions, opts); // Logic
this.search = this.search.bind(this);
this.triggerSearchInput = this.triggerSearchInput.bind(this);
this.addFile = this.addFile.bind(this);
this.preFirstRender = this.preFirstRender.bind(this);
this.handleError = this.handleError.bind(this);
this.handleScroll = this.handleScroll.bind(this);
this.donePicking = this.donePicking.bind(this);
this.cancelPicking = this.cancelPicking.bind(this);
this.clearSelection = this.clearSelection.bind(this); // Visual
this.render = this.render.bind(this);
this.clearSelection(); // Set default state for the plugin
this.plugin.setPluginState({
isInputMode: true,
files: [],
folders: [],
directories: [],
filterInput: '',
isSearchVisible: false
});
}
var _proto = ProviderView.prototype;
_proto.tearDown = function tearDown() {// Nothing.
};
_proto._updateFilesAndInputMode = function _updateFilesAndInputMode(res, files) {
this.nextPageQuery = res.nextPageQuery;
this._searchTerm = res.searchedFor;
res.items.forEach(function (item) {
files.push(item);
});
this.plugin.setPluginState({
isInputMode: false,
files: files
});
}
/**
* Called only the first time the provider view is rendered.
* Kind of like an init function.
*/
;
_proto.preFirstRender = function preFirstRender() {
this.plugin.setPluginState({
didFirstRender: true
});
this.plugin.onFirstRender();
};
_proto.search = function search(query) {
var _this = this;
if (query && query === this._searchTerm) {
// no need to search again as this is the same as the previous search
this.plugin.setPluginState({
isInputMode: false
});
return;
}
return this._sharedHandler.loaderWrapper(this.provider.search(query), function (res) {
_this._updateFilesAndInputMode(res, []);
}, this.handleError);
};
_proto.triggerSearchInput = function triggerSearchInput() {
this.plugin.setPluginState({
isInputMode: true
});
} // @todo this function should really be a function of the plugin and not the view.
// maybe we should consider creating a base ProviderPlugin class that has this method
;
_proto.addFile = function addFile(file) {
var tagFile = {
id: this.providerFileToId(file),
source: this.plugin.id,
data: file,
name: file.name || file.id,
type: file.mimeType,
isRemote: true,
body: {
fileId: file.id
},
remote: {
companionUrl: this.plugin.opts.companionUrl,
url: "" + this.provider.fileUrl(file.requestPath),
body: {
fileId: file.id
},
providerOptions: _extends({}, this.provider.opts, {
provider: null
})
}
};
var fileType = getFileType(tagFile); // TODO Should we just always use the thumbnail URL if it exists?
if (fileType && isPreviewSupported(fileType)) {
tagFile.preview = file.thumbnail;
}
this.plugin.uppy.log('Adding remote file');
try {
this.plugin.uppy.addFile(tagFile);
} catch (err) {
if (!err.isRestriction) {
this.plugin.uppy.log(err);
}
}
};
_proto.providerFileToId = function providerFileToId(file) {
return generateFileID({
data: file,
name: file.name || file.id,
type: file.mimeType
});
};
_proto.handleError = function handleError(error) {
var uppy = this.plugin.uppy;
uppy.log(error.toString());
var message = uppy.i18n('companionError');
uppy.info({
message: message,
details: error.toString()
}, 'error', 5000);
};
_proto.handleScroll = function handleScroll(e) {
var _this2 = this;
var scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight);
var query = this.nextPageQuery || null;
if (scrollPos < 50 && query && !this._isHandlingScroll) {
this.provider.search(this._searchTerm, query).then(function (res) {
var _this2$plugin$getPlug = _this2.plugin.getPluginState(),
files = _this2$plugin$getPlug.files;
_this2._updateFilesAndInputMode(res, files);
}).catch(this.handleError).then(function () {
_this2._isHandlingScroll = false;
}); // always called
this._isHandlingScroll = true;
}
};
_proto.donePicking = function donePicking() {
var _this3 = this;
var _this$plugin$getPlugi = this.plugin.getPluginState(),
currentSelection = _this$plugin$getPlugi.currentSelection;
var promises = currentSelection.map(function (file) {
return _this3.addFile(file);
});
this._sharedHandler.loaderWrapper(Promise.all(promises), function () {
_this3.clearSelection();
}, function () {});
};
_proto.cancelPicking = function cancelPicking() {
this.clearSelection();
var dashboard = this.plugin.uppy.getPlugin('Dashboard');
if (dashboard) dashboard.hideAllPanels();
};
_proto.clearSelection = function clearSelection() {
this.plugin.setPluginState({
currentSelection: []
});
};
_proto.render = function render(state, viewOptions) {
if (viewOptions === void 0) {
viewOptions = {};
}
var _this$plugin$getPlugi2 = this.plugin.getPluginState(),
didFirstRender = _this$plugin$getPlugi2.didFirstRender,
isInputMode = _this$plugin$getPlugi2.isInputMode;
if (!didFirstRender) {
this.preFirstRender();
} // reload pluginState for "loading" attribute because it might
// have changed above.
if (this.plugin.getPluginState().loading) {
return h(CloseWrapper, {
onUnmount: this.clearSelection
}, h(LoaderView, {
i18n: this.plugin.uppy.i18n
}));
}
if (isInputMode) {
return h(CloseWrapper, {
onUnmount: this.clearSelection
}, h(SearchInput, {
search: this.search,
i18n: this.plugin.uppy.i18n
}));
}
var targetViewOptions = _extends({}, this.opts, viewOptions);
var browserProps = _extends({}, this.plugin.getPluginState(), {
isChecked: this._sharedHandler.isChecked,
toggleCheckbox: this._sharedHandler.toggleCheckbox,
handleScroll: this.handleScroll,
done: this.donePicking,
cancel: this.cancelPicking,
headerComponent: Header({
triggerSearchInput: this.triggerSearchInput,
i18n: this.plugin.uppy.i18n
}),
title: this.plugin.title,
viewType: targetViewOptions.viewType,
showTitles: targetViewOptions.showTitles,
showFilter: targetViewOptions.showFilter,
showBreadcrumbs: targetViewOptions.showBreadcrumbs,
pluginIcon: this.plugin.icon,
i18n: this.plugin.uppy.i18n,
uppyFiles: this.plugin.uppy.getFiles(),
validateRestrictions: this.plugin.uppy.validateRestrictions
});
return h(CloseWrapper, {
onUnmount: this.clearSelection
}, h(Browser, browserProps));
};
return ProviderView;
}(), _class.VERSION = "1.12.3", _temp);
},{"../Browser":135,"../CloseWrapper":136,"../Loader":144,"../SharedHandler":154,"./Header":150,"./InputView":151,"@uppy/utils/lib/generateFileID":227,"@uppy/utils/lib/getFileType":235,"@uppy/utils/lib/isPreviewSupported":246,"preact":156}],153:[function(require,module,exports){
module.exports = require('./SearchProviderView');
},{"./SearchProviderView":152}],154:[function(require,module,exports){
var remoteFileObjToLocal = require('@uppy/utils/lib/remoteFileObjToLocal');
module.exports = /*#__PURE__*/function () {
function SharedHandler(plugin) {
this.plugin = plugin;
this.filterItems = this.filterItems.bind(this);
this.toggleCheckbox = this.toggleCheckbox.bind(this);
this.isChecked = this.isChecked.bind(this);
this.loaderWrapper = this.loaderWrapper.bind(this);
}
var _proto = SharedHandler.prototype;
_proto.filterItems = function filterItems(items) {
var state = this.plugin.getPluginState();
if (!state.filterInput || state.filterInput === '') {
return items;
}
return items.filter(function (folder) {
return folder.name.toLowerCase().indexOf(state.filterInput.toLowerCase()) !== -1;
});
}
/**
* Toggles file/folder checkbox to on/off state while updating files list.
*
* Note that some extra complexity comes from supporting shift+click to
* toggle multiple checkboxes at once, which is done by getting all files
* in between last checked file and current one.
*/
;
_proto.toggleCheckbox = function toggleCheckbox(e, file) {
var _this = this;
e.stopPropagation();
e.preventDefault();
e.currentTarget.focus();
var _this$plugin$getPlugi = this.plugin.getPluginState(),
folders = _this$plugin$getPlugi.folders,
files = _this$plugin$getPlugi.files;
var items = this.filterItems(folders.concat(files)); // Shift-clicking selects a single consecutive list of items
// starting at the previous click and deselects everything else.
if (this.lastCheckbox && e.shiftKey) {
var _currentSelection;
var prevIndex = items.indexOf(this.lastCheckbox);
var currentIndex = items.indexOf(file);
if (prevIndex < currentIndex) {
_currentSelection = items.slice(prevIndex, currentIndex + 1);
} else {
_currentSelection = items.slice(currentIndex, prevIndex + 1);
} // Check restrictions on each file in currentSelection,
// reduce it to only contain files that pass restrictions
_currentSelection = _currentSelection.reduce(function (reducedCurrentSelection, item) {
var uppy = _this.plugin.uppy;
var validatedRestrictions = uppy.validateRestrictions(remoteFileObjToLocal(item), [].concat(uppy.getFiles(), reducedCurrentSelection));
if (!validatedRestrictions.result) {
uppy.info({
message: validatedRestrictions.reason
}, 'error', uppy.opts.infoTimeout);
return reducedCurrentSelection;
}
return [].concat(reducedCurrentSelection, [item]);
});
this.plugin.setPluginState({
currentSelection: _currentSelection
});
return;
}
this.lastCheckbox = file;
var _this$plugin$getPlugi2 = this.plugin.getPluginState(),
currentSelection = _this$plugin$getPlugi2.currentSelection;
if (this.isChecked(file)) {
this.plugin.setPluginState({
currentSelection: currentSelection.filter(function (item) {
return item.id !== file.id;
})
});
} else {
this.plugin.setPluginState({
currentSelection: currentSelection.concat([file])
});
}
};
_proto.isChecked = function isChecked(file) {
var _this$plugin$getPlugi3 = this.plugin.getPluginState(),
currentSelection = _this$plugin$getPlugi3.currentSelection; // comparing id instead of the file object, because the reference to the object
// changes when we switch folders, and the file list is updated
return currentSelection.some(function (item) {
return item.id === file.id;
});
};
_proto.loaderWrapper = function loaderWrapper(promise, then, catch_) {
var _this2 = this;
promise.then(function (result) {
_this2.plugin.setPluginState({
loading: false
});
then(result);
}).catch(function (err) {
_this2.plugin.setPluginState({
loading: false
});
catch_(err);
});
this.plugin.setPluginState({
loading: true
});
};
return SharedHandler;
}();
},{"@uppy/utils/lib/remoteFileObjToLocal":249}],155:[function(require,module,exports){
var ProviderViews = require('./ProviderView');
var SearchProviderViews = require('./SearchProviderView');
module.exports = {
ProviderViews: ProviderViews,
SearchProviderViews: SearchProviderViews
};
},{"./ProviderView":149,"./SearchProviderView":153}],156:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],157:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
/**
* Add Redux DevTools support to Uppy
*
* See https://medium.com/@zalmoxis/redux-devtools-without-redux-or-how-to-have-a-predictable-state-with-any-architecture-61c5f5a7716f
* and https://github.com/zalmoxisus/mobx-remotedev/blob/master/src/monitorActions.js
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(ReduxDevTools, _Plugin);
function ReduxDevTools(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'debugger';
_this.id = _this.opts.id || 'ReduxDevTools';
_this.title = 'Redux DevTools'; // set default options
var defaultOptions = {}; // merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, opts);
_this.handleStateChange = _this.handleStateChange.bind(_assertThisInitialized(_this));
_this.initDevTools = _this.initDevTools.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = ReduxDevTools.prototype;
_proto.handleStateChange = function handleStateChange(prevState, nextState, patch) {
this.devTools.send('UPPY_STATE_UPDATE', nextState);
};
_proto.initDevTools = function initDevTools() {
var _this2 = this;
this.devTools = window.devToolsExtension.connect();
this.devToolsUnsubscribe = this.devTools.subscribe(function (message) {
if (message.type === 'DISPATCH') {
// Implement monitors actions
switch (message.payload.type) {
case 'RESET':
_this2.uppy.reset();
return;
case 'IMPORT_STATE':
{
var computedStates = message.payload.nextLiftedState.computedStates;
_this2.uppy.store.state = _extends({}, _this2.uppy.getState(), computedStates[computedStates.length - 1].state);
_this2.uppy.updateAll(_this2.uppy.getState());
return;
}
case 'JUMP_TO_STATE':
case 'JUMP_TO_ACTION':
_this2.uppy.store.state = _extends({}, _this2.uppy.getState(), JSON.parse(message.state));
_this2.uppy.updateAll(_this2.uppy.getState());
}
}
});
};
_proto.install = function install() {
this.withDevTools = typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__;
if (this.withDevTools) {
this.initDevTools();
this.uppy.on('state-update', this.handleStateChange);
}
};
_proto.uninstall = function uninstall() {
if (this.withDevTools) {
this.devToolsUnsubscribe();
this.uppy.off('state-update', this.handleStateUpdate);
}
};
return ReduxDevTools;
}(Plugin), _class.VERSION = "1.3.9", _temp);
},{"@uppy/core":78}],158:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var RecordButton = require('./RecordButton');
var SubmitButton = require('./SubmitButton');
var StopWatch = require('./StopWatch');
var StreamStatus = require('./StreamStatus');
var RecorderScreen = /*#__PURE__*/function (_Component) {
_inheritsLoose(RecorderScreen, _Component);
function RecorderScreen() {
return _Component.apply(this, arguments) || this;
}
var _proto = RecorderScreen.prototype;
_proto.componentWillUnmount = function componentWillUnmount() {
this.props.onStop();
};
_proto.render = function render() {
var _this = this;
var _this$props = this.props,
recording = _this$props.recording,
videoStream = _this$props.stream,
recordedVideo = _this$props.recordedVideo;
var videoProps = {
playsinline: true
}; // show stream
if (recording || !recordedVideo && !recording) {
videoProps.muted = true;
videoProps.autoplay = true;
videoProps.srcObject = videoStream;
} // show preview
if (recordedVideo && !recording) {
videoProps.muted = false;
videoProps.controls = true;
videoProps.src = recordedVideo; // reset srcObject in dom. If not resetted, stream sticks in element
if (this.videoElement) {
this.videoElement.srcObject = undefined;
}
}
return h("div", {
className: "uppy uppy-ScreenCapture-container"
}, h("div", {
className: "uppy-ScreenCapture-videoContainer"
}, h(StreamStatus, this.props), h("video", _extends({
ref: function ref(videoElement) {
return _this.videoElement = videoElement;
},
className: "uppy-ScreenCapture-video"
}, videoProps)), h(StopWatch, this.props)), h("div", {
className: "uppy-ScreenCapture-buttonContainer"
}, h(RecordButton, this.props), h(SubmitButton, this.props)));
};
return RecorderScreen;
}(Component);
module.exports = RecorderScreen;
},{"./RecordButton":159,"./StopWatch":161,"./StreamStatus":162,"./SubmitButton":163,"preact":165}],159:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
/**
* Control screen capture recording. Will show record or stop button.
*/
module.exports = function RecordButton(_ref) {
var recording = _ref.recording,
onStartRecording = _ref.onStartRecording,
onStopRecording = _ref.onStopRecording,
i18n = _ref.i18n;
if (recording) {
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-ScreenCapture-button uppy-ScreenCapture-button--video uppy-ScreenCapture-button--stop-rec",
type: "button",
title: i18n('stopCapturing'),
"aria-label": i18n('stopCapturing'),
onClick: onStopRecording,
"data-uppy-super-focusable": true
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "100",
height: "100",
viewBox: "0 0 100 100"
}, h("rect", {
x: "15",
y: "15",
width: "70",
height: "70"
})));
}
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-ScreenCapture-button uppy-ScreenCapture-button--video",
type: "button",
title: i18n('startCapturing'),
"aria-label": i18n('startCapturing'),
onClick: onStartRecording,
"data-uppy-super-focusable": true
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "100",
height: "100",
viewBox: "0 0 100 100"
}, h("circle", {
cx: "50",
cy: "50",
r: "40"
})));
};
},{"preact":165}],160:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#2C3E50",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M24.182 9H7.818C6.81 9 6 9.742 6 10.667v10c0 .916.81 1.666 1.818 1.666h4.546V24h7.272v-1.667h4.546c1 0 1.809-.75 1.809-1.666l.009-10C26 9.742 25.182 9 24.182 9zM24 21H8V11h16v10z",
fill: "#FFF",
fillRule: "nonzero"
}), h("circle", {
fill: "#FFF",
cx: "16",
cy: "16",
r: "2"
})));
};
},{"preact":165}],161:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var Stopwatch = /*#__PURE__*/function (_Component) {
_inheritsLoose(Stopwatch, _Component);
function Stopwatch(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.state = {
elapsedTime: 0
};
_this.wrapperStyle = {
width: '100%',
height: '100%',
display: 'flex'
};
_this.overlayStyle = {
position: 'absolute',
width: '100%',
height: '100%',
background: 'black',
opacity: 0.7
};
_this.infoContainerStyle = {
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 'auto',
marginBottom: 'auto',
zIndex: 1,
color: 'white'
};
_this.infotextStyle = {
marginLeft: 'auto',
marginRight: 'auto',
marginBottom: '1rem',
fontSize: '1.5rem'
};
_this.timeStyle = {
display: 'block',
fontWeight: 'bold',
marginLeft: 'auto',
marginRight: 'auto',
fontSize: '3rem',
fontFamily: 'Courier New'
};
return _this;
}
var _proto = Stopwatch.prototype;
_proto.startTimer = function startTimer() {
this.timerTick();
this.timerRunning = true;
};
_proto.resetTimer = function resetTimer() {
clearTimeout(this.timer);
this.setState({
elapsedTime: 0
});
this.timerRunning = false;
};
_proto.timerTick = function timerTick() {
var _this2 = this;
this.timer = setTimeout(function () {
_this2.setState({
elapsedTime: _this2.state.elapsedTime + 1
});
_this2.timerTick();
}, 1000);
};
_proto.fmtMSS = function fmtMSS(s) {
return (s - (s %= 60)) / 60 + (s > 9 ? ':' : ':0') + s;
};
_proto.render = function render() {
var _this$props = _extends({}, this.props),
recording = _this$props.recording,
i18n = _this$props.i18n; // second to minutes and seconds
var minAndSec = this.fmtMSS(this.state.elapsedTime);
if (recording && !this.timerRunning) {
this.startTimer();
}
if (!recording && this.timerRunning) {
this.resetTimer();
}
if (recording) {
return h("div", {
style: this.wrapperStyle
}, h("div", {
style: this.overlayStyle
}), h("div", {
style: this.infoContainerStyle
}, h("div", {
style: this.infotextStyle
}, i18n('recording')), h("div", {
style: this.timeStyle
}, minAndSec)));
}
return null;
};
return Stopwatch;
}(Component);
module.exports = Stopwatch;
},{"preact":165}],162:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (_ref) {
var streamActive = _ref.streamActive,
i18n = _ref.i18n;
if (streamActive) {
return h("div", {
title: i18n('streamActive'),
"aria-label": i18n('streamActive'),
className: "uppy-ScreenCapture-icon--stream uppy-ScreenCapture-icon--streamActive"
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0z",
opacity: ".1",
fill: "none"
}), h("path", {
d: "M0 0h24v24H0z",
fill: "none"
}), h("path", {
d: "M1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm18-7H5v1.63c3.96 1.28 7.09 4.41 8.37 8.37H19V7zM1 10v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11zm20-7H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
})));
}
return h("div", {
title: i18n('streamPassive'),
"aria-label": i18n('streamPassive'),
className: "uppy-ScreenCapture-icon--stream"
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "24",
height: "24",
viewBox: "0 0 24 24"
}, h("path", {
d: "M0 0h24v24H0z",
opacity: ".1",
fill: "none"
}), h("path", {
d: "M0 0h24v24H0z",
fill: "none"
}), h("path", {
d: "M21 3H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z"
})));
};
},{"preact":165}],163:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
/**
* Submit recorded video to uppy. Enabled when file is available
*/
module.exports = function SubmitButton(_ref) {
var recording = _ref.recording,
recordedVideo = _ref.recordedVideo,
onSubmit = _ref.onSubmit,
i18n = _ref.i18n;
if (recordedVideo && !recording) {
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-ScreenCapture-button uppy-ScreenCapture-button--submit",
type: "button",
title: i18n('submitRecordedFile'),
"aria-label": i18n('submitRecordedFile'),
onClick: onSubmit,
"data-uppy-super-focusable": true
}, h("svg", {
width: "12",
height: "9",
viewBox: "0 0 12 9",
xmlns: "http://www.w3.org/2000/svg",
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon"
}, h("path", {
fill: "#fff",
fillRule: "nonzero",
d: "M10.66 0L12 1.31 4.136 9 0 4.956l1.34-1.31L4.136 6.38z"
})));
}
return null;
};
},{"preact":165}],164:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h;
var _require2 = require('@uppy/core'),
Plugin = _require2.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var getFileTypeExtension = require('@uppy/utils/lib/getFileTypeExtension');
var ScreenRecIcon = require('./ScreenRecIcon');
var CaptureScreen = require('./CaptureScreen'); // Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
function getMediaDevices() {
// check if screen capturing is supported
/* eslint-disable */
if (navigator && navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia && window && window.MediaRecorder) {
return navigator.mediaDevices;
}
/* eslint-enable */
return null;
}
/**
* Screen capture
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(ScreenCapture, _Plugin);
function ScreenCapture(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.mediaDevices = getMediaDevices();
_this.protocol = location.protocol.match(/https/i) ? 'https' : 'http';
_this.id = _this.opts.id || 'ScreenCapture';
_this.title = _this.opts.title || 'Screencast';
_this.type = 'acquirer';
_this.icon = ScreenRecIcon;
_this.defaultLocale = {
strings: {
startCapturing: 'Begin screen capturing',
stopCapturing: 'Stop screen capturing',
submitRecordedFile: 'Submit recorded file',
streamActive: 'Stream active',
streamPassive: 'Stream passive',
micDisabled: 'Microphone access denied by user',
recording: 'Recording'
}
}; // set default options
// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints
var defaultOptions = {
// https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#Properties_of_shared_screen_tracks
displayMediaConstraints: {
video: {
width: 1280,
height: 720,
frameRate: {
ideal: 3,
max: 5
},
cursor: 'motion',
displaySurface: 'monitor'
}
},
// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints/audio
userMediaConstraints: {
audio: true
},
preferredVideoMimeType: 'video/webm'
}; // merge default options with the ones set by user
_this.opts = _extends({}, defaultOptions, opts); // i18n
_this.translator = new Translator([_this.defaultLocale, _this.uppy.locale, _this.opts.locale]);
_this.i18n = _this.translator.translate.bind(_this.translator);
_this.i18nArray = _this.translator.translateArray.bind(_this.translator); // uppy plugin class related
_this.install = _this.install.bind(_assertThisInitialized(_this));
_this.setPluginState = _this.setPluginState.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this)); // screen capturer related
_this.start = _this.start.bind(_assertThisInitialized(_this));
_this.stop = _this.stop.bind(_assertThisInitialized(_this));
_this.startRecording = _this.startRecording.bind(_assertThisInitialized(_this));
_this.stopRecording = _this.stopRecording.bind(_assertThisInitialized(_this));
_this.submit = _this.submit.bind(_assertThisInitialized(_this));
_this.streamInterrupted = _this.streamInactivated.bind(_assertThisInitialized(_this)); // initialize
_this.captureActive = false;
_this.capturedMediaFile = null;
return _this;
}
var _proto = ScreenCapture.prototype;
_proto.install = function install() {
// Return if browser doesn’t support getDisplayMedia and
if (!this.mediaDevices) {
this.uppy.log('Screen recorder access is not supported', 'error');
return null;
}
this.setPluginState({
streamActive: false,
audioStreamActive: false
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
if (this.videoStream) {
this.stop();
}
this.unmount();
};
_proto.start = function start() {
var _this2 = this;
if (!this.mediaDevices) {
return Promise.reject(new Error('Screen recorder access not supported'));
}
this.captureActive = true;
this.selectAudioStreamSource();
this.selectVideoStreamSource().then(function (res) {
// something happened in start -> return
if (res === false) {
// Close the Dashboard panel if plugin is installed
// into Dashboard (could be other parent UI plugin)
if (_this2.parent && _this2.parent.hideAllPanels) {
_this2.parent.hideAllPanels();
_this2.captureActive = false;
}
}
});
};
_proto.selectVideoStreamSource = function selectVideoStreamSource() {
var _this3 = this;
// if active stream available, return it
if (this.videoStream) {
return new Promise(function (resolve) {
return resolve(_this3.videoStream);
});
} // ask user to select source to record and get mediastream from that
// eslint-disable-next-line compat/compat
return this.mediaDevices.getDisplayMedia(this.opts.displayMediaConstraints).then(function (videoStream) {
_this3.videoStream = videoStream; // add event listener to stop recording if stream is interrupted
_this3.videoStream.addEventListener('inactive', function (event) {
_this3.streamInactivated();
});
_this3.setPluginState({
streamActive: true
});
return videoStream;
}).catch(function (err) {
_this3.setPluginState({
screenRecError: err
});
_this3.userDenied = true;
setTimeout(function () {
_this3.userDenied = false;
}, 1000);
return false;
});
};
_proto.selectAudioStreamSource = function selectAudioStreamSource() {
var _this4 = this;
// if active stream available, return it
if (this.audioStream) {
return new Promise(function (resolve) {
return resolve(_this4.audioStream);
});
} // ask user to select source to record and get mediastream from that
// eslint-disable-next-line compat/compat
return this.mediaDevices.getUserMedia(this.opts.userMediaConstraints).then(function (audioStream) {
_this4.audioStream = audioStream;
_this4.setPluginState({
audioStreamActive: true
});
return audioStream;
}).catch(function (err) {
if (err.name === 'NotAllowedError') {
_this4.uppy.info(_this4.i18n('micDisabled'), 'error', 5000);
}
return false;
});
};
_proto.startRecording = function startRecording() {
var _this5 = this;
var options = {};
this.capturedMediaFile = null;
this.recordingChunks = [];
var preferredVideoMimeType = this.opts.preferredVideoMimeType;
this.selectVideoStreamSource().then(function (videoStream) {
// Attempt to use the passed preferredVideoMimeType (if any) during recording.
// If the browser doesn't support it, we'll fall back to the browser default instead
if (preferredVideoMimeType && MediaRecorder.isTypeSupported(preferredVideoMimeType) && getFileTypeExtension(preferredVideoMimeType)) {
options.mimeType = preferredVideoMimeType;
} // prepare tracks
var tracks = [videoStream.getVideoTracks()[0]]; // merge audio if exits
if (_this5.audioStream) {
tracks.push(_this5.audioStream.getAudioTracks()[0]);
} // create new stream from video and audio
// eslint-disable-next-line compat/compat
_this5.outputStream = new MediaStream(tracks); // initialize mediarecorder
// eslint-disable-next-line compat/compat
_this5.recorder = new MediaRecorder(_this5.outputStream, options); // push data to buffer when data available
_this5.recorder.addEventListener('dataavailable', function (event) {
_this5.recordingChunks.push(event.data);
}); // start recording
_this5.recorder.start(); // set plugin state to recording
_this5.setPluginState({
recording: true
});
}).catch(function (err) {
_this5.uppy.log(err, 'error');
});
};
_proto.streamInactivated = function streamInactivated() {
// get screen recorder state
var _this$getPluginState = _extends({}, this.getPluginState()),
recordedVideo = _this$getPluginState.recordedVideo,
recording = _this$getPluginState.recording;
if (!recordedVideo && !recording) {
// Close the Dashboard panel if plugin is installed
// into Dashboard (could be other parent UI plugin)
if (this.parent && this.parent.hideAllPanels) {
this.parent.hideAllPanels();
}
} else if (recording) {
// stop recorder if it is active
this.uppy.log('Capture stream inactive — stop recording');
this.stopRecording();
}
this.videoStream = null;
this.audioStream = null;
this.setPluginState({
streamActive: false,
audioStreamActive: false
});
};
_proto.stopRecording = function stopRecording() {
var _this6 = this;
var stopped = new Promise(function (resolve, reject) {
_this6.recorder.addEventListener('stop', function () {
resolve();
});
_this6.recorder.stop();
});
return stopped.then(function () {
// recording stopped
_this6.setPluginState({
recording: false
}); // get video file after recorder stopped
return _this6.getVideo();
}).then(function (file) {
// store media file
_this6.capturedMediaFile = file; // create object url for capture result preview
_this6.setPluginState({
// eslint-disable-next-line compat/compat
recordedVideo: URL.createObjectURL(file.data)
});
}).then(function () {
_this6.recordingChunks = null;
_this6.recorder = null;
}, function (error) {
_this6.recordingChunks = null;
_this6.recorder = null;
throw error;
});
};
_proto.submit = function submit() {
try {
// add recorded file to uppy
if (this.capturedMediaFile) {
this.uppy.addFile(this.capturedMediaFile);
}
} catch (err) {
// Logging the error, exept restrictions, which is handled in Core
if (!err.isRestriction) {
this.uppy.log(err, 'error');
}
}
};
_proto.stop = function stop() {
// flush video stream
if (this.videoStream) {
this.videoStream.getVideoTracks().forEach(function (track) {
track.stop();
});
this.videoStream.getAudioTracks().forEach(function (track) {
track.stop();
});
this.videoStream = null;
} // flush audio stream
if (this.audioStream) {
this.audioStream.getAudioTracks().forEach(function (track) {
track.stop();
});
this.audioStream.getVideoTracks().forEach(function (track) {
track.stop();
});
this.audioStream = null;
} // flush output stream
if (this.outputStream) {
this.outputStream.getAudioTracks().forEach(function (track) {
track.stop();
});
this.outputStream.getVideoTracks().forEach(function (track) {
track.stop();
});
this.outputStream = null;
} // remove preview video
this.setPluginState({
recordedVideo: null
});
this.captureActive = false;
};
_proto.getVideo = function getVideo() {
var mimeType = this.recordingChunks[0].type;
var fileExtension = getFileTypeExtension(mimeType);
if (!fileExtension) {
return Promise.reject(new Error("Could not retrieve recording: Unsupported media type \"" + mimeType + "\""));
}
var name = "screencap-" + Date.now() + "." + fileExtension;
var blob = new Blob(this.recordingChunks, {
type: mimeType
});
var file = {
source: this.id,
name: name,
data: new Blob([blob], {
type: mimeType
}),
type: mimeType
};
return Promise.resolve(file);
};
_proto.render = function render(state) {
// get screen recorder state
var recorderState = this.getPluginState();
if (!recorderState.streamActive && !this.captureActive && !this.userDenied) {
this.start();
}
return h(CaptureScreen, _extends({}, recorderState, {
onStartRecording: this.startRecording,
onStopRecording: this.stopRecording,
onStop: this.stop,
onSubmit: this.submit,
i18n: this.i18n,
stream: this.videoStream
}));
};
return ScreenCapture;
}(Plugin), _class.VERSION = "1.1.0", _temp);
},{"./CaptureScreen":158,"./ScreenRecIcon":160,"@uppy/core":78,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/getFileTypeExtension":236,"preact":165}],165:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],166:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var throttle = require('lodash.throttle');
var classNames = require('classnames');
var statusBarStates = require('./StatusBarStates');
var prettierBytes = require('@transloadit/prettier-bytes');
var prettyETA = require('@uppy/utils/lib/prettyETA');
var _require = require('preact'),
h = _require.h;
function calculateProcessingProgress(files) {
// Collect pre or postprocessing progress states.
var progresses = [];
Object.keys(files).forEach(function (fileID) {
var progress = files[fileID].progress;
if (progress.preprocess) {
progresses.push(progress.preprocess);
}
if (progress.postprocess) {
progresses.push(progress.postprocess);
}
}); // In the future we should probably do this differently. For now we'll take the
// mode and message from the first file…
var _progresses$ = progresses[0],
mode = _progresses$.mode,
message = _progresses$.message;
var value = progresses.filter(isDeterminate).reduce(function (total, progress, index, all) {
return total + progress.value / all.length;
}, 0);
function isDeterminate(progress) {
return progress.mode === 'determinate';
}
return {
mode: mode,
message: message,
value: value
};
}
function togglePauseResume(props) {
if (props.isAllComplete) return;
if (!props.resumableUploads) {
return props.cancelAll();
}
if (props.isAllPaused) {
return props.resumeAll();
}
return props.pauseAll();
}
function RenderReSelectGhosts(_ref) {
var i18n = _ref.i18n;
return h("div", {
className: "uppy-StatusBar-serviceMsg"
}, i18n('reSelectGhosts'), h("svg", {
className: "uppy-c-icon uppy-StatusBar-serviceMsg-ghostsIcon",
"aria-hidden": "true",
width: "15",
height: "19",
viewBox: "0 0 35 39"
}, h("path", {
d: "M1.708 38.66c1.709 0 3.417-3.417 6.834-3.417 3.416 0 5.125 3.417 8.61 3.417 3.348 0 5.056-3.417 8.473-3.417 4.305 0 5.125 3.417 6.833 3.417.889 0 1.709-.889 1.709-1.709v-19.68C34.167-5.757 0-5.757 0 17.271v19.68c0 .82.888 1.709 1.708 1.709zm8.542-17.084a3.383 3.383 0 01-3.417-3.416 3.383 3.383 0 013.417-3.417 3.383 3.383 0 013.417 3.417 3.383 3.383 0 01-3.417 3.416zm13.667 0A3.383 3.383 0 0120.5 18.16a3.383 3.383 0 013.417-3.417 3.383 3.383 0 013.416 3.417 3.383 3.383 0 01-3.416 3.416z",
fillRule: "nonzero"
})));
}
module.exports = function (props) {
props = props || {};
var _props = props,
newFiles = _props.newFiles,
allowNewUpload = _props.allowNewUpload,
isUploadInProgress = _props.isUploadInProgress,
isAllPaused = _props.isAllPaused,
resumableUploads = _props.resumableUploads,
error = _props.error,
hideUploadButton = _props.hideUploadButton,
hidePauseResumeButton = _props.hidePauseResumeButton,
hideCancelButton = _props.hideCancelButton,
hideRetryButton = _props.hideRetryButton,
recoveredState = _props.recoveredState;
var uploadState = props.uploadState;
var progressValue = props.totalProgress;
var progressMode;
var progressBarContent;
if (uploadState === statusBarStates.STATE_PREPROCESSING || uploadState === statusBarStates.STATE_POSTPROCESSING) {
var progress = calculateProcessingProgress(props.files);
progressMode = progress.mode;
if (progressMode === 'determinate') {
progressValue = progress.value * 100;
}
progressBarContent = ProgressBarProcessing(progress);
} else if (uploadState === statusBarStates.STATE_COMPLETE) {
progressBarContent = ProgressBarComplete(props);
} else if (uploadState === statusBarStates.STATE_UPLOADING) {
if (!props.supportsUploadProgress) {
progressMode = 'indeterminate';
progressValue = null;
}
progressBarContent = ProgressBarUploading(props);
} else if (uploadState === statusBarStates.STATE_ERROR) {
progressValue = undefined;
progressBarContent = ProgressBarError(props);
}
var width = typeof progressValue === 'number' ? progressValue : 100;
var isHidden = uploadState === statusBarStates.STATE_WAITING && props.hideUploadButton || uploadState === statusBarStates.STATE_WAITING && !props.newFiles > 0 || uploadState === statusBarStates.STATE_COMPLETE && props.hideAfterFinish;
var showUploadBtn = !error && newFiles && !isUploadInProgress && !isAllPaused && allowNewUpload && !hideUploadButton;
if (recoveredState) {
isHidden = false;
showUploadBtn = true;
}
var showCancelBtn = !hideCancelButton && uploadState !== statusBarStates.STATE_WAITING && uploadState !== statusBarStates.STATE_COMPLETE;
var showPauseResumeBtn = resumableUploads && !hidePauseResumeButton && uploadState === statusBarStates.STATE_UPLOADING;
var showRetryBtn = error && !hideRetryButton;
var showDoneBtn = props.doneButtonHandler && uploadState === statusBarStates.STATE_COMPLETE;
var progressClassNames = "uppy-StatusBar-progress\n " + (progressMode ? "is-" + progressMode : '');
var statusBarClassNames = classNames({
'uppy-Root': props.isTargetDOMEl
}, 'uppy-StatusBar', "is-" + uploadState, {
'has-ghosts': props.isSomeGhost
});
return h("div", {
className: statusBarClassNames,
"aria-hidden": isHidden
}, h("div", {
className: progressClassNames,
style: {
width: width + "%"
},
role: "progressbar",
"aria-valuemin": "0",
"aria-valuemax": "100",
"aria-valuenow": progressValue
}), progressBarContent, h("div", {
className: "uppy-StatusBar-actions"
}, showUploadBtn ? h(UploadBtn, _extends({}, props, {
uploadState: uploadState
})) : null, showRetryBtn ? h(RetryBtn, props) : null, showPauseResumeBtn ? h(PauseResumeButton, props) : null, showCancelBtn ? h(CancelBtn, props) : null, showDoneBtn ? h(DoneBtn, props) : null));
};
var UploadBtn = function UploadBtn(props) {
var uploadBtnClassNames = classNames('uppy-u-reset', 'uppy-c-btn', 'uppy-StatusBar-actionBtn', 'uppy-StatusBar-actionBtn--upload', {
'uppy-c-btn-primary': props.uploadState === statusBarStates.STATE_WAITING
}, {
'uppy-StatusBar-actionBtn--disabled': props.isSomeGhost
});
var uploadBtnText = props.newFiles && props.isUploadStarted && !props.recoveredState ? props.i18n('uploadXNewFiles', {
smart_count: props.newFiles
}) : props.i18n('uploadXFiles', {
smart_count: props.newFiles
});
return h("button", {
type: "button",
className: uploadBtnClassNames,
"aria-label": props.i18n('uploadXFiles', {
smart_count: props.newFiles
}),
onClick: props.startUpload,
disabled: props.isSomeGhost,
"data-uppy-super-focusable": true
}, uploadBtnText);
};
var RetryBtn = function RetryBtn(props) {
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--retry",
"aria-label": props.i18n('retryUpload'),
onClick: props.retryAll,
"data-uppy-super-focusable": true
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "8",
height: "10",
viewBox: "0 0 8 10"
}, h("path", {
d: "M4 2.408a2.75 2.75 0 1 0 2.75 2.75.626.626 0 0 1 1.25.018v.023a4 4 0 1 1-4-4.041V.25a.25.25 0 0 1 .389-.208l2.299 1.533a.25.25 0 0 1 0 .416l-2.3 1.533A.25.25 0 0 1 4 3.316v-.908z"
})), props.i18n('retry'));
};
var CancelBtn = function CancelBtn(props) {
return h("button", {
type: "button",
className: "uppy-u-reset uppy-StatusBar-actionCircleBtn",
title: props.i18n('cancel'),
"aria-label": props.i18n('cancel'),
onClick: props.cancelAll,
"data-uppy-super-focusable": true
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "16",
height: "16",
viewBox: "0 0 16 16"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("circle", {
fill: "#888",
cx: "8",
cy: "8",
r: "8"
}), h("path", {
fill: "#FFF",
d: "M9.283 8l2.567 2.567-1.283 1.283L8 9.283 5.433 11.85 4.15 10.567 6.717 8 4.15 5.433 5.433 4.15 8 6.717l2.567-2.567 1.283 1.283z"
}))));
};
var PauseResumeButton = function PauseResumeButton(props) {
var isAllPaused = props.isAllPaused,
i18n = props.i18n;
var title = isAllPaused ? i18n('resume') : i18n('pause');
return h("button", {
title: title,
"aria-label": title,
className: "uppy-u-reset uppy-StatusBar-actionCircleBtn",
type: "button",
onClick: function onClick() {
return togglePauseResume(props);
},
"data-uppy-super-focusable": true
}, isAllPaused ? h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "16",
height: "16",
viewBox: "0 0 16 16"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("circle", {
fill: "#888",
cx: "8",
cy: "8",
r: "8"
}), h("path", {
fill: "#FFF",
d: "M6 4.25L11.5 8 6 11.75z"
}))) : h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "16",
height: "16",
viewBox: "0 0 16 16"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("circle", {
fill: "#888",
cx: "8",
cy: "8",
r: "8"
}), h("path", {
d: "M5 4.5h2v7H5v-7zm4 0h2v7H9v-7z",
fill: "#FFF"
}))));
};
var DoneBtn = function DoneBtn(props) {
var i18n = props.i18n;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--done",
onClick: props.doneButtonHandler,
"data-uppy-super-focusable": true
}, i18n('done'));
};
var LoadingSpinner = function LoadingSpinner() {
return h("svg", {
className: "uppy-StatusBar-spinner",
"aria-hidden": "true",
focusable: "false",
width: "14",
height: "14"
}, h("path", {
d: "M13.983 6.547c-.12-2.509-1.64-4.893-3.939-5.936-2.48-1.127-5.488-.656-7.556 1.094C.524 3.367-.398 6.048.162 8.562c.556 2.495 2.46 4.52 4.94 5.183 2.932.784 5.61-.602 7.256-3.015-1.493 1.993-3.745 3.309-6.298 2.868-2.514-.434-4.578-2.349-5.153-4.84a6.226 6.226 0 0 1 2.98-6.778C6.34.586 9.74 1.1 11.373 3.493c.407.596.693 1.282.842 1.988.127.598.073 1.197.161 1.794.078.525.543 1.257 1.15.864.525-.341.49-1.05.456-1.592-.007-.15.02.3 0 0",
fillRule: "evenodd"
}));
};
var ProgressBarProcessing = function ProgressBarProcessing(props) {
var value = Math.round(props.value * 100);
return h("div", {
className: "uppy-StatusBar-content"
}, h(LoadingSpinner, null), props.mode === 'determinate' ? value + "% \xB7 " : '', props.message);
};
var renderDot = function renderDot() {
return " \xB7 ";
};
var ProgressDetails = function ProgressDetails(props) {
var ifShowFilesUploadedOfTotal = props.numUploads > 1;
return h("div", {
className: "uppy-StatusBar-statusSecondary"
}, ifShowFilesUploadedOfTotal && props.i18n('filesUploadedOfTotal', {
complete: props.complete,
smart_count: props.numUploads
}), h("span", {
className: "uppy-StatusBar-additionalInfo"
}, ifShowFilesUploadedOfTotal && renderDot(), props.i18n('dataUploadedOfTotal', {
complete: prettierBytes(props.totalUploadedSize),
total: prettierBytes(props.totalSize)
}), renderDot(), props.i18n('xTimeLeft', {
time: prettyETA(props.totalETA)
})));
};
var UnknownProgressDetails = function UnknownProgressDetails(props) {
return h("div", {
className: "uppy-StatusBar-statusSecondary"
}, props.i18n('filesUploadedOfTotal', {
complete: props.complete,
smart_count: props.numUploads
}));
};
var UploadNewlyAddedFiles = function UploadNewlyAddedFiles(props) {
var uploadBtnClassNames = classNames('uppy-u-reset', 'uppy-c-btn', 'uppy-StatusBar-actionBtn', 'uppy-StatusBar-actionBtn--uploadNewlyAdded');
return h("div", {
className: "uppy-StatusBar-statusSecondary"
}, h("div", {
className: "uppy-StatusBar-statusSecondaryHint"
}, props.i18n('xMoreFilesAdded', {
smart_count: props.newFiles
})), h("button", {
type: "button",
className: uploadBtnClassNames,
"aria-label": props.i18n('uploadXFiles', {
smart_count: props.newFiles
}),
onClick: props.startUpload
}, props.i18n('upload')));
};
var ThrottledProgressDetails = throttle(ProgressDetails, 500, {
leading: true,
trailing: true
});
var ProgressBarUploading = function ProgressBarUploading(props) {
if (!props.isUploadStarted || props.isAllComplete) {
return null;
}
var title = props.isAllPaused ? props.i18n('paused') : props.i18n('uploading');
var showUploadNewlyAddedFiles = props.newFiles && props.isUploadStarted;
return h("div", {
className: "uppy-StatusBar-content",
"aria-label": title,
title: title
}, !props.isAllPaused ? h(LoadingSpinner, null) : null, h("div", {
className: "uppy-StatusBar-status"
}, h("div", {
className: "uppy-StatusBar-statusPrimary"
}, props.supportsUploadProgress ? title + ": " + props.totalProgress + "%" : title), !props.isAllPaused && !showUploadNewlyAddedFiles && props.showProgressDetails ? props.supportsUploadProgress ? h(ThrottledProgressDetails, props) : h(UnknownProgressDetails, props) : null, showUploadNewlyAddedFiles ? h(UploadNewlyAddedFiles, props) : null));
};
var ProgressBarComplete = function ProgressBarComplete(_ref2) {
var totalProgress = _ref2.totalProgress,
i18n = _ref2.i18n;
return h("div", {
className: "uppy-StatusBar-content",
role: "status",
title: i18n('complete')
}, h("div", {
className: "uppy-StatusBar-status"
}, h("div", {
className: "uppy-StatusBar-statusPrimary"
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-StatusBar-statusIndicator uppy-c-icon",
width: "15",
height: "11",
viewBox: "0 0 15 11"
}, h("path", {
d: "M.414 5.843L1.627 4.63l3.472 3.472L13.202 0l1.212 1.213L5.1 10.528z"
})), i18n('complete'))));
};
var ProgressBarError = function ProgressBarError(_ref3) {
var error = _ref3.error,
retryAll = _ref3.retryAll,
hideRetryButton = _ref3.hideRetryButton,
i18n = _ref3.i18n;
function displayErrorAlert() {
var errorMessage = i18n('uploadFailed') + " \n\n " + error;
alert(errorMessage);
}
return h("div", {
className: "uppy-StatusBar-content",
role: "alert",
title: i18n('uploadFailed')
}, h("div", {
className: "uppy-StatusBar-status"
}, h("div", {
className: "uppy-StatusBar-statusPrimary"
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-StatusBar-statusIndicator uppy-c-icon",
width: "11",
height: "11",
viewBox: "0 0 11 11"
}, h("path", {
d: "M4.278 5.5L0 1.222 1.222 0 5.5 4.278 9.778 0 11 1.222 6.722 5.5 11 9.778 9.778 11 5.5 6.722 1.222 11 0 9.778z"
})), i18n('uploadFailed'))), h("span", {
className: "uppy-StatusBar-details",
"aria-label": error,
"data-microtip-position": "top-right",
"data-microtip-size": "medium",
role: "tooltip",
onClick: displayErrorAlert
}, "?"));
};
},{"./StatusBarStates":167,"@transloadit/prettier-bytes":1,"@uppy/utils/lib/prettyETA":248,"classnames":11,"lodash.throttle":34,"preact":169}],167:[function(require,module,exports){
module.exports = {
STATE_ERROR: 'error',
STATE_WAITING: 'waiting',
STATE_PREPROCESSING: 'preprocessing',
STATE_UPLOADING: 'uploading',
STATE_POSTPROCESSING: 'postprocessing',
STATE_COMPLETE: 'complete'
};
},{}],168:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var StatusBarUI = require('./StatusBar');
var statusBarStates = require('./StatusBarStates');
var getSpeed = require('@uppy/utils/lib/getSpeed');
var getBytesRemaining = require('@uppy/utils/lib/getBytesRemaining');
var getTextDirection = require('@uppy/utils/lib/getTextDirection');
/**
* StatusBar: renders a status bar with upload/pause/resume/cancel/retry buttons,
* progress percentage and time remaining.
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(StatusBar, _Plugin);
function StatusBar(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.startUpload = function () {
var _this$uppy$getState = _this.uppy.getState(),
recoveredState = _this$uppy$getState.recoveredState;
if (recoveredState) {
_this.uppy.emit('restore-confirmed');
return;
}
return _this.uppy.upload().catch(function () {// Error logged in Core
});
};
_this.id = _this.opts.id || 'StatusBar';
_this.title = 'StatusBar';
_this.type = 'progressindicator';
_this.defaultLocale = {
strings: {
uploading: 'Uploading',
upload: 'Upload',
complete: 'Complete',
uploadFailed: 'Upload failed',
paused: 'Paused',
retry: 'Retry',
retryUpload: 'Retry upload',
cancel: 'Cancel',
pause: 'Pause',
resume: 'Resume',
done: 'Done',
filesUploadedOfTotal: {
0: '%{complete} of %{smart_count} file uploaded',
1: '%{complete} of %{smart_count} files uploaded'
},
dataUploadedOfTotal: '%{complete} of %{total}',
xTimeLeft: '%{time} left',
uploadXFiles: {
0: 'Upload %{smart_count} file',
1: 'Upload %{smart_count} files'
},
uploadXNewFiles: {
0: 'Upload +%{smart_count} file',
1: 'Upload +%{smart_count} files'
},
xMoreFilesAdded: {
0: '%{smart_count} more file added',
1: '%{smart_count} more files added'
}
}
}; // set default options
var defaultOptions = {
target: 'body',
hideUploadButton: false,
hideRetryButton: false,
hidePauseResumeButton: false,
hideCancelButton: false,
showProgressDetails: false,
hideAfterFinish: true,
doneButtonHandler: null
};
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this.render = _this.render.bind(_assertThisInitialized(_this));
_this.install = _this.install.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = StatusBar.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.getTotalSpeed = function getTotalSpeed(files) {
var totalSpeed = 0;
files.forEach(function (file) {
totalSpeed += getSpeed(file.progress);
});
return totalSpeed;
};
_proto.getTotalETA = function getTotalETA(files) {
var totalSpeed = this.getTotalSpeed(files);
if (totalSpeed === 0) {
return 0;
}
var totalBytesRemaining = files.reduce(function (total, file) {
return total + getBytesRemaining(file.progress);
}, 0);
return Math.round(totalBytesRemaining / totalSpeed * 10) / 10;
};
_proto.getUploadingState = function getUploadingState(isAllErrored, isAllComplete, recoveredState, files) {
if (isAllErrored) {
return statusBarStates.STATE_ERROR;
}
if (isAllComplete) {
return statusBarStates.STATE_COMPLETE;
}
if (recoveredState) {
return statusBarStates.STATE_WAITING;
}
var state = statusBarStates.STATE_WAITING;
var fileIDs = Object.keys(files);
for (var i = 0; i < fileIDs.length; i++) {
var progress = files[fileIDs[i]].progress; // If ANY files are being uploaded right now, show the uploading state.
if (progress.uploadStarted && !progress.uploadComplete) {
return statusBarStates.STATE_UPLOADING;
} // If files are being preprocessed AND postprocessed at this time, we show the
// preprocess state. If any files are being uploaded we show uploading.
if (progress.preprocess && state !== statusBarStates.STATE_UPLOADING) {
state = statusBarStates.STATE_PREPROCESSING;
} // If NO files are being preprocessed or uploaded right now, but some files are
// being postprocessed, show the postprocess state.
if (progress.postprocess && state !== statusBarStates.STATE_UPLOADING && state !== statusBarStates.STATE_PREPROCESSING) {
state = statusBarStates.STATE_POSTPROCESSING;
}
}
return state;
};
_proto.render = function render(state) {
var capabilities = state.capabilities,
files = state.files,
allowNewUpload = state.allowNewUpload,
totalProgress = state.totalProgress,
error = state.error,
recoveredState = state.recoveredState; // TODO: move this to Core, to share between Status Bar and Dashboard
// (and any other plugin that might need it, too)
var filesArray = Object.keys(files).map(function (file) {
return files[file];
});
var newFiles = filesArray.filter(function (file) {
return !file.progress.uploadStarted && !file.progress.preprocess && !file.progress.postprocess;
}); // If some state was recovered, we want to show Upload button/counter
// for all the files, because in this case it’s not an Upload button,
// but “Confirm Restore Button”
if (recoveredState) {
newFiles = filesArray;
}
var uploadStartedFiles = filesArray.filter(function (file) {
return file.progress.uploadStarted;
});
var pausedFiles = uploadStartedFiles.filter(function (file) {
return file.isPaused;
});
var completeFiles = filesArray.filter(function (file) {
return file.progress.uploadComplete;
});
var erroredFiles = filesArray.filter(function (file) {
return file.error;
});
var inProgressFiles = filesArray.filter(function (file) {
return !file.progress.uploadComplete && file.progress.uploadStarted;
});
var inProgressNotPausedFiles = inProgressFiles.filter(function (file) {
return !file.isPaused;
});
var startedFiles = filesArray.filter(function (file) {
return file.progress.uploadStarted || file.progress.preprocess || file.progress.postprocess;
});
var processingFiles = filesArray.filter(function (file) {
return file.progress.preprocess || file.progress.postprocess;
});
var totalETA = this.getTotalETA(inProgressNotPausedFiles);
var totalSize = 0;
var totalUploadedSize = 0;
startedFiles.forEach(function (file) {
totalSize += file.progress.bytesTotal || 0;
totalUploadedSize += file.progress.bytesUploaded || 0;
});
var isUploadStarted = startedFiles.length > 0;
var isAllComplete = totalProgress === 100 && completeFiles.length === Object.keys(files).length && processingFiles.length === 0;
var isAllErrored = error && erroredFiles.length === filesArray.length;
var isAllPaused = inProgressFiles.length !== 0 && pausedFiles.length === inProgressFiles.length;
var isUploadInProgress = inProgressFiles.length > 0;
var resumableUploads = capabilities.resumableUploads || false;
var supportsUploadProgress = capabilities.uploadProgress !== false;
var isSomeGhost = filesArray.some(function (file) {
return file.isGhost;
});
return StatusBarUI({
error: error,
uploadState: this.getUploadingState(isAllErrored, isAllComplete, recoveredState, state.files || {}),
allowNewUpload: allowNewUpload,
totalProgress: totalProgress,
totalSize: totalSize,
totalUploadedSize: totalUploadedSize,
isAllComplete: isAllComplete,
isAllPaused: isAllPaused,
isAllErrored: isAllErrored,
isUploadStarted: isUploadStarted,
isUploadInProgress: isUploadInProgress,
isSomeGhost: isSomeGhost,
recoveredState: recoveredState,
complete: completeFiles.length,
newFiles: newFiles.length,
numUploads: startedFiles.length,
totalETA: totalETA,
files: files,
i18n: this.i18n,
pauseAll: this.uppy.pauseAll,
resumeAll: this.uppy.resumeAll,
retryAll: this.uppy.retryAll,
cancelAll: this.uppy.cancelAll,
startUpload: this.startUpload,
doneButtonHandler: this.opts.doneButtonHandler,
resumableUploads: resumableUploads,
supportsUploadProgress: supportsUploadProgress,
showProgressDetails: this.opts.showProgressDetails,
hideUploadButton: this.opts.hideUploadButton,
hideRetryButton: this.opts.hideRetryButton,
hidePauseResumeButton: this.opts.hidePauseResumeButton,
hideCancelButton: this.opts.hideCancelButton,
hideAfterFinish: this.opts.hideAfterFinish,
isTargetDOMEl: this.isTargetDOMEl
});
};
_proto.onMount = function onMount() {
// Set the text direction if the page has not defined one.
var element = this.el;
var direction = getTextDirection(element);
if (!direction) {
element.dir = 'ltr';
}
};
_proto.install = function install() {
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.unmount();
};
return StatusBar;
}(Plugin), _class.VERSION = "1.9.6", _temp);
},{"./StatusBar":166,"./StatusBarStates":167,"@uppy/core":78,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/getBytesRemaining":228,"@uppy/utils/lib/getSpeed":238,"@uppy/utils/lib/getTextDirection":239}],169:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],170:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/**
* Default store that keeps state in a simple object.
*/
var DefaultStore = /*#__PURE__*/function () {
function DefaultStore() {
this.state = {};
this.callbacks = [];
}
var _proto = DefaultStore.prototype;
_proto.getState = function getState() {
return this.state;
};
_proto.setState = function setState(patch) {
var prevState = _extends({}, this.state);
var nextState = _extends({}, this.state, patch);
this.state = nextState;
this._publish(prevState, nextState, patch);
};
_proto.subscribe = function subscribe(listener) {
var _this = this;
this.callbacks.push(listener);
return function () {
// Remove the listener.
_this.callbacks.splice(_this.callbacks.indexOf(listener), 1);
};
};
_proto._publish = function _publish() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
this.callbacks.forEach(function (listener) {
listener.apply(void 0, args);
});
};
return DefaultStore;
}();
DefaultStore.VERSION = "1.2.7";
module.exports = function defaultStore() {
return new DefaultStore();
};
},{}],171:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var cuid = require('cuid'); // Redux action name.
var STATE_UPDATE = 'uppy/STATE_UPDATE'; // Pluck Uppy state from the Redux store in the default location.
var defaultSelector = function defaultSelector(id) {
return function (state) {
return state.uppy[id];
};
};
/**
* Redux store.
*
* @param {object} opts.store - The Redux store to use.
* @param {string} opts.id - This store instance's ID. Defaults to a random string.
* If you need to access Uppy state through Redux, eg. to render custom UI, set this to something constant.
* @param {Function} opts.selector - Function, `(state) => uppyState`, to pluck state from the Redux store.
* Defaults to retrieving `state.uppy[opts.id]`. Override if you placed Uppy state elsewhere in the Redux store.
*/
var ReduxStore = /*#__PURE__*/function () {
function ReduxStore(opts) {
this._store = opts.store;
this._id = opts.id || cuid();
this._selector = opts.selector || defaultSelector(this._id); // Calling `setState` to dispatch an action to the Redux store.
// The intent is to make sure that the reducer has run once.
this.setState({});
}
var _proto = ReduxStore.prototype;
_proto.setState = function setState(patch) {
this._store.dispatch({
type: STATE_UPDATE,
id: this._id,
payload: patch
});
};
_proto.getState = function getState() {
return this._selector(this._store.getState());
};
_proto.subscribe = function subscribe(cb) {
var _this = this;
var prevState = this.getState();
return this._store.subscribe(function () {
var nextState = _this.getState();
if (prevState !== nextState) {
var patch = getPatch(prevState, nextState);
cb(prevState, nextState, patch);
prevState = nextState;
}
});
};
return ReduxStore;
}();
ReduxStore.VERSION = "1.2.8";
function getPatch(prev, next) {
var nextKeys = Object.keys(next);
var patch = {};
nextKeys.forEach(function (k) {
if (prev[k] !== next[k]) patch[k] = next[k];
});
return patch;
}
function reducer(state, action) {
if (state === void 0) {
state = {};
}
if (action.type === STATE_UPDATE) {
var _extends2;
var newState = _extends({}, state[action.id], action.payload);
return _extends({}, state, (_extends2 = {}, _extends2[action.id] = newState, _extends2));
}
return state;
}
function middleware() {
// Do nothing, at the moment.
return function () {
return function (next) {
return function (action) {
next(action);
};
};
};
}
module.exports = function createReduxStore(opts) {
return new ReduxStore(opts);
};
module.exports.STATE_UPDATE = STATE_UPDATE;
module.exports.reducer = reducer;
module.exports.middleware = middleware;
},{"cuid":15}],172:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var dataURItoBlob = require('@uppy/utils/lib/dataURItoBlob');
var isObjectURL = require('@uppy/utils/lib/isObjectURL');
var isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported');
var MathLog2 = require('math-log2'); // Polyfill for IE.
var exifr = require('exifr/dist/mini.legacy.umd.js');
/**
* The Thumbnail Generator plugin
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(ThumbnailGenerator, _Plugin);
function ThumbnailGenerator(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.onFileAdded = function (file) {
if (!file.preview && file.data && isPreviewSupported(file.type) && !file.isRemote) {
_this.addToQueue(file.id);
}
};
_this.onCancelRequest = function (file) {
var index = _this.queue.indexOf(file.id);
if (index !== -1) {
_this.queue.splice(index, 1);
}
};
_this.onFileRemoved = function (file) {
var index = _this.queue.indexOf(file.id);
if (index !== -1) {
_this.queue.splice(index, 1);
} // Clean up object URLs.
if (file.preview && isObjectURL(file.preview)) {
URL.revokeObjectURL(file.preview);
}
};
_this.onRestored = function () {
var restoredFiles = _this.uppy.getFiles().filter(function (file) {
return file.isRestored;
});
restoredFiles.forEach(function (file) {
// Only add blob URLs; they are likely invalid after being restored.
if (!file.preview || isObjectURL(file.preview)) {
_this.addToQueue(file.id);
}
});
};
_this.waitUntilAllProcessed = function (fileIDs) {
fileIDs.forEach(function (fileID) {
var file = _this.uppy.getFile(fileID);
_this.uppy.emit('preprocess-progress', file, {
mode: 'indeterminate',
message: _this.i18n('generatingThumbnails')
});
});
var emitPreprocessCompleteForAll = function emitPreprocessCompleteForAll() {
fileIDs.forEach(function (fileID) {
var file = _this.uppy.getFile(fileID);
_this.uppy.emit('preprocess-complete', file);
});
};
return new Promise(function (resolve, reject) {
if (_this.queueProcessing) {
_this.uppy.once('thumbnail:all-generated', function () {
emitPreprocessCompleteForAll();
resolve();
});
} else {
emitPreprocessCompleteForAll();
resolve();
}
});
};
_this.type = 'modifier';
_this.id = _this.opts.id || 'ThumbnailGenerator';
_this.title = 'Thumbnail Generator';
_this.queue = [];
_this.queueProcessing = false;
_this.defaultThumbnailDimension = 200;
_this.thumbnailType = _this.opts.thumbnailType || 'image/jpeg';
_this.defaultLocale = {
strings: {
generatingThumbnails: 'Generating thumbnails...'
}
};
var defaultOptions = {
thumbnailWidth: null,
thumbnailHeight: null,
waitForThumbnailsBeforeUpload: false,
lazy: false
};
_this.opts = _extends({}, defaultOptions, opts);
if (_this.opts.lazy && _this.opts.waitForThumbnailsBeforeUpload) {
throw new Error('ThumbnailGenerator: The `lazy` and `waitForThumbnailsBeforeUpload` options are mutually exclusive. Please ensure at most one of them is set to `true`.');
}
_this.i18nInit();
return _this;
}
var _proto = ThumbnailGenerator.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
}
/**
* Create a thumbnail for the given Uppy file object.
*
* @param {{data: Blob}} file
* @param {number} targetWidth
* @param {number} targetHeight
* @returns {Promise}
*/
;
_proto.createThumbnail = function createThumbnail(file, targetWidth, targetHeight) {
var _this2 = this;
// bug in the compatibility data
// eslint-disable-next-line compat/compat
var originalUrl = URL.createObjectURL(file.data);
var onload = new Promise(function (resolve, reject) {
var image = new Image();
image.src = originalUrl;
image.addEventListener('load', function () {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
URL.revokeObjectURL(originalUrl);
resolve(image);
});
image.addEventListener('error', function (event) {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
URL.revokeObjectURL(originalUrl);
reject(event.error || new Error('Could not create thumbnail'));
});
});
var orientationPromise = exifr.rotation(file.data).catch(function (_err) {
return 1;
});
return Promise.all([onload, orientationPromise]).then(function (_ref) {
var image = _ref[0],
orientation = _ref[1];
var dimensions = _this2.getProportionalDimensions(image, targetWidth, targetHeight, orientation.deg);
var rotatedImage = _this2.rotateImage(image, orientation);
var resizedImage = _this2.resizeImage(rotatedImage, dimensions.width, dimensions.height);
return _this2.canvasToBlob(resizedImage, _this2.thumbnailType, 80);
}).then(function (blob) {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
return URL.createObjectURL(blob);
});
}
/**
* Get the new calculated dimensions for the given image and a target width
* or height. If both width and height are given, only width is taken into
* account. If neither width nor height are given, the default dimension
* is used.
*/
;
_proto.getProportionalDimensions = function getProportionalDimensions(img, width, height, rotation) {
var aspect = img.width / img.height;
if (rotation === 90 || rotation === 270) {
aspect = img.height / img.width;
}
if (width != null) {
return {
width: width,
height: Math.round(width / aspect)
};
}
if (height != null) {
return {
width: Math.round(height * aspect),
height: height
};
}
return {
width: this.defaultThumbnailDimension,
height: Math.round(this.defaultThumbnailDimension / aspect)
};
}
/**
* Make sure the image doesn’t exceed browser/device canvas limits.
* For ios with 256 RAM and ie
*/
;
_proto.protect = function protect(image) {
// https://stackoverflow.com/questions/6081483/maximum-size-of-a-canvas-element
var ratio = image.width / image.height;
var maxSquare = 5000000; // ios max canvas square
var maxSize = 4096; // ie max canvas dimensions
var maxW = Math.floor(Math.sqrt(maxSquare * ratio));
var maxH = Math.floor(maxSquare / Math.sqrt(maxSquare * ratio));
if (maxW > maxSize) {
maxW = maxSize;
maxH = Math.round(maxW / ratio);
}
if (maxH > maxSize) {
maxH = maxSize;
maxW = Math.round(ratio * maxH);
}
if (image.width > maxW) {
var canvas = document.createElement('canvas');
canvas.width = maxW;
canvas.height = maxH;
canvas.getContext('2d').drawImage(image, 0, 0, maxW, maxH);
image = canvas;
}
return image;
}
/**
* Resize an image to the target `width` and `height`.
*
* Returns a Canvas with the resized image on it.
*/
;
_proto.resizeImage = function resizeImage(image, targetWidth, targetHeight) {
// Resizing in steps refactored to use a solution from
// https://blog.uploadcare.com/image-resize-in-browsers-is-broken-e38eed08df01
image = this.protect(image);
var steps = Math.ceil(MathLog2(image.width / targetWidth));
if (steps < 1) {
steps = 1;
}
var sW = targetWidth * Math.pow(2, steps - 1);
var sH = targetHeight * Math.pow(2, steps - 1);
var x = 2;
while (steps--) {
var canvas = document.createElement('canvas');
canvas.width = sW;
canvas.height = sH;
canvas.getContext('2d').drawImage(image, 0, 0, sW, sH);
image = canvas;
sW = Math.round(sW / x);
sH = Math.round(sH / x);
}
return image;
};
_proto.rotateImage = function rotateImage(image, translate) {
var w = image.width;
var h = image.height;
if (translate.deg === 90 || translate.deg === 270) {
w = image.height;
h = image.width;
}
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var context = canvas.getContext('2d');
context.translate(w / 2, h / 2);
if (translate.canvas) {
context.rotate(translate.rad);
context.scale(translate.scaleX, translate.scaleY);
}
context.drawImage(image, -image.width / 2, -image.height / 2, image.width, image.height);
return canvas;
}
/**
* Save a <canvas> element's content to a Blob object.
*
* @param {HTMLCanvasElement} canvas
* @returns {Promise}
*/
;
_proto.canvasToBlob = function canvasToBlob(canvas, type, quality) {
try {
canvas.getContext('2d').getImageData(0, 0, 1, 1);
} catch (err) {
if (err.code === 18) {
return Promise.reject(new Error('cannot read image, probably an svg with external resources'));
}
}
if (canvas.toBlob) {
return new Promise(function (resolve) {
canvas.toBlob(resolve, type, quality);
}).then(function (blob) {
if (blob === null) {
throw new Error('cannot read image, probably an svg with external resources');
}
return blob;
});
}
return Promise.resolve().then(function () {
return dataURItoBlob(canvas.toDataURL(type, quality), {});
}).then(function (blob) {
if (blob === null) {
throw new Error('could not extract blob, probably an old browser');
}
return blob;
});
}
/**
* Set the preview URL for a file.
*/
;
_proto.setPreviewURL = function setPreviewURL(fileID, preview) {
this.uppy.setFileState(fileID, {
preview: preview
});
};
_proto.addToQueue = function addToQueue(item) {
this.queue.push(item);
if (this.queueProcessing === false) {
this.processQueue();
}
};
_proto.processQueue = function processQueue() {
var _this3 = this;
this.queueProcessing = true;
if (this.queue.length > 0) {
var current = this.uppy.getFile(this.queue.shift());
if (!current) {
this.uppy.log('[ThumbnailGenerator] file was removed before a thumbnail could be generated, but not removed from the queue. This is probably a bug', 'error');
return;
}
return this.requestThumbnail(current).catch(function (err) {}) // eslint-disable-line handle-callback-err
.then(function () {
return _this3.processQueue();
});
}
this.queueProcessing = false;
this.uppy.log('[ThumbnailGenerator] Emptied thumbnail queue');
this.uppy.emit('thumbnail:all-generated');
};
_proto.requestThumbnail = function requestThumbnail(file) {
var _this4 = this;
if (isPreviewSupported(file.type) && !file.isRemote) {
return this.createThumbnail(file, this.opts.thumbnailWidth, this.opts.thumbnailHeight).then(function (preview) {
_this4.setPreviewURL(file.id, preview);
_this4.uppy.log("[ThumbnailGenerator] Generated thumbnail for " + file.id);
_this4.uppy.emit('thumbnail:generated', _this4.uppy.getFile(file.id), preview);
}).catch(function (err) {
_this4.uppy.log("[ThumbnailGenerator] Failed thumbnail for " + file.id + ":", 'warning');
_this4.uppy.log(err, 'warning');
_this4.uppy.emit('thumbnail:error', _this4.uppy.getFile(file.id), err);
});
}
return Promise.resolve();
};
_proto.install = function install() {
this.uppy.on('file-removed', this.onFileRemoved);
if (this.opts.lazy) {
this.uppy.on('thumbnail:request', this.onFileAdded);
this.uppy.on('thumbnail:cancel', this.onCancelRequest);
} else {
this.uppy.on('file-added', this.onFileAdded);
this.uppy.on('restored', this.onRestored);
}
if (this.opts.waitForThumbnailsBeforeUpload) {
this.uppy.addPreProcessor(this.waitUntilAllProcessed);
}
};
_proto.uninstall = function uninstall() {
this.uppy.off('file-removed', this.onFileRemoved);
if (this.opts.lazy) {
this.uppy.off('thumbnail:request', this.onFileAdded);
this.uppy.off('thumbnail:cancel', this.onCancelRequest);
} else {
this.uppy.off('file-added', this.onFileAdded);
this.uppy.off('restored', this.onRestored);
}
if (this.opts.waitForThumbnailsBeforeUpload) {
this.uppy.removePreProcessor(this.waitUntilAllProcessed);
}
};
return ThumbnailGenerator;
}(Plugin), _class.VERSION = "1.7.11", _temp);
},{"@uppy/core":78,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/dataURItoBlob":220,"@uppy/utils/lib/isObjectURL":245,"@uppy/utils/lib/isPreviewSupported":246,"exifr/dist/mini.legacy.umd.js":24,"math-log2":35}],173:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var io = requireSocketIo;
var Emitter = require('component-emitter');
var has = require('@uppy/utils/lib/hasProperty');
var parseUrl = require('./parseUrl');
var NetworkError = require('@uppy/utils/lib/NetworkError');
var fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError'); // Lazy load socket.io to avoid a console error
// in IE 10 when the Transloadit plugin is not used.
// (The console.error call comes from `buffer`. I
// think we actually don't use that part of socket.io
// at all…)
var socketIo;
function requireSocketIo() {
if (!socketIo) {
socketIo = require('socket.io-client');
}
return socketIo;
}
var ASSEMBLY_UPLOADING = 'ASSEMBLY_UPLOADING';
var ASSEMBLY_EXECUTING = 'ASSEMBLY_EXECUTING';
var ASSEMBLY_COMPLETED = 'ASSEMBLY_COMPLETED';
var statusOrder = [ASSEMBLY_UPLOADING, ASSEMBLY_EXECUTING, ASSEMBLY_COMPLETED];
/**
* Check that an assembly status is equal to or larger than some desired status.
* It checks for things that are larger so that a comparison like this works,
* when the old assembly status is UPLOADING but the new is FINISHED:
*
* !isStatus(oldStatus, ASSEMBLY_EXECUTING) && isStatus(newState, ASSEMBLY_EXECUTING)
*
* …so that we can emit the 'executing' event even if the execution step was so
* fast that we missed it.
*/
function isStatus(status, test) {
return statusOrder.indexOf(status) >= statusOrder.indexOf(test);
}
var TransloaditAssembly = /*#__PURE__*/function (_Emitter) {
_inheritsLoose(TransloaditAssembly, _Emitter);
function TransloaditAssembly(assembly) {
var _this;
_this = _Emitter.call(this) || this; // The current assembly status.
_this.status = assembly; // The socket.io connection.
_this.socket = null; // The interval timer for full status updates.
_this.pollInterval = null; // Whether this assembly has been closed (finished or errored)
_this.closed = false;
return _this;
}
var _proto = TransloaditAssembly.prototype;
_proto.connect = function connect() {
this._connectSocket();
this._beginPolling();
};
_proto._onFinished = function _onFinished() {
this.emit('finished');
this.close();
};
_proto._connectSocket = function _connectSocket() {
var _this2 = this;
var parsed = parseUrl(this.status.websocket_url);
var socket = io().connect(parsed.origin, {
transports: ['websocket'],
path: parsed.pathname
});
socket.on('connect', function () {
socket.emit('assembly_connect', {
id: _this2.status.assembly_id
});
_this2.emit('connect');
});
socket.on('connect_failed', function () {
_this2._onError(new NetworkError('Transloadit Socket.io connection error'));
_this2.socket = null;
});
socket.on('error', function () {
socket.disconnect();
_this2.socket = null;
});
socket.on('assembly_finished', function () {
_this2._onFinished();
});
socket.on('assembly_upload_finished', function (file) {
_this2.emit('upload', file);
_this2.status.uploads.push(file);
});
socket.on('assembly_uploading_finished', function () {
_this2.emit('executing');
});
socket.on('assembly_upload_meta_data_extracted', function () {
_this2.emit('metadata');
_this2._fetchStatus({
diff: false
});
});
socket.on('assembly_result_finished', function (stepName, result) {
_this2.emit('result', stepName, result);
if (!_this2.status.results[stepName]) {
_this2.status.results[stepName] = [];
}
_this2.status.results[stepName].push(result);
});
socket.on('assembly_error', function (err) {
_this2._onError(err); // Refetch for updated status code
_this2._fetchStatus({
diff: false
});
});
this.socket = socket;
};
_proto._onError = function _onError(err) {
this.emit('error', _extends(new Error(err.message), err));
}
/**
* Begin polling for assembly status changes. This sends a request to the
* assembly status endpoint every so often, if the socket is not connected.
* If the socket connection fails or takes a long time, we won't miss any
* events.
*/
;
_proto._beginPolling = function _beginPolling() {
var _this3 = this;
this.pollInterval = setInterval(function () {
if (!_this3.socket || !_this3.socket.connected) {
_this3._fetchStatus();
}
}, 2000);
}
/**
* Reload assembly status. Useful if the socket doesn't work.
*
* Pass `diff: false` to avoid emitting diff events, instead only emitting
* 'status'.
*/
;
_proto._fetchStatus = function _fetchStatus(_temp) {
var _this4 = this;
var _ref = _temp === void 0 ? {} : _temp,
_ref$diff = _ref.diff,
diff = _ref$diff === void 0 ? true : _ref$diff;
return fetchWithNetworkError(this.status.assembly_ssl_url).then(function (response) {
return response.json();
}).then(function (status) {
// Avoid updating if we closed during this request's lifetime.
if (_this4.closed) return;
_this4.emit('status', status);
if (diff) {
_this4.updateStatus(status);
} else {
_this4.status = status;
}
}).catch(function (err) {
return _this4._onError(err);
});
};
_proto.update = function update() {
return this._fetchStatus({
diff: true
});
}
/**
* Update this assembly's status with a full new object. Events will be
* emitted for status changes, new files, and new results.
*
* @param {object} next The new assembly status object.
*/
;
_proto.updateStatus = function updateStatus(next) {
this._diffStatus(this.status, next);
this.status = next;
}
/**
* Diff two assembly statuses, and emit the events necessary to go from `prev`
* to `next`.
*
* @param {object} prev The previous assembly status.
* @param {object} next The new assembly status.
*/
;
_proto._diffStatus = function _diffStatus(prev, next) {
var _this5 = this;
var prevStatus = prev.ok;
var nextStatus = next.ok;
if (next.error && !prev.error) {
return this._onError(next);
} // Desired emit order:
// - executing
// - (n × upload)
// - metadata
// - (m × result)
// - finished
// The below checks run in this order, that way even if we jump from
// UPLOADING straight to FINISHED all the events are emitted as expected.
var nowExecuting = isStatus(nextStatus, ASSEMBLY_EXECUTING) && !isStatus(prevStatus, ASSEMBLY_EXECUTING);
if (nowExecuting) {
// Without WebSockets, this is our only way to tell if uploading finished.
// Hence, we emit this just before the 'upload's and before the 'metadata'
// event for the most intuitive ordering, corresponding to the _usual_
// ordering (if not guaranteed) that you'd get on the WebSocket.
this.emit('executing');
} // Find new uploaded files.
Object.keys(next.uploads).filter(function (upload) {
return !has(prev.uploads, upload);
}).map(function (upload) {
return next.uploads[upload];
}).forEach(function (upload) {
_this5.emit('upload', upload);
});
if (nowExecuting) {
this.emit('metadata');
} // Find new results.
Object.keys(next.results).forEach(function (stepName) {
var nextResults = next.results[stepName];
var prevResults = prev.results[stepName];
nextResults.filter(function (n) {
return !prevResults || !prevResults.some(function (p) {
return p.id === n.id;
});
}).forEach(function (result) {
_this5.emit('result', stepName, result);
});
});
if (isStatus(nextStatus, ASSEMBLY_COMPLETED) && !isStatus(prevStatus, ASSEMBLY_COMPLETED)) {
this.emit('finished');
}
}
/**
* Stop updating this assembly.
*/
;
_proto.close = function close() {
this.closed = true;
if (this.socket) {
this.socket.disconnect();
this.socket = null;
}
clearInterval(this.pollInterval);
};
return TransloaditAssembly;
}(Emitter);
module.exports = TransloaditAssembly;
},{"./parseUrl":178,"@uppy/utils/lib/NetworkError":215,"@uppy/utils/lib/fetchWithNetworkError":223,"@uppy/utils/lib/hasProperty":241,"component-emitter":179,"socket.io-client":195}],174:[function(require,module,exports){
/**
* Check that Assembly parameters are present and include all required fields.
*/
function validateParams(params) {
if (!params) {
throw new Error('Transloadit: The `params` option is required.');
}
if (typeof params === 'string') {
try {
params = JSON.parse(params);
} catch (err) {
// Tell the user that this is not an Uppy bug!
err.message = "Transloadit: The `params` option is a malformed JSON string: " + err.message;
throw err;
}
}
if (!params.auth || !params.auth.key) {
throw new Error('Transloadit: The `params.auth.key` option is required. ' + 'You can find your Transloadit API key at https://transloadit.com/account/api-settings.');
}
}
/**
* Turn Transloadit plugin options and a list of files into a list of Assembly
* options.
*/
var AssemblyOptions = /*#__PURE__*/function () {
function AssemblyOptions(files, opts) {
this.files = files;
this.opts = opts;
}
/**
* Normalize Uppy-specific Assembly option features to a Transloadit-
* compatible object.
*/
var _proto = AssemblyOptions.prototype;
_proto._normalizeAssemblyOptions = function _normalizeAssemblyOptions(file, assemblyOptions) {
if (Array.isArray(assemblyOptions.fields)) {
var fieldNames = assemblyOptions.fields;
assemblyOptions.fields = {};
fieldNames.forEach(function (fieldName) {
assemblyOptions.fields[fieldName] = file.meta[fieldName];
});
}
if (!assemblyOptions.fields) {
assemblyOptions.fields = {};
}
return assemblyOptions;
}
/**
* Get Assembly options for a file.
*/
;
_proto._getAssemblyOptions = function _getAssemblyOptions(file) {
var _this = this;
var options = this.opts;
return Promise.resolve().then(function () {
return options.getAssemblyOptions(file, options);
}).then(function (assemblyOptions) {
return _this._normalizeAssemblyOptions(file, assemblyOptions);
}).then(function (assemblyOptions) {
validateParams(assemblyOptions.params);
return {
fileIDs: [file.id],
options: assemblyOptions
};
});
}
/**
* Combine Assemblies with the same options into a single Assembly for all the
* relevant files.
*/
;
_proto._dedupe = function _dedupe(list) {
var dedupeMap = Object.create(null);
list.forEach(function (_ref) {
var fileIDs = _ref.fileIDs,
options = _ref.options;
var id = JSON.stringify(options);
if (dedupeMap[id]) {
var _dedupeMap$id$fileIDs;
(_dedupeMap$id$fileIDs = dedupeMap[id].fileIDs).push.apply(_dedupeMap$id$fileIDs, fileIDs);
} else {
dedupeMap[id] = {
options: options,
fileIDs: [].concat(fileIDs)
};
}
});
return Object.keys(dedupeMap).map(function (id) {
return dedupeMap[id];
});
}
/**
* Generate a set of Assemblies that will handle the upload.
* Returns a Promise for an object with keys:
* - fileIDs - an array of file IDs to add to this Assembly
* - options - Assembly options
*/
;
_proto.build = function build() {
var _this2 = this;
var options = this.opts;
if (this.files.length > 0) {
return Promise.all(this.files.map(function (file) {
return _this2._getAssemblyOptions(file);
})).then(function (list) {
return _this2._dedupe(list);
});
}
if (options.alwaysRunAssembly) {
// No files, just generate one Assembly
return Promise.resolve(options.getAssemblyOptions(null, options)).then(function (assemblyOptions) {
validateParams(assemblyOptions.params);
return [{
fileIDs: _this2.files.map(function (file) {
return file.id;
}),
options: assemblyOptions
}];
});
} // If there are no files and we do not `alwaysRunAssembly`,
// don't do anything.
return Promise.resolve([]);
};
return AssemblyOptions;
}();
module.exports = AssemblyOptions;
module.exports.validateParams = validateParams;
},{}],175:[function(require,module,exports){
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var Emitter = require('component-emitter');
/**
* Track completion of multiple assemblies.
*
* Emits 'assembly-complete' when an assembly completes.
* Emits 'assembly-error' when an assembly fails.
* Exposes a `.promise` property that resolves when all assemblies have
* completed (or failed).
*/
var TransloaditAssemblyWatcher = /*#__PURE__*/function (_Emitter) {
_inheritsLoose(TransloaditAssemblyWatcher, _Emitter);
function TransloaditAssemblyWatcher(uppy, assemblyIDs) {
var _this;
_this = _Emitter.call(this) || this;
_this._uppy = uppy;
_this._assemblyIDs = assemblyIDs;
_this._remaining = assemblyIDs.length;
_this.promise = new Promise(function (resolve, reject) {
_this._resolve = resolve;
_this._reject = reject;
});
_this._onAssemblyComplete = _this._onAssemblyComplete.bind(_assertThisInitialized(_this));
_this._onAssemblyCancel = _this._onAssemblyCancel.bind(_assertThisInitialized(_this));
_this._onAssemblyError = _this._onAssemblyError.bind(_assertThisInitialized(_this));
_this._onImportError = _this._onImportError.bind(_assertThisInitialized(_this));
_this._addListeners();
return _this;
}
/**
* Are we watching this assembly ID?
*/
var _proto = TransloaditAssemblyWatcher.prototype;
_proto._watching = function _watching(id) {
return this._assemblyIDs.indexOf(id) !== -1;
};
_proto._onAssemblyComplete = function _onAssemblyComplete(assembly) {
if (!this._watching(assembly.assembly_id)) {
return;
}
this._uppy.log("[Transloadit] AssemblyWatcher: Got Assembly finish " + assembly.assembly_id);
this.emit('assembly-complete', assembly.assembly_id);
this._checkAllComplete();
};
_proto._onAssemblyCancel = function _onAssemblyCancel(assembly) {
if (!this._watching(assembly.assembly_id)) {
return;
}
this._checkAllComplete();
};
_proto._onAssemblyError = function _onAssemblyError(assembly, error) {
if (!this._watching(assembly.assembly_id)) {
return;
}
this._uppy.log("[Transloadit] AssemblyWatcher: Got Assembly error " + assembly.assembly_id);
this._uppy.log(error);
this.emit('assembly-error', assembly.assembly_id, error);
this._checkAllComplete();
};
_proto._onImportError = function _onImportError(assembly, fileID, error) {
if (!this._watching(assembly.assembly_id)) {
return;
} // Not sure if we should be doing something when it's just one file failing.
// ATM, the only options are 1) ignoring or 2) failing the entire upload.
// I think failing the upload is better than silently ignoring.
// In the future we should maybe have a way to resolve uploads with some failures,
// like returning an object with `{ successful, failed }` uploads.
this._onAssemblyError(assembly, error);
};
_proto._checkAllComplete = function _checkAllComplete() {
this._remaining -= 1;
if (this._remaining === 0) {
// We're done, these listeners can be removed
this._removeListeners();
this._resolve();
}
};
_proto._removeListeners = function _removeListeners() {
this._uppy.off('transloadit:complete', this._onAssemblyComplete);
this._uppy.off('transloadit:assembly-cancel', this._onAssemblyCancel);
this._uppy.off('transloadit:assembly-error', this._onAssemblyError);
this._uppy.off('transloadit:import-error', this._onImportError);
};
_proto._addListeners = function _addListeners() {
this._uppy.on('transloadit:complete', this._onAssemblyComplete);
this._uppy.on('transloadit:assembly-cancel', this._onAssemblyCancel);
this._uppy.on('transloadit:assembly-error', this._onAssemblyError);
this._uppy.on('transloadit:import-error', this._onImportError);
};
return TransloaditAssemblyWatcher;
}(Emitter);
module.exports = TransloaditAssemblyWatcher;
},{"component-emitter":179}],176:[function(require,module,exports){
var fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError');
var URL = require('url-parse');
/**
* A Barebones HTTP API client for Transloadit.
*/
module.exports = /*#__PURE__*/function () {
function Client(opts) {
if (opts === void 0) {
opts = {};
}
this.opts = opts;
this._reportError = this._reportError.bind(this);
this._headers = {
'Transloadit-Client': this.opts.client
};
}
/**
* Create a new assembly.
*
* @param {object} options
* @param {string|object} options.params
* @param {object} options.fields
* @param {string} options.signature
* @param {number} options.expectedFiles
*/
var _proto = Client.prototype;
_proto.createAssembly = function createAssembly(_ref) {
var _this = this;
var params = _ref.params,
fields = _ref.fields,
signature = _ref.signature,
expectedFiles = _ref.expectedFiles;
var data = new FormData();
data.append('params', typeof params === 'string' ? params : JSON.stringify(params));
if (signature) {
data.append('signature', signature);
}
Object.keys(fields).forEach(function (key) {
data.append(key, fields[key]);
});
data.append('num_expected_upload_files', expectedFiles);
var url = new URL('/assemblies', "" + this.opts.service).href;
return fetchWithNetworkError(url, {
method: 'post',
headers: this._headers,
body: data
}).then(function (response) {
return response.json();
}).then(function (assembly) {
if (assembly.error) {
var error = new Error(assembly.error);
error.details = assembly.message;
error.assembly = assembly;
if (assembly.assembly_id) {
error.details += ' ' + ("Assembly ID: " + assembly.assembly_id);
}
throw error;
}
return assembly;
}).catch(function (err) {
return _this._reportError(err, {
url: url,
type: 'API_ERROR'
});
});
}
/**
* Reserve resources for a file in an Assembly. Then addFile can be used later.
*
* @param {object} assembly
* @param {UppyFile} file
*/
;
_proto.reserveFile = function reserveFile(assembly, file) {
var _this2 = this;
var size = encodeURIComponent(file.size);
var url = assembly.assembly_ssl_url + "/reserve_file?size=" + size;
return fetchWithNetworkError(url, {
method: 'post',
headers: this._headers
}).then(function (response) {
return response.json();
}).catch(function (err) {
return _this2._reportError(err, {
assembly: assembly,
file: file,
url: url,
type: 'API_ERROR'
});
});
}
/**
* Import a remote file to an Assembly.
*
* @param {object} assembly
* @param {UppyFile} file
*/
;
_proto.addFile = function addFile(assembly, file) {
var _this3 = this;
if (!file.uploadURL) {
return Promise.reject(new Error('File does not have an `uploadURL`.'));
}
var size = encodeURIComponent(file.size);
var uploadUrl = encodeURIComponent(file.uploadURL);
var filename = encodeURIComponent(file.name);
var fieldname = 'file';
var qs = "size=" + size + "&filename=" + filename + "&fieldname=" + fieldname + "&s3Url=" + uploadUrl;
var url = assembly.assembly_ssl_url + "/add_file?" + qs;
return fetchWithNetworkError(url, {
method: 'post',
headers: this._headers
}).then(function (response) {
return response.json();
}).catch(function (err) {
return _this3._reportError(err, {
assembly: assembly,
file: file,
url: url,
type: 'API_ERROR'
});
});
}
/**
* Cancel a running Assembly.
*
* @param {object} assembly
*/
;
_proto.cancelAssembly = function cancelAssembly(assembly) {
var _this4 = this;
var url = assembly.assembly_ssl_url;
return fetchWithNetworkError(url, {
method: 'delete',
headers: this._headers
}).then(function (response) {
return response.json();
}).catch(function (err) {
return _this4._reportError(err, {
url: url,
type: 'API_ERROR'
});
});
}
/**
* Get the current status for an assembly.
*
* @param {string} url The status endpoint of the assembly.
*/
;
_proto.getAssemblyStatus = function getAssemblyStatus(url) {
var _this5 = this;
return fetchWithNetworkError(url, {
headers: this._headers
}).then(function (response) {
return response.json();
}).catch(function (err) {
return _this5._reportError(err, {
url: url,
type: 'STATUS_ERROR'
});
});
};
_proto.submitError = function submitError(err, _ref2) {
var endpoint = _ref2.endpoint,
instance = _ref2.instance,
assembly = _ref2.assembly;
var message = err.details ? err.message + " (" + err.details + ")" : err.message;
return fetchWithNetworkError('https://transloaditstatus.com/client_error', {
method: 'post',
body: JSON.stringify({
endpoint: endpoint,
instance: instance,
assembly_id: assembly,
agent: typeof navigator !== 'undefined' ? navigator.userAgent : '',
client: this.opts.client,
error: message
})
}).then(function (response) {
return response.json();
});
};
_proto._reportError = function _reportError(err, params) {
if (this.opts.errorReporting === false) {
throw err;
}
var opts = {
type: params.type
};
if (params.assembly) {
opts.assembly = params.assembly.assembly_id;
opts.instance = params.assembly.instance;
}
if (params.url) {
opts.endpoint = params.url;
}
this.submitError(err, opts).catch(function (_) {// not much we can do then is there
});
throw err;
};
return Client;
}();
},{"@uppy/utils/lib/fetchWithNetworkError":223,"url-parse":59}],177:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var Translator = require('@uppy/utils/lib/Translator');
var hasProperty = require('@uppy/utils/lib/hasProperty');
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Tus = require('@uppy/tus');
var Assembly = require('./Assembly');
var Client = require('./Client');
var AssemblyOptions = require('./AssemblyOptions');
var AssemblyWatcher = require('./AssemblyWatcher');
function defaultGetAssemblyOptions(file, options) {
return {
params: options.params,
signature: options.signature,
fields: options.fields
};
}
var COMPANION = 'https://api2.transloadit.com/companion'; // Regex matching acceptable postMessage() origins for authentication feedback from companion.
var ALLOWED_COMPANION_PATTERN = /\.transloadit\.com$/; // Regex used to check if a Companion address is run by Transloadit.
var TL_COMPANION = /https?:\/\/api2(?:-\w+)?\.transloadit\.com\/companion/;
var TL_UPPY_SERVER = /https?:\/\/api2(?:-\w+)?\.transloadit\.com\/uppy-server/;
/**
* Upload files to Transloadit using Tus.
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Transloadit, _Plugin);
function Transloadit(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'uploader';
_this.id = _this.opts.id || 'Transloadit';
_this.title = 'Transloadit';
_this.defaultLocale = {
strings: {
creatingAssembly: 'Preparing upload...',
creatingAssemblyFailed: 'Transloadit: Could not create Assembly',
encoding: 'Encoding...'
}
};
var defaultOptions = {
service: 'https://api2.transloadit.com',
errorReporting: true,
waitForEncoding: false,
waitForMetadata: false,
alwaysRunAssembly: false,
importFromUploadURLs: false,
signature: null,
params: null,
fields: {},
getAssemblyOptions: defaultGetAssemblyOptions,
limit: 0
};
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this._prepareUpload = _this._prepareUpload.bind(_assertThisInitialized(_this));
_this._afterUpload = _this._afterUpload.bind(_assertThisInitialized(_this));
_this._onError = _this._onError.bind(_assertThisInitialized(_this));
_this._onTusError = _this._onTusError.bind(_assertThisInitialized(_this));
_this._onCancelAll = _this._onCancelAll.bind(_assertThisInitialized(_this));
_this._onFileUploadURLAvailable = _this._onFileUploadURLAvailable.bind(_assertThisInitialized(_this));
_this._onRestored = _this._onRestored.bind(_assertThisInitialized(_this));
_this._getPersistentData = _this._getPersistentData.bind(_assertThisInitialized(_this));
var hasCustomAssemblyOptions = _this.opts.getAssemblyOptions !== defaultOptions.getAssemblyOptions;
if (_this.opts.params) {
AssemblyOptions.validateParams(_this.opts.params);
} else if (!hasCustomAssemblyOptions) {
// Throw the same error that we'd throw if the `params` returned from a
// `getAssemblyOptions()` function is null.
AssemblyOptions.validateParams(null);
}
_this.client = new Client({
service: _this.opts.service,
client: _this._getClientVersion(),
errorReporting: _this.opts.errorReporting
}); // Contains Assembly instances for in-progress Assemblies.
_this.activeAssemblies = {}; // Contains a mapping of uploadID to AssemblyWatcher
_this.assemblyWatchers = {}; // Contains a file IDs that have completed postprocessing before the upload they belong to has entered the postprocess stage.
_this.completedFiles = Object.create(null);
return _this;
}
var _proto = Transloadit.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto._getClientVersion = function _getClientVersion() {
var _this2 = this;
var list = ["uppy-core:" + this.uppy.constructor.VERSION, "uppy-transloadit:" + this.constructor.VERSION, "uppy-tus:" + Tus.VERSION];
var addPluginVersion = function addPluginVersion(pluginName, versionName) {
var plugin = _this2.uppy.getPlugin(pluginName);
if (plugin) {
list.push(versionName + ":" + plugin.constructor.VERSION);
}
};
if (this.opts.importFromUploadURLs) {
addPluginVersion('XHRUpload', 'uppy-xhr-upload');
addPluginVersion('AwsS3', 'uppy-aws-s3');
addPluginVersion('AwsS3Multipart', 'uppy-aws-s3-multipart');
}
addPluginVersion('Dropbox', 'uppy-dropbox');
addPluginVersion('Box', 'uppy-box');
addPluginVersion('Facebook', 'uppy-facebook');
addPluginVersion('GoogleDrive', 'uppy-google-drive');
addPluginVersion('Instagram', 'uppy-instagram');
addPluginVersion('OneDrive', 'uppy-onedrive');
addPluginVersion('Zoom', 'uppy-zoom');
addPluginVersion('Url', 'uppy-url');
return list.join(',');
}
/**
* Attach metadata to files to configure the Tus plugin to upload to Transloadit.
* Also use Transloadit's Companion
*
* See: https://github.com/tus/tusd/wiki/Uploading-to-Transloadit-using-tus#uploading-using-tus
*
* @param {object} file
* @param {object} status
*/
;
_proto._attachAssemblyMetadata = function _attachAssemblyMetadata(file, status) {
// Add the metadata parameters Transloadit needs.
var meta = _extends({}, file.meta, {
assembly_url: status.assembly_url,
filename: file.name,
fieldname: 'file'
}); // Add Assembly-specific Tus endpoint.
var tus = _extends({}, file.tus, {
endpoint: status.tus_url,
// Include X-Request-ID headers for better debugging.
addRequestId: true
}); // Set Companion location. We only add this, if 'file' has the attribute
// remote, because this is the criteria to identify remote files.
// We only replace the hostname for Transloadit's companions, so that
// people can also self-host them while still using Transloadit for encoding.
var remote = file.remote;
if (file.remote && TL_UPPY_SERVER.test(file.remote.companionUrl)) {
var err = new Error('The https://api2.transloadit.com/uppy-server endpoint was renamed to ' + 'https://api2.transloadit.com/companion, please update your `companionUrl` ' + 'options accordingly.'); // Explicitly log this error here because it is caught by the `createAssembly`
// Promise further along.
// That's fine, but createAssembly only shows the informer, we need something a
// little more noisy.
this.uppy.log(err);
throw err;
}
if (file.remote && TL_COMPANION.test(file.remote.companionUrl)) {
var newHost = status.companion_url.replace(/\/$/, '');
var path = file.remote.url.replace(file.remote.companionUrl, '').replace(/^\//, '');
remote = _extends({}, file.remote, {
companionUrl: newHost,
url: newHost + "/" + path
});
} // Store the Assembly ID this file is in on the file under the `transloadit` key.
var newFile = _extends({}, file, {
transloadit: {
assembly: status.assembly_id
}
}); // Only configure the Tus plugin if we are uploading straight to Transloadit (the default).
if (!this.opts.importFromUploadURLs) {
_extends(newFile, {
meta: meta,
tus: tus,
remote: remote
});
}
return newFile;
};
_proto._createAssembly = function _createAssembly(fileIDs, uploadID, options) {
var _this3 = this;
this.uppy.log('[Transloadit] Create Assembly');
return this.client.createAssembly({
params: options.params,
fields: options.fields,
expectedFiles: fileIDs.length,
signature: options.signature
}).then(function (newAssembly) {
var _extends2, _extends3;
var assembly = new Assembly(newAssembly);
var status = assembly.status;
var assemblyID = status.assembly_id;
var _this3$getPluginState = _this3.getPluginState(),
assemblies = _this3$getPluginState.assemblies,
uploadsAssemblies = _this3$getPluginState.uploadsAssemblies;
_this3.setPluginState({
// Store the Assembly status.
assemblies: _extends({}, assemblies, (_extends2 = {}, _extends2[assemblyID] = status, _extends2)),
// Store the list of Assemblies related to this upload.
uploadsAssemblies: _extends({}, uploadsAssemblies, (_extends3 = {}, _extends3[uploadID] = [].concat(uploadsAssemblies[uploadID], [assemblyID]), _extends3))
});
var _this3$uppy$getState = _this3.uppy.getState(),
files = _this3$uppy$getState.files;
var updatedFiles = {};
fileIDs.forEach(function (id) {
updatedFiles[id] = _this3._attachAssemblyMetadata(_this3.uppy.getFile(id), status);
});
_this3.uppy.setState({
files: _extends({}, files, updatedFiles)
});
_this3.uppy.emit('transloadit:assembly-created', status, fileIDs);
_this3.uppy.log("[Transloadit] Created Assembly " + assemblyID);
return assembly;
}).catch(function (err) {
err.message = _this3.i18n('creatingAssemblyFailed') + ": " + err.message; // Reject the promise.
throw err;
});
};
_proto._createAssemblyWatcher = function _createAssemblyWatcher(assemblyID, fileIDs, uploadID) {
var _this4 = this;
// AssemblyWatcher tracks completion states of all Assemblies in this upload.
var watcher = new AssemblyWatcher(this.uppy, assemblyID);
watcher.on('assembly-complete', function (id) {
var files = _this4.getAssemblyFiles(id);
files.forEach(function (file) {
_this4.completedFiles[file.id] = true;
_this4.uppy.emit('postprocess-complete', file);
});
});
watcher.on('assembly-error', function (id, error) {
// Clear postprocessing state for all our files.
var files = _this4.getAssemblyFiles(id);
files.forEach(function (file) {
// TODO Maybe make a postprocess-error event here?
_this4.uppy.emit('upload-error', file, error);
_this4.uppy.emit('postprocess-complete', file);
});
});
this.assemblyWatchers[uploadID] = watcher;
};
_proto._shouldWaitAfterUpload = function _shouldWaitAfterUpload() {
return this.opts.waitForEncoding || this.opts.waitForMetadata;
}
/**
* Used when `importFromUploadURLs` is enabled: reserves all files in
* the Assembly.
*/
;
_proto._reserveFiles = function _reserveFiles(assembly, fileIDs) {
var _this5 = this;
return Promise.all(fileIDs.map(function (fileID) {
var file = _this5.uppy.getFile(fileID);
return _this5.client.reserveFile(assembly.status, file);
}));
}
/**
* Used when `importFromUploadURLs` is enabled: adds files to the Assembly
* once they have been fully uploaded.
*/
;
_proto._onFileUploadURLAvailable = function _onFileUploadURLAvailable(rawFile) {
var _this6 = this;
var file = this.uppy.getFile(rawFile.id);
if (!file || !file.transloadit || !file.transloadit.assembly) {
return;
}
var _this$getPluginState = this.getPluginState(),
assemblies = _this$getPluginState.assemblies;
var assembly = assemblies[file.transloadit.assembly];
this.client.addFile(assembly, file).catch(function (err) {
_this6.uppy.log(err);
_this6.uppy.emit('transloadit:import-error', assembly, file.id, err);
});
};
_proto._findFile = function _findFile(uploadedFile) {
var files = this.uppy.getFiles();
for (var i = 0; i < files.length; i++) {
var file = files[i]; // Completed file upload.
if (file.uploadURL === uploadedFile.tus_upload_url) {
return file;
} // In-progress file upload.
if (file.tus && file.tus.uploadUrl === uploadedFile.tus_upload_url) {
return file;
}
if (!uploadedFile.is_tus_file) {
// Fingers-crossed check for non-tus uploads, eg imported from S3.
if (file.name === uploadedFile.name && file.size === uploadedFile.size) {
return file;
}
}
}
};
_proto._onFileUploadComplete = function _onFileUploadComplete(assemblyId, uploadedFile) {
var _extends4;
var state = this.getPluginState();
var file = this._findFile(uploadedFile);
if (!file) {
this.uppy.log('[Transloadit] Couldn’t file the file, it was likely removed in the process');
return;
}
this.setPluginState({
files: _extends({}, state.files, (_extends4 = {}, _extends4[uploadedFile.id] = {
assembly: assemblyId,
id: file.id,
uploadedFile: uploadedFile
}, _extends4))
});
this.uppy.emit('transloadit:upload', uploadedFile, this.getAssembly(assemblyId));
}
/**
* Callback when a new Assembly result comes in.
*
* @param {string} assemblyId
* @param {string} stepName
* @param {object} result
*/
;
_proto._onResult = function _onResult(assemblyId, stepName, result) {
var state = this.getPluginState();
var file = state.files[result.original_id]; // The `file` may not exist if an import robot was used instead of a file upload.
result.localId = file ? file.id : null;
var entry = {
result: result,
stepName: stepName,
id: result.id,
assembly: assemblyId
};
this.setPluginState({
results: [].concat(state.results, [entry])
});
this.uppy.emit('transloadit:result', stepName, result, this.getAssembly(assemblyId));
}
/**
* When an Assembly has finished processing, get the final state
* and emit it.
*
* @param {object} status
*/
;
_proto._onAssemblyFinished = function _onAssemblyFinished(status) {
var _this7 = this;
var url = status.assembly_ssl_url;
this.client.getAssemblyStatus(url).then(function (finalStatus) {
var _extends5;
var assemblyId = finalStatus.assembly_id;
var state = _this7.getPluginState();
_this7.setPluginState({
assemblies: _extends({}, state.assemblies, (_extends5 = {}, _extends5[assemblyId] = finalStatus, _extends5))
});
_this7.uppy.emit('transloadit:complete', finalStatus);
});
};
_proto._cancelAssembly = function _cancelAssembly(assembly) {
var _this8 = this;
return this.client.cancelAssembly(assembly).then(function () {
// TODO bubble this through AssemblyWatcher so its event handlers can clean up correctly
_this8.uppy.emit('transloadit:assembly-cancelled', assembly);
});
}
/**
* When all files are removed, cancel in-progress Assemblies.
*/
;
_proto._onCancelAll = function _onCancelAll() {
var _this9 = this;
var _this$getPluginState2 = this.getPluginState(),
uploadsAssemblies = _this$getPluginState2.uploadsAssemblies;
var assemblyIDs = Object.keys(uploadsAssemblies).reduce(function (acc, uploadID) {
acc.push.apply(acc, uploadsAssemblies[uploadID]);
return acc;
}, []);
var cancelPromises = assemblyIDs.map(function (assemblyID) {
var assembly = _this9.getAssembly(assemblyID);
return _this9._cancelAssembly(assembly);
});
Promise.all(cancelPromises).catch(function (err) {
_this9.uppy.log(err);
});
}
/**
* Custom state serialization for the Golden Retriever plugin.
* It will pass this back to the `_onRestored` function.
*
* @param {Function} setData
*/
;
_proto._getPersistentData = function _getPersistentData(setData) {
var _setData;
var state = this.getPluginState();
var assemblies = state.assemblies;
var uploadsAssemblies = state.uploadsAssemblies;
setData((_setData = {}, _setData[this.id] = {
assemblies: assemblies,
uploadsAssemblies: uploadsAssemblies
}, _setData));
};
_proto._onRestored = function _onRestored(pluginData) {
var _this10 = this;
var savedState = pluginData && pluginData[this.id] ? pluginData[this.id] : {};
var previousAssemblies = savedState.assemblies || {};
var uploadsAssemblies = savedState.uploadsAssemblies || {};
if (Object.keys(uploadsAssemblies).length === 0) {
// Nothing to restore.
return;
} // Convert loaded Assembly statuses to a Transloadit plugin state object.
var restoreState = function restoreState(assemblies) {
var files = {};
var results = [];
Object.keys(assemblies).forEach(function (id) {
var status = assemblies[id];
status.uploads.forEach(function (uploadedFile) {
var file = _this10._findFile(uploadedFile);
files[uploadedFile.id] = {
id: file.id,
assembly: id,
uploadedFile: uploadedFile
};
});
var state = _this10.getPluginState();
Object.keys(status.results).forEach(function (stepName) {
status.results[stepName].forEach(function (result) {
var file = state.files[result.original_id];
result.localId = file ? file.id : null;
results.push({
id: result.id,
result: result,
stepName: stepName,
assembly: id
});
});
});
});
_this10.setPluginState({
assemblies: assemblies,
files: files,
results: results,
uploadsAssemblies: uploadsAssemblies
});
}; // Set up the Assembly instances and AssemblyWatchers for existing Assemblies.
var restoreAssemblies = function restoreAssemblies() {
var _this10$getPluginStat = _this10.getPluginState(),
assemblies = _this10$getPluginStat.assemblies,
uploadsAssemblies = _this10$getPluginStat.uploadsAssemblies; // Set up the assembly watchers again for all the ongoing uploads.
Object.keys(uploadsAssemblies).forEach(function (uploadID) {
var assemblyIDs = uploadsAssemblies[uploadID];
var fileIDsInUpload = assemblyIDs.reduce(function (acc, assemblyID) {
var fileIDsInAssembly = _this10.getAssemblyFiles(assemblyID).map(function (file) {
return file.id;
});
acc.push.apply(acc, fileIDsInAssembly);
return acc;
}, []);
_this10._createAssemblyWatcher(assemblyIDs, fileIDsInUpload, uploadID);
});
var allAssemblyIDs = Object.keys(assemblies);
allAssemblyIDs.forEach(function (id) {
var assembly = new Assembly(assemblies[id]);
_this10._connectAssembly(assembly);
});
}; // Force-update all Assemblies to check for missed events.
var updateAssemblies = function updateAssemblies() {
var _this10$getPluginStat2 = _this10.getPluginState(),
assemblies = _this10$getPluginStat2.assemblies;
return Promise.all(Object.keys(assemblies).map(function (id) {
return _this10.activeAssemblies[id].update();
}));
}; // Restore all Assembly state.
this.restored = Promise.resolve().then(function () {
restoreState(previousAssemblies);
restoreAssemblies();
return updateAssemblies();
});
this.restored.then(function () {
_this10.restored = null;
});
};
_proto._connectAssembly = function _connectAssembly(assembly) {
var _this11 = this;
var status = assembly.status;
var id = status.assembly_id;
this.activeAssemblies[id] = assembly; // Sync local `assemblies` state
assembly.on('status', function (newStatus) {
var _extends6;
var _this11$getPluginStat = _this11.getPluginState(),
assemblies = _this11$getPluginStat.assemblies;
_this11.setPluginState({
assemblies: _extends({}, assemblies, (_extends6 = {}, _extends6[id] = newStatus, _extends6))
});
});
assembly.on('upload', function (file) {
_this11._onFileUploadComplete(id, file);
});
assembly.on('error', function (error) {
error.assembly = assembly.status;
_this11.uppy.emit('transloadit:assembly-error', assembly.status, error);
});
assembly.on('executing', function () {
_this11.uppy.emit('transloadit:assembly-executing', assembly.status);
});
if (this.opts.waitForEncoding) {
assembly.on('result', function (stepName, result) {
_this11._onResult(id, stepName, result);
});
}
if (this.opts.waitForEncoding) {
assembly.on('finished', function () {
_this11._onAssemblyFinished(assembly.status);
});
} else if (this.opts.waitForMetadata) {
assembly.on('metadata', function () {
_this11._onAssemblyFinished(assembly.status);
});
} // No need to connect to the socket if the Assembly has completed by now.
if (assembly.ok === 'ASSEMBLY_COMPLETE') {
return assembly;
} // TODO Do we still need this for anything…?
// eslint-disable-next-line no-unused-vars
var connected = new Promise(function (resolve, reject) {
assembly.once('connect', resolve);
assembly.once('status', resolve);
assembly.once('error', reject);
}).then(function () {
_this11.uppy.log('[Transloadit] Socket is ready');
});
assembly.connect();
return assembly;
};
_proto._prepareUpload = function _prepareUpload(fileIDs, uploadID) {
var _this12 = this,
_extends7;
// Only use files without errors
fileIDs = fileIDs.filter(function (file) {
return !file.error;
});
fileIDs.forEach(function (fileID) {
var file = _this12.uppy.getFile(fileID);
_this12.uppy.emit('preprocess-progress', file, {
mode: 'indeterminate',
message: _this12.i18n('creatingAssembly')
});
});
var createAssembly = function createAssembly(_ref) {
var fileIDs = _ref.fileIDs,
options = _ref.options;
var createdAssembly;
return _this12._createAssembly(fileIDs, uploadID, options).then(function (assembly) {
createdAssembly = assembly;
if (_this12.opts.importFromUploadURLs) {
return _this12._reserveFiles(assembly, fileIDs);
}
}).then(function () {
fileIDs.forEach(function (fileID) {
var file = _this12.uppy.getFile(fileID);
_this12.uppy.emit('preprocess-complete', file);
});
return createdAssembly;
}).catch(function (err) {
fileIDs.forEach(function (fileID) {
var file = _this12.uppy.getFile(fileID); // Clear preprocessing state when the Assembly could not be created,
// otherwise the UI gets confused about the lingering progress keys
_this12.uppy.emit('preprocess-complete', file);
_this12.uppy.emit('upload-error', file, err);
});
throw err;
});
};
var _this$getPluginState3 = this.getPluginState(),
uploadsAssemblies = _this$getPluginState3.uploadsAssemblies;
this.setPluginState({
uploadsAssemblies: _extends({}, uploadsAssemblies, (_extends7 = {}, _extends7[uploadID] = [], _extends7))
});
var files = fileIDs.map(function (id) {
return _this12.uppy.getFile(id);
});
var assemblyOptions = new AssemblyOptions(files, this.opts);
return assemblyOptions.build().then(function (assemblies) {
return Promise.all(assemblies.map(createAssembly)).then(function (createdAssemblies) {
var assemblyIDs = createdAssemblies.map(function (assembly) {
return assembly.status.assembly_id;
});
_this12._createAssemblyWatcher(assemblyIDs, fileIDs, uploadID);
createdAssemblies.map(function (assembly) {
return _this12._connectAssembly(assembly);
});
});
}, // If something went wrong before any Assemblies could be created,
// clear all processing state.
function (err) {
fileIDs.forEach(function (fileID) {
var file = _this12.uppy.getFile(fileID);
_this12.uppy.emit('preprocess-complete', file);
_this12.uppy.emit('upload-error', file, err);
});
throw err;
});
};
_proto._afterUpload = function _afterUpload(fileIDs, uploadID) {
var _this13 = this;
var files = fileIDs.map(function (fileID) {
return _this13.uppy.getFile(fileID);
}); // Only use files without errors
fileIDs = files.filter(function (file) {
return !file.error;
}).map(function (file) {
return file.id;
});
var state = this.getPluginState(); // If we're still restoring state, wait for that to be done.
if (this.restored) {
return this.restored.then(function () {
return _this13._afterUpload(fileIDs, uploadID);
});
}
var assemblyIDs = state.uploadsAssemblies[uploadID];
var closeSocketConnections = function closeSocketConnections() {
assemblyIDs.forEach(function (assemblyID) {
var assembly = _this13.activeAssemblies[assemblyID];
assembly.close();
delete _this13.activeAssemblies[assemblyID];
});
}; // If we don't have to wait for encoding metadata or results, we can close
// the socket immediately and finish the upload.
if (!this._shouldWaitAfterUpload()) {
closeSocketConnections();
var assemblies = assemblyIDs.map(function (id) {
return _this13.getAssembly(id);
});
this.uppy.addResultData(uploadID, {
transloadit: assemblies
});
return Promise.resolve();
} // If no Assemblies were created for this upload, we also do not have to wait.
// There's also no sockets or anything to close, so just return immediately.
if (assemblyIDs.length === 0) {
this.uppy.addResultData(uploadID, {
transloadit: []
});
return Promise.resolve();
}
var incompleteFiles = files.filter(function (file) {
return !hasProperty(_this13.completedFiles, file.id);
});
incompleteFiles.forEach(function (file) {
_this13.uppy.emit('postprocess-progress', file, {
mode: 'indeterminate',
message: _this13.i18n('encoding')
});
});
var watcher = this.assemblyWatchers[uploadID];
return watcher.promise.then(function () {
closeSocketConnections();
var assemblies = assemblyIDs.map(function (id) {
return _this13.getAssembly(id);
}); // Remove the Assembly ID list for this upload,
// it's no longer going to be used anywhere.
var state = _this13.getPluginState();
var uploadsAssemblies = _extends({}, state.uploadsAssemblies);
delete uploadsAssemblies[uploadID];
_this13.setPluginState({
uploadsAssemblies: uploadsAssemblies
});
_this13.uppy.addResultData(uploadID, {
transloadit: assemblies
});
});
};
_proto._onError = function _onError(err, uploadID) {
var _this14 = this;
if (err === void 0) {
err = null;
}
var state = this.getPluginState();
var assemblyIDs = state.uploadsAssemblies[uploadID];
assemblyIDs.forEach(function (assemblyID) {
if (_this14.activeAssemblies[assemblyID]) {
_this14.activeAssemblies[assemblyID].close();
}
});
};
_proto._onTusError = function _onTusError(err) {
if (err && /^tus: /.test(err.message)) {
var xhr = err.originalRequest ? err.originalRequest.getUnderlyingObject() : null;
var url = xhr && xhr.responseURL ? xhr.responseURL : null;
this.client.submitError(err, {
url: url,
type: 'TUS_ERROR'
}).then(function (_) {// if we can't report the error that sucks
});
}
};
_proto.install = function install() {
this.uppy.addPreProcessor(this._prepareUpload);
this.uppy.addPostProcessor(this._afterUpload); // We may need to close socket.io connections on error.
this.uppy.on('error', this._onError); // Handle cancellation.
this.uppy.on('cancel-all', this._onCancelAll); // For error reporting.
this.uppy.on('upload-error', this._onTusError);
if (this.opts.importFromUploadURLs) {
// No uploader needed when importing; instead we take the upload URL from an existing uploader.
this.uppy.on('upload-success', this._onFileUploadURLAvailable);
} else {
this.uppy.use(Tus, {
// Disable tus-js-client fingerprinting, otherwise uploading the same file at different times
// will upload to an outdated Assembly, and we won't get socket events for it.
//
// To resume a Transloadit upload, we need to reconnect to the websocket, and the state that's
// required to do that is not saved by tus-js-client's fingerprinting. We need the tus URL,
// the Assembly URL, and the WebSocket URL, at least. We also need to know _all_ the files that
// were added to the Assembly, so we can properly complete it. All that state is handled by
// Golden Retriever. So, Golden Retriever is required to do resumability with the Transloadit plugin,
// and we disable Tus's default resume implementation to prevent bad behaviours.
storeFingerprintForResuming: false,
resume: false,
// Disable Companion's retry optimisation; we need to change the endpoint on retry
// so it can't just reuse the same tus.Upload instance server-side.
useFastRemoteRetry: false,
// Only send Assembly metadata to the tus endpoint.
metaFields: ['assembly_url', 'filename', 'fieldname'],
// Pass the limit option to @uppy/tus
limit: this.opts.limit
});
}
this.uppy.on('restore:get-data', this._getPersistentData);
this.uppy.on('restored', this._onRestored);
this.setPluginState({
// Contains Assembly status objects, indexed by their ID.
assemblies: {},
// Contains arrays of Assembly IDs, indexed by the upload ID that they belong to.
uploadsAssemblies: {},
// Contains file data from Transloadit, indexed by their Transloadit-assigned ID.
files: {},
// Contains result data from Transloadit.
results: []
}); // We cannot cancel individual files because Assemblies tend to contain many files.
var _this$uppy$getState = this.uppy.getState(),
capabilities = _this$uppy$getState.capabilities;
this.uppy.setState({
capabilities: _extends({}, capabilities, {
individualCancellation: false
})
});
};
_proto.uninstall = function uninstall() {
this.uppy.removePreProcessor(this._prepareUpload);
this.uppy.removePostProcessor(this._afterUpload);
this.uppy.off('error', this._onError);
if (this.opts.importFromUploadURLs) {
this.uppy.off('upload-success', this._onFileUploadURLAvailable);
}
var _this$uppy$getState2 = this.uppy.getState(),
capabilities = _this$uppy$getState2.capabilities;
this.uppy.setState({
capabilities: _extends({}, capabilities, {
individualCancellation: true
})
});
};
_proto.getAssembly = function getAssembly(id) {
var _this$getPluginState4 = this.getPluginState(),
assemblies = _this$getPluginState4.assemblies;
return assemblies[id];
};
_proto.getAssemblyFiles = function getAssemblyFiles(assemblyID) {
return this.uppy.getFiles().filter(function (file) {
return file && file.transloadit && file.transloadit.assembly === assemblyID;
});
};
return Transloadit;
}(Plugin), _class.VERSION = "1.7.0", _temp);
module.exports.COMPANION = COMPANION;
module.exports.UPPY_SERVER = COMPANION;
module.exports.COMPANION_PATTERN = ALLOWED_COMPANION_PATTERN;
},{"./Assembly":173,"./AssemblyOptions":174,"./AssemblyWatcher":175,"./Client":176,"@uppy/core":78,"@uppy/tus":205,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/hasProperty":241}],178:[function(require,module,exports){
module.exports = function parseUrl(url) {
var scheme = /^\w+:\/\//.exec(url);
var i = 0;
if (scheme) {
i = scheme[0].length + 1;
}
var slashIndex = url.indexOf('/', i);
if (slashIndex === -1) {
return {
origin: url,
pathname: '/'
};
}
return {
origin: url.slice(0, slashIndex),
pathname: url.slice(slashIndex)
};
};
},{}],179:[function(require,module,exports){
/**
* Expose `Emitter`.
*/
if (typeof module !== 'undefined') {
module.exports = Emitter;
}
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks['$' + event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
},{}],180:[function(require,module,exports){
(function (process){(function (){
/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = 'undefined' != typeof chrome
&& 'undefined' != typeof chrome.storage
? chrome.storage.local
: localstorage();
/**
* Colors.
*/
exports.colors = [
'#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC',
'#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF',
'#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC',
'#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF',
'#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC',
'#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033',
'#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366',
'#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933',
'#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC',
'#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF',
'#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
return true;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
try {
return JSON.stringify(v);
} catch (err) {
return '[UnexpectedJSONParseError]: ' + err.message;
}
};
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
var useColors = this.useColors;
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? ' %c' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!useColors) return;
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit')
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
// this hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return 'object' === typeof console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
exports.storage.removeItem('debug');
} else {
exports.storage.debug = namespaces;
}
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = exports.storage.debug;
} catch(e) {}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
}
}).call(this)}).call(this,require('_process'))
},{"./debug":181,"_process":39}],181:[function(require,module,exports){
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');
/**
* Active `debug` instances.
*/
exports.instances = [];
/**
* The currently active debug mode names, and names to skip.
*/
exports.names = [];
exports.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
exports.formatters = {};
/**
* Select a color.
* @param {String} namespace
* @return {Number}
* @api private
*/
function selectColor(namespace) {
var hash = 0, i;
for (i in namespace) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return exports.colors[Math.abs(hash) % exports.colors.length];
}
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
var prevTime;
function debug() {
// disabled?
if (!debug.enabled) return;
var self = debug;
// set `diff` timestamp
var curr = +new Date();
var ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
// turn the `arguments` into a proper Array
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
args[0] = exports.coerce(args[0]);
if ('string' !== typeof args[0]) {
// anything else let's inspect with %O
args.unshift('%O');
}
// apply any `formatters` transformations
var index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
// if we encounter an escaped % then don't increase the array index
if (match === '%%') return match;
index++;
var formatter = exports.formatters[format];
if ('function' === typeof formatter) {
var val = args[index];
match = formatter.call(self, val);
// now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// apply env-specific formatting (colors, etc.)
exports.formatArgs.call(self, args);
var logFn = debug.log || exports.log || console.log.bind(console);
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = exports.enabled(namespace);
debug.useColors = exports.useColors();
debug.color = selectColor(namespace);
debug.destroy = destroy;
// env-specific initialization logic for debug instances
if ('function' === typeof exports.init) {
exports.init(debug);
}
exports.instances.push(debug);
return debug;
}
function destroy () {
var index = exports.instances.indexOf(this);
if (index !== -1) {
exports.instances.splice(index, 1);
return true;
} else {
return false;
}
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
exports.save(namespaces);
exports.names = [];
exports.skips = [];
var i;
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
var len = split.length;
for (i = 0; i < len; i++) {
if (!split[i]) continue; // ignore empty strings
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
for (i = 0; i < exports.instances.length; i++) {
var instance = exports.instances[i];
instance.enabled = exports.enabled(instance.namespace);
}
}
/**
* Disable debug output.
*
* @api public
*/
function disable() {
exports.enable('');
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
var i, len;
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = exports.names.length; i < len; i++) {
if (exports.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
},{"ms":192}],182:[function(require,module,exports){
module.exports = require('./socket');
/**
* Exports parser
*
* @api public
*
*/
module.exports.parser = require('engine.io-parser');
},{"./socket":183,"engine.io-parser":19}],183:[function(require,module,exports){
/**
* Module dependencies.
*/
var transports = require('./transports/index');
var Emitter = require('component-emitter');
var debug = require('debug')('engine.io-client:socket');
var index = require('indexof');
var parser = require('engine.io-parser');
var parseuri = require('parseuri');
var parseqs = require('parseqs');
/**
* Module exports.
*/
module.exports = Socket;
/**
* Socket constructor.
*
* @param {String|Object} uri or options
* @param {Object} options
* @api public
*/
function Socket (uri, opts) {
if (!(this instanceof Socket)) return new Socket(uri, opts);
opts = opts || {};
if (uri && 'object' === typeof uri) {
opts = uri;
uri = null;
}
if (uri) {
uri = parseuri(uri);
opts.hostname = uri.host;
opts.secure = uri.protocol === 'https' || uri.protocol === 'wss';
opts.port = uri.port;
if (uri.query) opts.query = uri.query;
} else if (opts.host) {
opts.hostname = parseuri(opts.host).host;
}
this.secure = null != opts.secure ? opts.secure
: (typeof location !== 'undefined' && 'https:' === location.protocol);
if (opts.hostname && !opts.port) {
// if no port is specified manually, use the protocol default
opts.port = this.secure ? '443' : '80';
}
this.agent = opts.agent || false;
this.hostname = opts.hostname ||
(typeof location !== 'undefined' ? location.hostname : 'localhost');
this.port = opts.port || (typeof location !== 'undefined' && location.port
? location.port
: (this.secure ? 443 : 80));
this.query = opts.query || {};
if ('string' === typeof this.query) this.query = parseqs.decode(this.query);
this.upgrade = false !== opts.upgrade;
this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
this.forceJSONP = !!opts.forceJSONP;
this.jsonp = false !== opts.jsonp;
this.forceBase64 = !!opts.forceBase64;
this.enablesXDR = !!opts.enablesXDR;
this.timestampParam = opts.timestampParam || 't';
this.timestampRequests = opts.timestampRequests;
this.transports = opts.transports || ['polling', 'websocket'];
this.transportOptions = opts.transportOptions || {};
this.readyState = '';
this.writeBuffer = [];
this.prevBufferLen = 0;
this.policyPort = opts.policyPort || 843;
this.rememberUpgrade = opts.rememberUpgrade || false;
this.binaryType = null;
this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;
if (true === this.perMessageDeflate) this.perMessageDeflate = {};
if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {
this.perMessageDeflate.threshold = 1024;
}
// SSL options for Node.js client
this.pfx = opts.pfx || null;
this.key = opts.key || null;
this.passphrase = opts.passphrase || null;
this.cert = opts.cert || null;
this.ca = opts.ca || null;
this.ciphers = opts.ciphers || null;
this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? true : opts.rejectUnauthorized;
this.forceNode = !!opts.forceNode;
// detect ReactNative environment
this.isReactNative = (typeof navigator !== 'undefined' && typeof navigator.product === 'string' && navigator.product.toLowerCase() === 'reactnative');
// other options for Node.js or ReactNative client
if (typeof self === 'undefined' || this.isReactNative) {
if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {
this.extraHeaders = opts.extraHeaders;
}
if (opts.localAddress) {
this.localAddress = opts.localAddress;
}
}
// set on handshake
this.id = null;
this.upgrades = null;
this.pingInterval = null;
this.pingTimeout = null;
// set on heartbeat
this.pingIntervalTimer = null;
this.pingTimeoutTimer = null;
this.open();
}
Socket.priorWebsocketSuccess = false;
/**
* Mix in `Emitter`.
*/
Emitter(Socket.prototype);
/**
* Protocol version.
*
* @api public
*/
Socket.protocol = parser.protocol; // this is an int
/**
* Expose deps for legacy compatibility
* and standalone browser access.
*/
Socket.Socket = Socket;
Socket.Transport = require('./transport');
Socket.transports = require('./transports/index');
Socket.parser = require('engine.io-parser');
/**
* Creates transport of the given type.
*
* @param {String} transport name
* @return {Transport}
* @api private
*/
Socket.prototype.createTransport = function (name) {
debug('creating transport "%s"', name);
var query = clone(this.query);
// append engine.io protocol identifier
query.EIO = parser.protocol;
// transport name
query.transport = name;
// per-transport options
var options = this.transportOptions[name] || {};
// session id if we already have one
if (this.id) query.sid = this.id;
var transport = new transports[name]({
query: query,
socket: this,
agent: options.agent || this.agent,
hostname: options.hostname || this.hostname,
port: options.port || this.port,
secure: options.secure || this.secure,
path: options.path || this.path,
forceJSONP: options.forceJSONP || this.forceJSONP,
jsonp: options.jsonp || this.jsonp,
forceBase64: options.forceBase64 || this.forceBase64,
enablesXDR: options.enablesXDR || this.enablesXDR,
timestampRequests: options.timestampRequests || this.timestampRequests,
timestampParam: options.timestampParam || this.timestampParam,
policyPort: options.policyPort || this.policyPort,
pfx: options.pfx || this.pfx,
key: options.key || this.key,
passphrase: options.passphrase || this.passphrase,
cert: options.cert || this.cert,
ca: options.ca || this.ca,
ciphers: options.ciphers || this.ciphers,
rejectUnauthorized: options.rejectUnauthorized || this.rejectUnauthorized,
perMessageDeflate: options.perMessageDeflate || this.perMessageDeflate,
extraHeaders: options.extraHeaders || this.extraHeaders,
forceNode: options.forceNode || this.forceNode,
localAddress: options.localAddress || this.localAddress,
requestTimeout: options.requestTimeout || this.requestTimeout,
protocols: options.protocols || void (0),
isReactNative: this.isReactNative
});
return transport;
};
function clone (obj) {
var o = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
o[i] = obj[i];
}
}
return o;
}
/**
* Initializes transport to use and starts probe.
*
* @api private
*/
Socket.prototype.open = function () {
var transport;
if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) {
transport = 'websocket';
} else if (0 === this.transports.length) {
// Emit error on next tick so it can be listened to
var self = this;
setTimeout(function () {
self.emit('error', 'No transports available');
}, 0);
return;
} else {
transport = this.transports[0];
}
this.readyState = 'opening';
// Retry with the next transport if the transport is disabled (jsonp: false)
try {
transport = this.createTransport(transport);
} catch (e) {
this.transports.shift();
this.open();
return;
}
transport.open();
this.setTransport(transport);
};
/**
* Sets the current transport. Disables the existing one (if any).
*
* @api private
*/
Socket.prototype.setTransport = function (transport) {
debug('setting transport %s', transport.name);
var self = this;
if (this.transport) {
debug('clearing existing transport %s', this.transport.name);
this.transport.removeAllListeners();
}
// set up transport
this.transport = transport;
// set up transport listeners
transport
.on('drain', function () {
self.onDrain();
})
.on('packet', function (packet) {
self.onPacket(packet);
})
.on('error', function (e) {
self.onError(e);
})
.on('close', function () {
self.onClose('transport close');
});
};
/**
* Probes a transport.
*
* @param {String} transport name
* @api private
*/
Socket.prototype.probe = function (name) {
debug('probing transport "%s"', name);
var transport = this.createTransport(name, { probe: 1 });
var failed = false;
var self = this;
Socket.priorWebsocketSuccess = false;
function onTransportOpen () {
if (self.onlyBinaryUpgrades) {
var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
failed = failed || upgradeLosesBinary;
}
if (failed) return;
debug('probe transport "%s" opened', name);
transport.send([{ type: 'ping', data: 'probe' }]);
transport.once('packet', function (msg) {
if (failed) return;
if ('pong' === msg.type && 'probe' === msg.data) {
debug('probe transport "%s" pong', name);
self.upgrading = true;
self.emit('upgrading', transport);
if (!transport) return;
Socket.priorWebsocketSuccess = 'websocket' === transport.name;
debug('pausing current transport "%s"', self.transport.name);
self.transport.pause(function () {
if (failed) return;
if ('closed' === self.readyState) return;
debug('changing transport and sending upgrade packet');
cleanup();
self.setTransport(transport);
transport.send([{ type: 'upgrade' }]);
self.emit('upgrade', transport);
transport = null;
self.upgrading = false;
self.flush();
});
} else {
debug('probe transport "%s" failed', name);
var err = new Error('probe error');
err.transport = transport.name;
self.emit('upgradeError', err);
}
});
}
function freezeTransport () {
if (failed) return;
// Any callback called by transport should be ignored since now
failed = true;
cleanup();
transport.close();
transport = null;
}
// Handle any error that happens while probing
function onerror (err) {
var error = new Error('probe error: ' + err);
error.transport = transport.name;
freezeTransport();
debug('probe transport "%s" failed because of error: %s', name, err);
self.emit('upgradeError', error);
}
function onTransportClose () {
onerror('transport closed');
}
// When the socket is closed while we're probing
function onclose () {
onerror('socket closed');
}
// When the socket is upgraded while we're probing
function onupgrade (to) {
if (transport && to.name !== transport.name) {
debug('"%s" works - aborting "%s"', to.name, transport.name);
freezeTransport();
}
}
// Remove all listeners on the transport and on self
function cleanup () {
transport.removeListener('open', onTransportOpen);
transport.removeListener('error', onerror);
transport.removeListener('close', onTransportClose);
self.removeListener('close', onclose);
self.removeListener('upgrading', onupgrade);
}
transport.once('open', onTransportOpen);
transport.once('error', onerror);
transport.once('close', onTransportClose);
this.once('close', onclose);
this.once('upgrading', onupgrade);
transport.open();
};
/**
* Called when connection is deemed open.
*
* @api public
*/
Socket.prototype.onOpen = function () {
debug('socket open');
this.readyState = 'open';
Socket.priorWebsocketSuccess = 'websocket' === this.transport.name;
this.emit('open');
this.flush();
// we check for `readyState` in case an `open`
// listener already closed the socket
if ('open' === this.readyState && this.upgrade && this.transport.pause) {
debug('starting upgrade probes');
for (var i = 0, l = this.upgrades.length; i < l; i++) {
this.probe(this.upgrades[i]);
}
}
};
/**
* Handles a packet.
*
* @api private
*/
Socket.prototype.onPacket = function (packet) {
if ('opening' === this.readyState || 'open' === this.readyState ||
'closing' === this.readyState) {
debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
this.emit('packet', packet);
// Socket is live - any packet counts
this.emit('heartbeat');
switch (packet.type) {
case 'open':
this.onHandshake(JSON.parse(packet.data));
break;
case 'pong':
this.setPing();
this.emit('pong');
break;
case 'error':
var err = new Error('server error');
err.code = packet.data;
this.onError(err);
break;
case 'message':
this.emit('data', packet.data);
this.emit('message', packet.data);
break;
}
} else {
debug('packet received with socket readyState "%s"', this.readyState);
}
};
/**
* Called upon handshake completion.
*
* @param {Object} handshake obj
* @api private
*/
Socket.prototype.onHandshake = function (data) {
this.emit('handshake', data);
this.id = data.sid;
this.transport.query.sid = data.sid;
this.upgrades = this.filterUpgrades(data.upgrades);
this.pingInterval = data.pingInterval;
this.pingTimeout = data.pingTimeout;
this.onOpen();
// In case open handler closes socket
if ('closed' === this.readyState) return;
this.setPing();
// Prolong liveness of socket on heartbeat
this.removeListener('heartbeat', this.onHeartbeat);
this.on('heartbeat', this.onHeartbeat);
};
/**
* Resets ping timeout.
*
* @api private
*/
Socket.prototype.onHeartbeat = function (timeout) {
clearTimeout(this.pingTimeoutTimer);
var self = this;
self.pingTimeoutTimer = setTimeout(function () {
if ('closed' === self.readyState) return;
self.onClose('ping timeout');
}, timeout || (self.pingInterval + self.pingTimeout));
};
/**
* Pings server every `this.pingInterval` and expects response
* within `this.pingTimeout` or closes connection.
*
* @api private
*/
Socket.prototype.setPing = function () {
var self = this;
clearTimeout(self.pingIntervalTimer);
self.pingIntervalTimer = setTimeout(function () {
debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
self.ping();
self.onHeartbeat(self.pingTimeout);
}, self.pingInterval);
};
/**
* Sends a ping packet.
*
* @api private
*/
Socket.prototype.ping = function () {
var self = this;
this.sendPacket('ping', function () {
self.emit('ping');
});
};
/**
* Called on `drain` event
*
* @api private
*/
Socket.prototype.onDrain = function () {
this.writeBuffer.splice(0, this.prevBufferLen);
// setting prevBufferLen = 0 is very important
// for example, when upgrading, upgrade packet is sent over,
// and a nonzero prevBufferLen could cause problems on `drain`
this.prevBufferLen = 0;
if (0 === this.writeBuffer.length) {
this.emit('drain');
} else {
this.flush();
}
};
/**
* Flush write buffers.
*
* @api private
*/
Socket.prototype.flush = function () {
if ('closed' !== this.readyState && this.transport.writable &&
!this.upgrading && this.writeBuffer.length) {
debug('flushing %d packets in socket', this.writeBuffer.length);
this.transport.send(this.writeBuffer);
// keep track of current length of writeBuffer
// splice writeBuffer and callbackBuffer on `drain`
this.prevBufferLen = this.writeBuffer.length;
this.emit('flush');
}
};
/**
* Sends a message.
*
* @param {String} message.
* @param {Function} callback function.
* @param {Object} options.
* @return {Socket} for chaining.
* @api public
*/
Socket.prototype.write =
Socket.prototype.send = function (msg, options, fn) {
this.sendPacket('message', msg, options, fn);
return this;
};
/**
* Sends a packet.
*
* @param {String} packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} callback function.
* @api private
*/
Socket.prototype.sendPacket = function (type, data, options, fn) {
if ('function' === typeof data) {
fn = data;
data = undefined;
}
if ('function' === typeof options) {
fn = options;
options = null;
}
if ('closing' === this.readyState || 'closed' === this.readyState) {
return;
}
options = options || {};
options.compress = false !== options.compress;
var packet = {
type: type,
data: data,
options: options
};
this.emit('packetCreate', packet);
this.writeBuffer.push(packet);
if (fn) this.once('flush', fn);
this.flush();
};
/**
* Closes the connection.
*
* @api private
*/
Socket.prototype.close = function () {
if ('opening' === this.readyState || 'open' === this.readyState) {
this.readyState = 'closing';
var self = this;
if (this.writeBuffer.length) {
this.once('drain', function () {
if (this.upgrading) {
waitForUpgrade();
} else {
close();
}
});
} else if (this.upgrading) {
waitForUpgrade();
} else {
close();
}
}
function close () {
self.onClose('forced close');
debug('socket closing - telling transport to close');
self.transport.close();
}
function cleanupAndClose () {
self.removeListener('upgrade', cleanupAndClose);
self.removeListener('upgradeError', cleanupAndClose);
close();
}
function waitForUpgrade () {
// wait for upgrade to finish since we can't send packets while pausing a transport
self.once('upgrade', cleanupAndClose);
self.once('upgradeError', cleanupAndClose);
}
return this;
};
/**
* Called upon transport error
*
* @api private
*/
Socket.prototype.onError = function (err) {
debug('socket error %j', err);
Socket.priorWebsocketSuccess = false;
this.emit('error', err);
this.onClose('transport error', err);
};
/**
* Called upon transport close.
*
* @api private
*/
Socket.prototype.onClose = function (reason, desc) {
if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) {
debug('socket close with reason: "%s"', reason);
var self = this;
// clear timers
clearTimeout(this.pingIntervalTimer);
clearTimeout(this.pingTimeoutTimer);
// stop event from firing again for transport
this.transport.removeAllListeners('close');
// ensure transport won't stay open
this.transport.close();
// ignore further transport communication
this.transport.removeAllListeners();
// set ready state
this.readyState = 'closed';
// clear session id
this.id = null;
// emit close event
this.emit('close', reason, desc);
// clean buffers after, so users can still
// grab the buffers on `close` event
self.writeBuffer = [];
self.prevBufferLen = 0;
}
};
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} server upgrades
* @api private
*
*/
Socket.prototype.filterUpgrades = function (upgrades) {
var filteredUpgrades = [];
for (var i = 0, j = upgrades.length; i < j; i++) {
if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
}
return filteredUpgrades;
};
},{"./transport":184,"./transports/index":185,"component-emitter":179,"debug":180,"engine.io-parser":19,"indexof":30,"parseqs":193,"parseuri":194}],184:[function(require,module,exports){
/**
* Module dependencies.
*/
var parser = require('engine.io-parser');
var Emitter = require('component-emitter');
/**
* Module exports.
*/
module.exports = Transport;
/**
* Transport abstract constructor.
*
* @param {Object} options.
* @api private
*/
function Transport (opts) {
this.path = opts.path;
this.hostname = opts.hostname;
this.port = opts.port;
this.secure = opts.secure;
this.query = opts.query;
this.timestampParam = opts.timestampParam;
this.timestampRequests = opts.timestampRequests;
this.readyState = '';
this.agent = opts.agent || false;
this.socket = opts.socket;
this.enablesXDR = opts.enablesXDR;
// SSL options for Node.js client
this.pfx = opts.pfx;
this.key = opts.key;
this.passphrase = opts.passphrase;
this.cert = opts.cert;
this.ca = opts.ca;
this.ciphers = opts.ciphers;
this.rejectUnauthorized = opts.rejectUnauthorized;
this.forceNode = opts.forceNode;
// results of ReactNative environment detection
this.isReactNative = opts.isReactNative;
// other options for Node.js client
this.extraHeaders = opts.extraHeaders;
this.localAddress = opts.localAddress;
}
/**
* Mix in `Emitter`.
*/
Emitter(Transport.prototype);
/**
* Emits an error.
*
* @param {String} str
* @return {Transport} for chaining
* @api public
*/
Transport.prototype.onError = function (msg, desc) {
var err = new Error(msg);
err.type = 'TransportError';
err.description = desc;
this.emit('error', err);
return this;
};
/**
* Opens the transport.
*
* @api public
*/
Transport.prototype.open = function () {
if ('closed' === this.readyState || '' === this.readyState) {
this.readyState = 'opening';
this.doOpen();
}
return this;
};
/**
* Closes the transport.
*
* @api private
*/
Transport.prototype.close = function () {
if ('opening' === this.readyState || 'open' === this.readyState) {
this.doClose();
this.onClose();
}
return this;
};
/**
* Sends multiple packets.
*
* @param {Array} packets
* @api private
*/
Transport.prototype.send = function (packets) {
if ('open' === this.readyState) {
this.write(packets);
} else {
throw new Error('Transport not open');
}
};
/**
* Called upon open
*
* @api private
*/
Transport.prototype.onOpen = function () {
this.readyState = 'open';
this.writable = true;
this.emit('open');
};
/**
* Called with data.
*
* @param {String} data
* @api private
*/
Transport.prototype.onData = function (data) {
var packet = parser.decodePacket(data, this.socket.binaryType);
this.onPacket(packet);
};
/**
* Called with a decoded packet.
*/
Transport.prototype.onPacket = function (packet) {
this.emit('packet', packet);
};
/**
* Called upon close.
*
* @api private
*/
Transport.prototype.onClose = function () {
this.readyState = 'closed';
this.emit('close');
};
},{"component-emitter":179,"engine.io-parser":19}],185:[function(require,module,exports){
/**
* Module dependencies
*/
var XMLHttpRequest = require('xmlhttprequest-ssl');
var XHR = require('./polling-xhr');
var JSONP = require('./polling-jsonp');
var websocket = require('./websocket');
/**
* Export transports.
*/
exports.polling = polling;
exports.websocket = websocket;
/**
* Polling transport polymorphic constructor.
* Decides on xhr vs jsonp based on feature detection.
*
* @api private
*/
function polling (opts) {
var xhr;
var xd = false;
var xs = false;
var jsonp = false !== opts.jsonp;
if (typeof location !== 'undefined') {
var isSSL = 'https:' === location.protocol;
var port = location.port;
// some user agents have empty `location.port`
if (!port) {
port = isSSL ? 443 : 80;
}
xd = opts.hostname !== location.hostname || port !== opts.port;
xs = opts.secure !== isSSL;
}
opts.xdomain = xd;
opts.xscheme = xs;
xhr = new XMLHttpRequest(opts);
if ('open' in xhr && !opts.forceJSONP) {
return new XHR(opts);
} else {
if (!jsonp) throw new Error('JSONP disabled');
return new JSONP(opts);
}
}
},{"./polling-jsonp":186,"./polling-xhr":187,"./websocket":189,"xmlhttprequest-ssl":190}],186:[function(require,module,exports){
(function (global){(function (){
/**
* Module requirements.
*/
var Polling = require('./polling');
var inherit = require('component-inherit');
/**
* Module exports.
*/
module.exports = JSONPPolling;
/**
* Cached regular expressions.
*/
var rNewline = /\n/g;
var rEscapedNewline = /\\n/g;
/**
* Global JSONP callbacks.
*/
var callbacks;
/**
* Noop.
*/
function empty () { }
/**
* Until https://github.com/tc39/proposal-global is shipped.
*/
function glob () {
return typeof self !== 'undefined' ? self
: typeof window !== 'undefined' ? window
: typeof global !== 'undefined' ? global : {};
}
/**
* JSONP Polling constructor.
*
* @param {Object} opts.
* @api public
*/
function JSONPPolling (opts) {
Polling.call(this, opts);
this.query = this.query || {};
// define global callbacks array if not present
// we do this here (lazily) to avoid unneeded global pollution
if (!callbacks) {
// we need to consider multiple engines in the same page
var global = glob();
callbacks = global.___eio = (global.___eio || []);
}
// callback identifier
this.index = callbacks.length;
// add callback to jsonp global
var self = this;
callbacks.push(function (msg) {
self.onData(msg);
});
// append to query string
this.query.j = this.index;
// prevent spurious errors from being emitted when the window is unloaded
if (typeof addEventListener === 'function') {
addEventListener('beforeunload', function () {
if (self.script) self.script.onerror = empty;
}, false);
}
}
/**
* Inherits from Polling.
*/
inherit(JSONPPolling, Polling);
/*
* JSONP only supports binary as base64 encoded strings
*/
JSONPPolling.prototype.supportsBinary = false;
/**
* Closes the socket.
*
* @api private
*/
JSONPPolling.prototype.doClose = function () {
if (this.script) {
this.script.parentNode.removeChild(this.script);
this.script = null;
}
if (this.form) {
this.form.parentNode.removeChild(this.form);
this.form = null;
this.iframe = null;
}
Polling.prototype.doClose.call(this);
};
/**
* Starts a poll cycle.
*
* @api private
*/
JSONPPolling.prototype.doPoll = function () {
var self = this;
var script = document.createElement('script');
if (this.script) {
this.script.parentNode.removeChild(this.script);
this.script = null;
}
script.async = true;
script.src = this.uri();
script.onerror = function (e) {
self.onError('jsonp poll error', e);
};
var insertAt = document.getElementsByTagName('script')[0];
if (insertAt) {
insertAt.parentNode.insertBefore(script, insertAt);
} else {
(document.head || document.body).appendChild(script);
}
this.script = script;
var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);
if (isUAgecko) {
setTimeout(function () {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
document.body.removeChild(iframe);
}, 100);
}
};
/**
* Writes with a hidden iframe.
*
* @param {String} data to send
* @param {Function} called upon flush.
* @api private
*/
JSONPPolling.prototype.doWrite = function (data, fn) {
var self = this;
if (!this.form) {
var form = document.createElement('form');
var area = document.createElement('textarea');
var id = this.iframeId = 'eio_iframe_' + this.index;
var iframe;
form.className = 'socketio';
form.style.position = 'absolute';
form.style.top = '-1000px';
form.style.left = '-1000px';
form.target = id;
form.method = 'POST';
form.setAttribute('accept-charset', 'utf-8');
area.name = 'd';
form.appendChild(area);
document.body.appendChild(form);
this.form = form;
this.area = area;
}
this.form.action = this.uri();
function complete () {
initIframe();
fn();
}
function initIframe () {
if (self.iframe) {
try {
self.form.removeChild(self.iframe);
} catch (e) {
self.onError('jsonp polling iframe removal error', e);
}
}
try {
// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
var html = '<iframe src="javascript:0" name="' + self.iframeId + '">';
iframe = document.createElement(html);
} catch (e) {
iframe = document.createElement('iframe');
iframe.name = self.iframeId;
iframe.src = 'javascript:0';
}
iframe.id = self.iframeId;
self.form.appendChild(iframe);
self.iframe = iframe;
}
initIframe();
// escape \n to prevent it from being converted into \r\n by some UAs
// double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
data = data.replace(rEscapedNewline, '\\\n');
this.area.value = data.replace(rNewline, '\\n');
try {
this.form.submit();
} catch (e) {}
if (this.iframe.attachEvent) {
this.iframe.onreadystatechange = function () {
if (self.iframe.readyState === 'complete') {
complete();
}
};
} else {
this.iframe.onload = complete;
}
};
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./polling":188,"component-inherit":13}],187:[function(require,module,exports){
/* global attachEvent */
/**
* Module requirements.
*/
var XMLHttpRequest = require('xmlhttprequest-ssl');
var Polling = require('./polling');
var Emitter = require('component-emitter');
var inherit = require('component-inherit');
var debug = require('debug')('engine.io-client:polling-xhr');
/**
* Module exports.
*/
module.exports = XHR;
module.exports.Request = Request;
/**
* Empty function
*/
function empty () {}
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @api public
*/
function XHR (opts) {
Polling.call(this, opts);
this.requestTimeout = opts.requestTimeout;
this.extraHeaders = opts.extraHeaders;
if (typeof location !== 'undefined') {
var isSSL = 'https:' === location.protocol;
var port = location.port;
// some user agents have empty `location.port`
if (!port) {
port = isSSL ? 443 : 80;
}
this.xd = (typeof location !== 'undefined' && opts.hostname !== location.hostname) ||
port !== opts.port;
this.xs = opts.secure !== isSSL;
}
}
/**
* Inherits from Polling.
*/
inherit(XHR, Polling);
/**
* XHR supports binary
*/
XHR.prototype.supportsBinary = true;
/**
* Creates a request.
*
* @param {String} method
* @api private
*/
XHR.prototype.request = function (opts) {
opts = opts || {};
opts.uri = this.uri();
opts.xd = this.xd;
opts.xs = this.xs;
opts.agent = this.agent || false;
opts.supportsBinary = this.supportsBinary;
opts.enablesXDR = this.enablesXDR;
// SSL options for Node.js client
opts.pfx = this.pfx;
opts.key = this.key;
opts.passphrase = this.passphrase;
opts.cert = this.cert;
opts.ca = this.ca;
opts.ciphers = this.ciphers;
opts.rejectUnauthorized = this.rejectUnauthorized;
opts.requestTimeout = this.requestTimeout;
// other options for Node.js client
opts.extraHeaders = this.extraHeaders;
return new Request(opts);
};
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @api private
*/
XHR.prototype.doWrite = function (data, fn) {
var isBinary = typeof data !== 'string' && data !== undefined;
var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
var self = this;
req.on('success', fn);
req.on('error', function (err) {
self.onError('xhr post error', err);
});
this.sendXhr = req;
};
/**
* Starts a poll cycle.
*
* @api private
*/
XHR.prototype.doPoll = function () {
debug('xhr poll');
var req = this.request();
var self = this;
req.on('data', function (data) {
self.onData(data);
});
req.on('error', function (err) {
self.onError('xhr poll error', err);
});
this.pollXhr = req;
};
/**
* Request constructor
*
* @param {Object} options
* @api public
*/
function Request (opts) {
this.method = opts.method || 'GET';
this.uri = opts.uri;
this.xd = !!opts.xd;
this.xs = !!opts.xs;
this.async = false !== opts.async;
this.data = undefined !== opts.data ? opts.data : null;
this.agent = opts.agent;
this.isBinary = opts.isBinary;
this.supportsBinary = opts.supportsBinary;
this.enablesXDR = opts.enablesXDR;
this.requestTimeout = opts.requestTimeout;
// SSL options for Node.js client
this.pfx = opts.pfx;
this.key = opts.key;
this.passphrase = opts.passphrase;
this.cert = opts.cert;
this.ca = opts.ca;
this.ciphers = opts.ciphers;
this.rejectUnauthorized = opts.rejectUnauthorized;
// other options for Node.js client
this.extraHeaders = opts.extraHeaders;
this.create();
}
/**
* Mix in `Emitter`.
*/
Emitter(Request.prototype);
/**
* Creates the XHR object and sends the request.
*
* @api private
*/
Request.prototype.create = function () {
var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };
// SSL options for Node.js client
opts.pfx = this.pfx;
opts.key = this.key;
opts.passphrase = this.passphrase;
opts.cert = this.cert;
opts.ca = this.ca;
opts.ciphers = this.ciphers;
opts.rejectUnauthorized = this.rejectUnauthorized;
var xhr = this.xhr = new XMLHttpRequest(opts);
var self = this;
try {
debug('xhr open %s: %s', this.method, this.uri);
xhr.open(this.method, this.uri, this.async);
try {
if (this.extraHeaders) {
xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
for (var i in this.extraHeaders) {
if (this.extraHeaders.hasOwnProperty(i)) {
xhr.setRequestHeader(i, this.extraHeaders[i]);
}
}
}
} catch (e) {}
if ('POST' === this.method) {
try {
if (this.isBinary) {
xhr.setRequestHeader('Content-type', 'application/octet-stream');
} else {
xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
}
} catch (e) {}
}
try {
xhr.setRequestHeader('Accept', '*/*');
} catch (e) {}
// ie6 check
if ('withCredentials' in xhr) {
xhr.withCredentials = true;
}
if (this.requestTimeout) {
xhr.timeout = this.requestTimeout;
}
if (this.hasXDR()) {
xhr.onload = function () {
self.onLoad();
};
xhr.onerror = function () {
self.onError(xhr.responseText);
};
} else {
xhr.onreadystatechange = function () {
if (xhr.readyState === 2) {
try {
var contentType = xhr.getResponseHeader('Content-Type');
if (self.supportsBinary && contentType === 'application/octet-stream') {
xhr.responseType = 'arraybuffer';
}
} catch (e) {}
}
if (4 !== xhr.readyState) return;
if (200 === xhr.status || 1223 === xhr.status) {
self.onLoad();
} else {
// make sure the `error` event handler that's user-set
// does not throw in the same tick and gets caught here
setTimeout(function () {
self.onError(xhr.status);
}, 0);
}
};
}
debug('xhr data %s', this.data);
xhr.send(this.data);
} catch (e) {
// Need to defer since .create() is called directly fhrom the constructor
// and thus the 'error' event can only be only bound *after* this exception
// occurs. Therefore, also, we cannot throw here at all.
setTimeout(function () {
self.onError(e);
}, 0);
return;
}
if (typeof document !== 'undefined') {
this.index = Request.requestsCount++;
Request.requests[this.index] = this;
}
};
/**
* Called upon successful response.
*
* @api private
*/
Request.prototype.onSuccess = function () {
this.emit('success');
this.cleanup();
};
/**
* Called if we have data.
*
* @api private
*/
Request.prototype.onData = function (data) {
this.emit('data', data);
this.onSuccess();
};
/**
* Called upon error.
*
* @api private
*/
Request.prototype.onError = function (err) {
this.emit('error', err);
this.cleanup(true);
};
/**
* Cleans up house.
*
* @api private
*/
Request.prototype.cleanup = function (fromError) {
if ('undefined' === typeof this.xhr || null === this.xhr) {
return;
}
// xmlhttprequest
if (this.hasXDR()) {
this.xhr.onload = this.xhr.onerror = empty;
} else {
this.xhr.onreadystatechange = empty;
}
if (fromError) {
try {
this.xhr.abort();
} catch (e) {}
}
if (typeof document !== 'undefined') {
delete Request.requests[this.index];
}
this.xhr = null;
};
/**
* Called upon load.
*
* @api private
*/
Request.prototype.onLoad = function () {
var data;
try {
var contentType;
try {
contentType = this.xhr.getResponseHeader('Content-Type');
} catch (e) {}
if (contentType === 'application/octet-stream') {
data = this.xhr.response || this.xhr.responseText;
} else {
data = this.xhr.responseText;
}
} catch (e) {
this.onError(e);
}
if (null != data) {
this.onData(data);
}
};
/**
* Check if it has XDomainRequest.
*
* @api private
*/
Request.prototype.hasXDR = function () {
return typeof XDomainRequest !== 'undefined' && !this.xs && this.enablesXDR;
};
/**
* Aborts the request.
*
* @api public
*/
Request.prototype.abort = function () {
this.cleanup();
};
/**
* Aborts pending requests when unloading the window. This is needed to prevent
* memory leaks (e.g. when using IE) and to ensure that no spurious error is
* emitted.
*/
Request.requestsCount = 0;
Request.requests = {};
if (typeof document !== 'undefined') {
if (typeof attachEvent === 'function') {
attachEvent('onunload', unloadHandler);
} else if (typeof addEventListener === 'function') {
var terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
addEventListener(terminationEvent, unloadHandler, false);
}
}
function unloadHandler () {
for (var i in Request.requests) {
if (Request.requests.hasOwnProperty(i)) {
Request.requests[i].abort();
}
}
}
},{"./polling":188,"component-emitter":179,"component-inherit":13,"debug":180,"xmlhttprequest-ssl":190}],188:[function(require,module,exports){
/**
* Module dependencies.
*/
var Transport = require('../transport');
var parseqs = require('parseqs');
var parser = require('engine.io-parser');
var inherit = require('component-inherit');
var yeast = require('yeast');
var debug = require('debug')('engine.io-client:polling');
/**
* Module exports.
*/
module.exports = Polling;
/**
* Is XHR2 supported?
*/
var hasXHR2 = (function () {
var XMLHttpRequest = require('xmlhttprequest-ssl');
var xhr = new XMLHttpRequest({ xdomain: false });
return null != xhr.responseType;
})();
/**
* Polling interface.
*
* @param {Object} opts
* @api private
*/
function Polling (opts) {
var forceBase64 = (opts && opts.forceBase64);
if (!hasXHR2 || forceBase64) {
this.supportsBinary = false;
}
Transport.call(this, opts);
}
/**
* Inherits from Transport.
*/
inherit(Polling, Transport);
/**
* Transport name.
*/
Polling.prototype.name = 'polling';
/**
* Opens the socket (triggers polling). We write a PING message to determine
* when the transport is open.
*
* @api private
*/
Polling.prototype.doOpen = function () {
this.poll();
};
/**
* Pauses polling.
*
* @param {Function} callback upon buffers are flushed and transport is paused
* @api private
*/
Polling.prototype.pause = function (onPause) {
var self = this;
this.readyState = 'pausing';
function pause () {
debug('paused');
self.readyState = 'paused';
onPause();
}
if (this.polling || !this.writable) {
var total = 0;
if (this.polling) {
debug('we are currently polling - waiting to pause');
total++;
this.once('pollComplete', function () {
debug('pre-pause polling complete');
--total || pause();
});
}
if (!this.writable) {
debug('we are currently writing - waiting to pause');
total++;
this.once('drain', function () {
debug('pre-pause writing complete');
--total || pause();
});
}
} else {
pause();
}
};
/**
* Starts polling cycle.
*
* @api public
*/
Polling.prototype.poll = function () {
debug('polling');
this.polling = true;
this.doPoll();
this.emit('poll');
};
/**
* Overloads onData to detect payloads.
*
* @api private
*/
Polling.prototype.onData = function (data) {
var self = this;
debug('polling got data %s', data);
var callback = function (packet, index, total) {
// if its the first message we consider the transport open
if ('opening' === self.readyState) {
self.onOpen();
}
// if its a close packet, we close the ongoing requests
if ('close' === packet.type) {
self.onClose();
return false;
}
// otherwise bypass onData and handle the message
self.onPacket(packet);
};
// decode payload
parser.decodePayload(data, this.socket.binaryType, callback);
// if an event did not trigger closing
if ('closed' !== this.readyState) {
// if we got data we're not polling
this.polling = false;
this.emit('pollComplete');
if ('open' === this.readyState) {
this.poll();
} else {
debug('ignoring poll - transport state "%s"', this.readyState);
}
}
};
/**
* For polling, send a close packet.
*
* @api private
*/
Polling.prototype.doClose = function () {
var self = this;
function close () {
debug('writing close packet');
self.write([{ type: 'close' }]);
}
if ('open' === this.readyState) {
debug('transport open - closing');
close();
} else {
// in case we're trying to close while
// handshaking is in progress (GH-164)
debug('transport not open - deferring close');
this.once('open', close);
}
};
/**
* Writes a packets payload.
*
* @param {Array} data packets
* @param {Function} drain callback
* @api private
*/
Polling.prototype.write = function (packets) {
var self = this;
this.writable = false;
var callbackfn = function () {
self.writable = true;
self.emit('drain');
};
parser.encodePayload(packets, this.supportsBinary, function (data) {
self.doWrite(data, callbackfn);
});
};
/**
* Generates uri for connection.
*
* @api private
*/
Polling.prototype.uri = function () {
var query = this.query || {};
var schema = this.secure ? 'https' : 'http';
var port = '';
// cache busting is forced
if (false !== this.timestampRequests) {
query[this.timestampParam] = yeast();
}
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
}
query = parseqs.encode(query);
// avoid port if default for schema
if (this.port && (('https' === schema && Number(this.port) !== 443) ||
('http' === schema && Number(this.port) !== 80))) {
port = ':' + this.port;
}
// prepend ? to query
if (query.length) {
query = '?' + query;
}
var ipv6 = this.hostname.indexOf(':') !== -1;
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
};
},{"../transport":184,"component-inherit":13,"debug":180,"engine.io-parser":19,"parseqs":193,"xmlhttprequest-ssl":190,"yeast":62}],189:[function(require,module,exports){
(function (Buffer){(function (){
/**
* Module dependencies.
*/
var Transport = require('../transport');
var parser = require('engine.io-parser');
var parseqs = require('parseqs');
var inherit = require('component-inherit');
var yeast = require('yeast');
var debug = require('debug')('engine.io-client:websocket');
var BrowserWebSocket, NodeWebSocket;
if (typeof WebSocket !== 'undefined') {
BrowserWebSocket = WebSocket;
} else if (typeof self !== 'undefined') {
BrowserWebSocket = self.WebSocket || self.MozWebSocket;
} else {
try {
NodeWebSocket = require('ws');
} catch (e) { }
}
/**
* Get either the `WebSocket` or `MozWebSocket` globals
* in the browser or try to resolve WebSocket-compatible
* interface exposed by `ws` for Node-like environment.
*/
var WebSocketImpl = BrowserWebSocket || NodeWebSocket;
/**
* Module exports.
*/
module.exports = WS;
/**
* WebSocket transport constructor.
*
* @api {Object} connection options
* @api public
*/
function WS (opts) {
var forceBase64 = (opts && opts.forceBase64);
if (forceBase64) {
this.supportsBinary = false;
}
this.perMessageDeflate = opts.perMessageDeflate;
this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;
this.protocols = opts.protocols;
if (!this.usingBrowserWebSocket) {
WebSocketImpl = NodeWebSocket;
}
Transport.call(this, opts);
}
/**
* Inherits from Transport.
*/
inherit(WS, Transport);
/**
* Transport name.
*
* @api public
*/
WS.prototype.name = 'websocket';
/*
* WebSockets support binary
*/
WS.prototype.supportsBinary = true;
/**
* Opens socket.
*
* @api private
*/
WS.prototype.doOpen = function () {
if (!this.check()) {
// let probe timeout
return;
}
var uri = this.uri();
var protocols = this.protocols;
var opts = {
agent: this.agent,
perMessageDeflate: this.perMessageDeflate
};
// SSL options for Node.js client
opts.pfx = this.pfx;
opts.key = this.key;
opts.passphrase = this.passphrase;
opts.cert = this.cert;
opts.ca = this.ca;
opts.ciphers = this.ciphers;
opts.rejectUnauthorized = this.rejectUnauthorized;
if (this.extraHeaders) {
opts.headers = this.extraHeaders;
}
if (this.localAddress) {
opts.localAddress = this.localAddress;
}
try {
this.ws =
this.usingBrowserWebSocket && !this.isReactNative
? protocols
? new WebSocketImpl(uri, protocols)
: new WebSocketImpl(uri)
: new WebSocketImpl(uri, protocols, opts);
} catch (err) {
return this.emit('error', err);
}
if (this.ws.binaryType === undefined) {
this.supportsBinary = false;
}
if (this.ws.supports && this.ws.supports.binary) {
this.supportsBinary = true;
this.ws.binaryType = 'nodebuffer';
} else {
this.ws.binaryType = 'arraybuffer';
}
this.addEventListeners();
};
/**
* Adds event listeners to the socket
*
* @api private
*/
WS.prototype.addEventListeners = function () {
var self = this;
this.ws.onopen = function () {
self.onOpen();
};
this.ws.onclose = function () {
self.onClose();
};
this.ws.onmessage = function (ev) {
self.onData(ev.data);
};
this.ws.onerror = function (e) {
self.onError('websocket error', e);
};
};
/**
* Writes data to socket.
*
* @param {Array} array of packets.
* @api private
*/
WS.prototype.write = function (packets) {
var self = this;
this.writable = false;
// encodePacket efficient as it uses WS framing
// no need for encodePayload
var total = packets.length;
for (var i = 0, l = total; i < l; i++) {
(function (packet) {
parser.encodePacket(packet, self.supportsBinary, function (data) {
if (!self.usingBrowserWebSocket) {
// always create a new object (GH-437)
var opts = {};
if (packet.options) {
opts.compress = packet.options.compress;
}
if (self.perMessageDeflate) {
var len = 'string' === typeof data ? Buffer.byteLength(data) : data.length;
if (len < self.perMessageDeflate.threshold) {
opts.compress = false;
}
}
}
// Sometimes the websocket has already been closed but the browser didn't
// have a chance of informing us about it yet, in that case send will
// throw an error
try {
if (self.usingBrowserWebSocket) {
// TypeError is thrown when passing the second argument on Safari
self.ws.send(data);
} else {
self.ws.send(data, opts);
}
} catch (e) {
debug('websocket closed before onclose event');
}
--total || done();
});
})(packets[i]);
}
function done () {
self.emit('flush');
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
setTimeout(function () {
self.writable = true;
self.emit('drain');
}, 0);
}
};
/**
* Called upon close
*
* @api private
*/
WS.prototype.onClose = function () {
Transport.prototype.onClose.call(this);
};
/**
* Closes socket.
*
* @api private
*/
WS.prototype.doClose = function () {
if (typeof this.ws !== 'undefined') {
this.ws.close();
}
};
/**
* Generates uri for connection.
*
* @api private
*/
WS.prototype.uri = function () {
var query = this.query || {};
var schema = this.secure ? 'wss' : 'ws';
var port = '';
// avoid port if default for schema
if (this.port && (('wss' === schema && Number(this.port) !== 443) ||
('ws' === schema && Number(this.port) !== 80))) {
port = ':' + this.port;
}
// append timestamp to URI
if (this.timestampRequests) {
query[this.timestampParam] = yeast();
}
// communicate binary support capabilities
if (!this.supportsBinary) {
query.b64 = 1;
}
query = parseqs.encode(query);
// prepend ? to query
if (query.length) {
query = '?' + query;
}
var ipv6 = this.hostname.indexOf(':') !== -1;
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
};
/**
* Feature detection for WebSocket.
*
* @return {Boolean} whether this transport is available.
* @api public
*/
WS.prototype.check = function () {
return !!WebSocketImpl && !('__initialize' in WebSocketImpl && this.name === WS.prototype.name);
};
}).call(this)}).call(this,require("buffer").Buffer)
},{"../transport":184,"buffer":10,"component-inherit":13,"debug":180,"engine.io-parser":19,"parseqs":193,"ws":9,"yeast":62}],190:[function(require,module,exports){
// browser shim for xmlhttprequest module
var hasCORS = require('has-cors');
module.exports = function (opts) {
var xdomain = opts.xdomain;
// scheme must be same when usign XDomainRequest
// http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
var xscheme = opts.xscheme;
// XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
// https://github.com/Automattic/engine.io-client/pull/217
var enablesXDR = opts.enablesXDR;
// XMLHttpRequest can be disabled on IE
try {
if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
return new XMLHttpRequest();
}
} catch (e) { }
// Use XDomainRequest for IE8 if enablesXDR is true
// because loading bar keeps flashing when using jsonp-polling
// https://github.com/yujiosaka/socke.io-ie8-loading-example
try {
if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {
return new XDomainRequest();
}
} catch (e) { }
if (!xdomain) {
try {
return new self[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');
} catch (e) { }
}
};
},{"has-cors":28}],191:[function(require,module,exports){
arguments[4][27][0].apply(exports,arguments)
},{"dup":27}],192:[function(require,module,exports){
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function(val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isNaN(val) === false) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return;
}
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd';
}
if (ms >= h) {
return Math.round(ms / h) + 'h';
}
if (ms >= m) {
return Math.round(ms / m) + 'm';
}
if (ms >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
return plural(ms, d, 'day') ||
plural(ms, h, 'hour') ||
plural(ms, m, 'minute') ||
plural(ms, s, 'second') ||
ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, n, name) {
if (ms < n) {
return;
}
if (ms < n * 1.5) {
return Math.floor(ms / n) + ' ' + name;
}
return Math.ceil(ms / n) + ' ' + name + 's';
}
},{}],193:[function(require,module,exports){
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
exports.encode = function (obj) {
var str = '';
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length) str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
};
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
exports.decode = function(qs){
var qry = {};
var pairs = qs.split('&');
for (var i = 0, l = pairs.length; i < l; i++) {
var pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
};
},{}],194:[function(require,module,exports){
/**
* Parses an URI
*
* @author Steven Levithan <stevenlevithan.com> (MIT license)
* @api private
*/
var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
var parts = [
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
];
module.exports = function parseuri(str) {
var src = str,
b = str.indexOf('['),
e = str.indexOf(']');
if (b != -1 && e != -1) {
str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
}
var m = re.exec(str || ''),
uri = {},
i = 14;
while (i--) {
uri[parts[i]] = m[i] || '';
}
if (b != -1 && e != -1) {
uri.source = src;
uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
uri.ipv6uri = true;
}
return uri;
};
},{}],195:[function(require,module,exports){
/**
* Module dependencies.
*/
var url = require('./url');
var parser = require('socket.io-parser');
var Manager = require('./manager');
var debug = require('debug')('socket.io-client');
/**
* Module exports.
*/
module.exports = exports = lookup;
/**
* Managers cache.
*/
var cache = exports.managers = {};
/**
* Looks up an existing `Manager` for multiplexing.
* If the user summons:
*
* `io('http://localhost/a');`
* `io('http://localhost/b');`
*
* We reuse the existing instance based on same scheme/port/host,
* and we initialize sockets for each namespace.
*
* @api public
*/
function lookup (uri, opts) {
if (typeof uri === 'object') {
opts = uri;
uri = undefined;
}
opts = opts || {};
var parsed = url(uri);
var source = parsed.source;
var id = parsed.id;
var path = parsed.path;
var sameNamespace = cache[id] && path in cache[id].nsps;
var newConnection = opts.forceNew || opts['force new connection'] ||
false === opts.multiplex || sameNamespace;
var io;
if (newConnection) {
debug('ignoring socket cache for %s', source);
io = Manager(source, opts);
} else {
if (!cache[id]) {
debug('new io instance for %s', source);
cache[id] = Manager(source, opts);
}
io = cache[id];
}
if (parsed.query && !opts.query) {
opts.query = parsed.query;
}
return io.socket(parsed.path, opts);
}
/**
* Protocol version.
*
* @api public
*/
exports.protocol = parser.protocol;
/**
* `connect`.
*
* @param {String} uri
* @api public
*/
exports.connect = lookup;
/**
* Expose constructors for standalone build.
*
* @api public
*/
exports.Manager = require('./manager');
exports.Socket = require('./socket');
},{"./manager":196,"./socket":198,"./url":199,"debug":180,"socket.io-parser":201}],196:[function(require,module,exports){
/**
* Module dependencies.
*/
var eio = require('engine.io-client');
var Socket = require('./socket');
var Emitter = require('component-emitter');
var parser = require('socket.io-parser');
var on = require('./on');
var bind = require('component-bind');
var debug = require('debug')('socket.io-client:manager');
var indexOf = require('indexof');
var Backoff = require('backo2');
/**
* IE6+ hasOwnProperty
*/
var has = Object.prototype.hasOwnProperty;
/**
* Module exports
*/
module.exports = Manager;
/**
* `Manager` constructor.
*
* @param {String} engine instance or engine uri/opts
* @param {Object} options
* @api public
*/
function Manager (uri, opts) {
if (!(this instanceof Manager)) return new Manager(uri, opts);
if (uri && ('object' === typeof uri)) {
opts = uri;
uri = undefined;
}
opts = opts || {};
opts.path = opts.path || '/socket.io';
this.nsps = {};
this.subs = [];
this.opts = opts;
this.reconnection(opts.reconnection !== false);
this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
this.reconnectionDelay(opts.reconnectionDelay || 1000);
this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
this.randomizationFactor(opts.randomizationFactor || 0.5);
this.backoff = new Backoff({
min: this.reconnectionDelay(),
max: this.reconnectionDelayMax(),
jitter: this.randomizationFactor()
});
this.timeout(null == opts.timeout ? 20000 : opts.timeout);
this.readyState = 'closed';
this.uri = uri;
this.connecting = [];
this.lastPing = null;
this.encoding = false;
this.packetBuffer = [];
var _parser = opts.parser || parser;
this.encoder = new _parser.Encoder();
this.decoder = new _parser.Decoder();
this.autoConnect = opts.autoConnect !== false;
if (this.autoConnect) this.open();
}
/**
* Propagate given event to sockets and emit on `this`
*
* @api private
*/
Manager.prototype.emitAll = function () {
this.emit.apply(this, arguments);
for (var nsp in this.nsps) {
if (has.call(this.nsps, nsp)) {
this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
}
}
};
/**
* Update `socket.id` of all sockets
*
* @api private
*/
Manager.prototype.updateSocketIds = function () {
for (var nsp in this.nsps) {
if (has.call(this.nsps, nsp)) {
this.nsps[nsp].id = this.generateId(nsp);
}
}
};
/**
* generate `socket.id` for the given `nsp`
*
* @param {String} nsp
* @return {String}
* @api private
*/
Manager.prototype.generateId = function (nsp) {
return (nsp === '/' ? '' : (nsp + '#')) + this.engine.id;
};
/**
* Mix in `Emitter`.
*/
Emitter(Manager.prototype);
/**
* Sets the `reconnection` config.
*
* @param {Boolean} true/false if it should automatically reconnect
* @return {Manager} self or value
* @api public
*/
Manager.prototype.reconnection = function (v) {
if (!arguments.length) return this._reconnection;
this._reconnection = !!v;
return this;
};
/**
* Sets the reconnection attempts config.
*
* @param {Number} max reconnection attempts before giving up
* @return {Manager} self or value
* @api public
*/
Manager.prototype.reconnectionAttempts = function (v) {
if (!arguments.length) return this._reconnectionAttempts;
this._reconnectionAttempts = v;
return this;
};
/**
* Sets the delay between reconnections.
*
* @param {Number} delay
* @return {Manager} self or value
* @api public
*/
Manager.prototype.reconnectionDelay = function (v) {
if (!arguments.length) return this._reconnectionDelay;
this._reconnectionDelay = v;
this.backoff && this.backoff.setMin(v);
return this;
};
Manager.prototype.randomizationFactor = function (v) {
if (!arguments.length) return this._randomizationFactor;
this._randomizationFactor = v;
this.backoff && this.backoff.setJitter(v);
return this;
};
/**
* Sets the maximum delay between reconnections.
*
* @param {Number} delay
* @return {Manager} self or value
* @api public
*/
Manager.prototype.reconnectionDelayMax = function (v) {
if (!arguments.length) return this._reconnectionDelayMax;
this._reconnectionDelayMax = v;
this.backoff && this.backoff.setMax(v);
return this;
};
/**
* Sets the connection timeout. `false` to disable
*
* @return {Manager} self or value
* @api public
*/
Manager.prototype.timeout = function (v) {
if (!arguments.length) return this._timeout;
this._timeout = v;
return this;
};
/**
* Starts trying to reconnect if reconnection is enabled and we have not
* started reconnecting yet
*
* @api private
*/
Manager.prototype.maybeReconnectOnOpen = function () {
// Only try to reconnect if it's the first time we're connecting
if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {
// keeps reconnection from firing twice for the same reconnection loop
this.reconnect();
}
};
/**
* Sets the current transport `socket`.
*
* @param {Function} optional, callback
* @return {Manager} self
* @api public
*/
Manager.prototype.open =
Manager.prototype.connect = function (fn, opts) {
debug('readyState %s', this.readyState);
if (~this.readyState.indexOf('open')) return this;
debug('opening %s', this.uri);
this.engine = eio(this.uri, this.opts);
var socket = this.engine;
var self = this;
this.readyState = 'opening';
this.skipReconnect = false;
// emit `open`
var openSub = on(socket, 'open', function () {
self.onopen();
fn && fn();
});
// emit `connect_error`
var errorSub = on(socket, 'error', function (data) {
debug('connect_error');
self.cleanup();
self.readyState = 'closed';
self.emitAll('connect_error', data);
if (fn) {
var err = new Error('Connection error');
err.data = data;
fn(err);
} else {
// Only do this if there is no fn to handle the error
self.maybeReconnectOnOpen();
}
});
// emit `connect_timeout`
if (false !== this._timeout) {
var timeout = this._timeout;
debug('connect attempt will timeout after %d', timeout);
// set timer
var timer = setTimeout(function () {
debug('connect attempt timed out after %d', timeout);
openSub.destroy();
socket.close();
socket.emit('error', 'timeout');
self.emitAll('connect_timeout', timeout);
}, timeout);
this.subs.push({
destroy: function () {
clearTimeout(timer);
}
});
}
this.subs.push(openSub);
this.subs.push(errorSub);
return this;
};
/**
* Called upon transport open.
*
* @api private
*/
Manager.prototype.onopen = function () {
debug('open');
// clear old subs
this.cleanup();
// mark as open
this.readyState = 'open';
this.emit('open');
// add new subs
var socket = this.engine;
this.subs.push(on(socket, 'data', bind(this, 'ondata')));
this.subs.push(on(socket, 'ping', bind(this, 'onping')));
this.subs.push(on(socket, 'pong', bind(this, 'onpong')));
this.subs.push(on(socket, 'error', bind(this, 'onerror')));
this.subs.push(on(socket, 'close', bind(this, 'onclose')));
this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
};
/**
* Called upon a ping.
*
* @api private
*/
Manager.prototype.onping = function () {
this.lastPing = new Date();
this.emitAll('ping');
};
/**
* Called upon a packet.
*
* @api private
*/
Manager.prototype.onpong = function () {
this.emitAll('pong', new Date() - this.lastPing);
};
/**
* Called with data.
*
* @api private
*/
Manager.prototype.ondata = function (data) {
this.decoder.add(data);
};
/**
* Called when parser fully decodes a packet.
*
* @api private
*/
Manager.prototype.ondecoded = function (packet) {
this.emit('packet', packet);
};
/**
* Called upon socket error.
*
* @api private
*/
Manager.prototype.onerror = function (err) {
debug('error', err);
this.emitAll('error', err);
};
/**
* Creates a new socket for the given `nsp`.
*
* @return {Socket}
* @api public
*/
Manager.prototype.socket = function (nsp, opts) {
var socket = this.nsps[nsp];
if (!socket) {
socket = new Socket(this, nsp, opts);
this.nsps[nsp] = socket;
var self = this;
socket.on('connecting', onConnecting);
socket.on('connect', function () {
socket.id = self.generateId(nsp);
});
if (this.autoConnect) {
// manually call here since connecting event is fired before listening
onConnecting();
}
}
function onConnecting () {
if (!~indexOf(self.connecting, socket)) {
self.connecting.push(socket);
}
}
return socket;
};
/**
* Called upon a socket close.
*
* @param {Socket} socket
*/
Manager.prototype.destroy = function (socket) {
var index = indexOf(this.connecting, socket);
if (~index) this.connecting.splice(index, 1);
if (this.connecting.length) return;
this.close();
};
/**
* Writes a packet.
*
* @param {Object} packet
* @api private
*/
Manager.prototype.packet = function (packet) {
debug('writing packet %j', packet);
var self = this;
if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;
if (!self.encoding) {
// encode, then write to engine with result
self.encoding = true;
this.encoder.encode(packet, function (encodedPackets) {
for (var i = 0; i < encodedPackets.length; i++) {
self.engine.write(encodedPackets[i], packet.options);
}
self.encoding = false;
self.processPacketQueue();
});
} else { // add packet to the queue
self.packetBuffer.push(packet);
}
};
/**
* If packet buffer is non-empty, begins encoding the
* next packet in line.
*
* @api private
*/
Manager.prototype.processPacketQueue = function () {
if (this.packetBuffer.length > 0 && !this.encoding) {
var pack = this.packetBuffer.shift();
this.packet(pack);
}
};
/**
* Clean up transport subscriptions and packet buffer.
*
* @api private
*/
Manager.prototype.cleanup = function () {
debug('cleanup');
var subsLength = this.subs.length;
for (var i = 0; i < subsLength; i++) {
var sub = this.subs.shift();
sub.destroy();
}
this.packetBuffer = [];
this.encoding = false;
this.lastPing = null;
this.decoder.destroy();
};
/**
* Close the current socket.
*
* @api private
*/
Manager.prototype.close =
Manager.prototype.disconnect = function () {
debug('disconnect');
this.skipReconnect = true;
this.reconnecting = false;
if ('opening' === this.readyState) {
// `onclose` will not fire because
// an open event never happened
this.cleanup();
}
this.backoff.reset();
this.readyState = 'closed';
if (this.engine) this.engine.close();
};
/**
* Called upon engine close.
*
* @api private
*/
Manager.prototype.onclose = function (reason) {
debug('onclose');
this.cleanup();
this.backoff.reset();
this.readyState = 'closed';
this.emit('close', reason);
if (this._reconnection && !this.skipReconnect) {
this.reconnect();
}
};
/**
* Attempt a reconnection.
*
* @api private
*/
Manager.prototype.reconnect = function () {
if (this.reconnecting || this.skipReconnect) return this;
var self = this;
if (this.backoff.attempts >= this._reconnectionAttempts) {
debug('reconnect failed');
this.backoff.reset();
this.emitAll('reconnect_failed');
this.reconnecting = false;
} else {
var delay = this.backoff.duration();
debug('will wait %dms before reconnect attempt', delay);
this.reconnecting = true;
var timer = setTimeout(function () {
if (self.skipReconnect) return;
debug('attempting reconnect');
self.emitAll('reconnect_attempt', self.backoff.attempts);
self.emitAll('reconnecting', self.backoff.attempts);
// check again for the case socket closed in above events
if (self.skipReconnect) return;
self.open(function (err) {
if (err) {
debug('reconnect attempt error');
self.reconnecting = false;
self.reconnect();
self.emitAll('reconnect_error', err.data);
} else {
debug('reconnect success');
self.onreconnect();
}
});
}, delay);
this.subs.push({
destroy: function () {
clearTimeout(timer);
}
});
}
};
/**
* Called upon successful reconnect.
*
* @api private
*/
Manager.prototype.onreconnect = function () {
var attempt = this.backoff.attempts;
this.reconnecting = false;
this.backoff.reset();
this.updateSocketIds();
this.emitAll('reconnect', attempt);
};
},{"./on":197,"./socket":198,"backo2":5,"component-bind":12,"component-emitter":179,"debug":180,"engine.io-client":182,"indexof":30,"socket.io-parser":201}],197:[function(require,module,exports){
/**
* Module exports.
*/
module.exports = on;
/**
* Helper for subscriptions.
*
* @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
* @param {String} event name
* @param {Function} callback
* @api public
*/
function on (obj, ev, fn) {
obj.on(ev, fn);
return {
destroy: function () {
obj.removeListener(ev, fn);
}
};
}
},{}],198:[function(require,module,exports){
/**
* Module dependencies.
*/
var parser = require('socket.io-parser');
var Emitter = require('component-emitter');
var toArray = require('to-array');
var on = require('./on');
var bind = require('component-bind');
var debug = require('debug')('socket.io-client:socket');
var parseqs = require('parseqs');
var hasBin = require('has-binary2');
/**
* Module exports.
*/
module.exports = exports = Socket;
/**
* Internal events (blacklisted).
* These events can't be emitted by the user.
*
* @api private
*/
var events = {
connect: 1,
connect_error: 1,
connect_timeout: 1,
connecting: 1,
disconnect: 1,
error: 1,
reconnect: 1,
reconnect_attempt: 1,
reconnect_failed: 1,
reconnect_error: 1,
reconnecting: 1,
ping: 1,
pong: 1
};
/**
* Shortcut to `Emitter#emit`.
*/
var emit = Emitter.prototype.emit;
/**
* `Socket` constructor.
*
* @api public
*/
function Socket (io, nsp, opts) {
this.io = io;
this.nsp = nsp;
this.json = this; // compat
this.ids = 0;
this.acks = {};
this.receiveBuffer = [];
this.sendBuffer = [];
this.connected = false;
this.disconnected = true;
this.flags = {};
if (opts && opts.query) {
this.query = opts.query;
}
if (this.io.autoConnect) this.open();
}
/**
* Mix in `Emitter`.
*/
Emitter(Socket.prototype);
/**
* Subscribe to open, close and packet events
*
* @api private
*/
Socket.prototype.subEvents = function () {
if (this.subs) return;
var io = this.io;
this.subs = [
on(io, 'open', bind(this, 'onopen')),
on(io, 'packet', bind(this, 'onpacket')),
on(io, 'close', bind(this, 'onclose'))
];
};
/**
* "Opens" the socket.
*
* @api public
*/
Socket.prototype.open =
Socket.prototype.connect = function () {
if (this.connected) return this;
this.subEvents();
this.io.open(); // ensure open
if ('open' === this.io.readyState) this.onopen();
this.emit('connecting');
return this;
};
/**
* Sends a `message` event.
*
* @return {Socket} self
* @api public
*/
Socket.prototype.send = function () {
var args = toArray(arguments);
args.unshift('message');
this.emit.apply(this, args);
return this;
};
/**
* Override `emit`.
* If the event is in `events`, it's emitted normally.
*
* @param {String} event name
* @return {Socket} self
* @api public
*/
Socket.prototype.emit = function (ev) {
if (events.hasOwnProperty(ev)) {
emit.apply(this, arguments);
return this;
}
var args = toArray(arguments);
var packet = {
type: (this.flags.binary !== undefined ? this.flags.binary : hasBin(args)) ? parser.BINARY_EVENT : parser.EVENT,
data: args
};
packet.options = {};
packet.options.compress = !this.flags || false !== this.flags.compress;
// event ack callback
if ('function' === typeof args[args.length - 1]) {
debug('emitting packet with ack id %d', this.ids);
this.acks[this.ids] = args.pop();
packet.id = this.ids++;
}
if (this.connected) {
this.packet(packet);
} else {
this.sendBuffer.push(packet);
}
this.flags = {};
return this;
};
/**
* Sends a packet.
*
* @param {Object} packet
* @api private
*/
Socket.prototype.packet = function (packet) {
packet.nsp = this.nsp;
this.io.packet(packet);
};
/**
* Called upon engine `open`.
*
* @api private
*/
Socket.prototype.onopen = function () {
debug('transport is open - connecting');
// write connect packet if necessary
if ('/' !== this.nsp) {
if (this.query) {
var query = typeof this.query === 'object' ? parseqs.encode(this.query) : this.query;
debug('sending connect packet with query %s', query);
this.packet({type: parser.CONNECT, query: query});
} else {
this.packet({type: parser.CONNECT});
}
}
};
/**
* Called upon engine `close`.
*
* @param {String} reason
* @api private
*/
Socket.prototype.onclose = function (reason) {
debug('close (%s)', reason);
this.connected = false;
this.disconnected = true;
delete this.id;
this.emit('disconnect', reason);
};
/**
* Called with socket packet.
*
* @param {Object} packet
* @api private
*/
Socket.prototype.onpacket = function (packet) {
var sameNamespace = packet.nsp === this.nsp;
var rootNamespaceError = packet.type === parser.ERROR && packet.nsp === '/';
if (!sameNamespace && !rootNamespaceError) return;
switch (packet.type) {
case parser.CONNECT:
this.onconnect();
break;
case parser.EVENT:
this.onevent(packet);
break;
case parser.BINARY_EVENT:
this.onevent(packet);
break;
case parser.ACK:
this.onack(packet);
break;
case parser.BINARY_ACK:
this.onack(packet);
break;
case parser.DISCONNECT:
this.ondisconnect();
break;
case parser.ERROR:
this.emit('error', packet.data);
break;
}
};
/**
* Called upon a server event.
*
* @param {Object} packet
* @api private
*/
Socket.prototype.onevent = function (packet) {
var args = packet.data || [];
debug('emitting event %j', args);
if (null != packet.id) {
debug('attaching ack callback to event');
args.push(this.ack(packet.id));
}
if (this.connected) {
emit.apply(this, args);
} else {
this.receiveBuffer.push(args);
}
};
/**
* Produces an ack callback to emit with an event.
*
* @api private
*/
Socket.prototype.ack = function (id) {
var self = this;
var sent = false;
return function () {
// prevent double callbacks
if (sent) return;
sent = true;
var args = toArray(arguments);
debug('sending ack %j', args);
self.packet({
type: hasBin(args) ? parser.BINARY_ACK : parser.ACK,
id: id,
data: args
});
};
};
/**
* Called upon a server acknowlegement.
*
* @param {Object} packet
* @api private
*/
Socket.prototype.onack = function (packet) {
var ack = this.acks[packet.id];
if ('function' === typeof ack) {
debug('calling ack %s with %j', packet.id, packet.data);
ack.apply(this, packet.data);
delete this.acks[packet.id];
} else {
debug('bad ack %s', packet.id);
}
};
/**
* Called upon server connect.
*
* @api private
*/
Socket.prototype.onconnect = function () {
this.connected = true;
this.disconnected = false;
this.emit('connect');
this.emitBuffered();
};
/**
* Emit buffered events (received and emitted).
*
* @api private
*/
Socket.prototype.emitBuffered = function () {
var i;
for (i = 0; i < this.receiveBuffer.length; i++) {
emit.apply(this, this.receiveBuffer[i]);
}
this.receiveBuffer = [];
for (i = 0; i < this.sendBuffer.length; i++) {
this.packet(this.sendBuffer[i]);
}
this.sendBuffer = [];
};
/**
* Called upon server disconnect.
*
* @api private
*/
Socket.prototype.ondisconnect = function () {
debug('server disconnect (%s)', this.nsp);
this.destroy();
this.onclose('io server disconnect');
};
/**
* Called upon forced client/server side disconnections,
* this method ensures the manager stops tracking us and
* that reconnections don't get triggered for this.
*
* @api private.
*/
Socket.prototype.destroy = function () {
if (this.subs) {
// clean subscriptions to avoid reconnections
for (var i = 0; i < this.subs.length; i++) {
this.subs[i].destroy();
}
this.subs = null;
}
this.io.destroy(this);
};
/**
* Disconnects the socket manually.
*
* @return {Socket} self
* @api public
*/
Socket.prototype.close =
Socket.prototype.disconnect = function () {
if (this.connected) {
debug('performing disconnect (%s)', this.nsp);
this.packet({ type: parser.DISCONNECT });
}
// remove socket from pool
this.destroy();
if (this.connected) {
// fire events
this.onclose('io client disconnect');
}
return this;
};
/**
* Sets the compress flag.
*
* @param {Boolean} if `true`, compresses the sending data
* @return {Socket} self
* @api public
*/
Socket.prototype.compress = function (compress) {
this.flags.compress = compress;
return this;
};
/**
* Sets the binary flag
*
* @param {Boolean} whether the emitted data contains binary
* @return {Socket} self
* @api public
*/
Socket.prototype.binary = function (binary) {
this.flags.binary = binary;
return this;
};
},{"./on":197,"component-bind":12,"component-emitter":179,"debug":180,"has-binary2":26,"parseqs":193,"socket.io-parser":201,"to-array":44}],199:[function(require,module,exports){
/**
* Module dependencies.
*/
var parseuri = require('parseuri');
var debug = require('debug')('socket.io-client:url');
/**
* Module exports.
*/
module.exports = url;
/**
* URL parser.
*
* @param {String} url
* @param {Object} An object meant to mimic window.location.
* Defaults to window.location.
* @api public
*/
function url (uri, loc) {
var obj = uri;
// default to window.location
loc = loc || (typeof location !== 'undefined' && location);
if (null == uri) uri = loc.protocol + '//' + loc.host;
// relative path support
if ('string' === typeof uri) {
if ('/' === uri.charAt(0)) {
if ('/' === uri.charAt(1)) {
uri = loc.protocol + uri;
} else {
uri = loc.host + uri;
}
}
if (!/^(https?|wss?):\/\//.test(uri)) {
debug('protocol-less url %s', uri);
if ('undefined' !== typeof loc) {
uri = loc.protocol + '//' + uri;
} else {
uri = 'https://' + uri;
}
}
// parse
debug('parse %s', uri);
obj = parseuri(uri);
}
// make sure we treat `localhost:80` and `localhost` equally
if (!obj.port) {
if (/^(http|ws)$/.test(obj.protocol)) {
obj.port = '80';
} else if (/^(http|ws)s$/.test(obj.protocol)) {
obj.port = '443';
}
}
obj.path = obj.path || '/';
var ipv6 = obj.host.indexOf(':') !== -1;
var host = ipv6 ? '[' + obj.host + ']' : obj.host;
// define unique id
obj.id = obj.protocol + '://' + host + ':' + obj.port;
// define href
obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port));
return obj;
}
},{"debug":180,"parseuri":194}],200:[function(require,module,exports){
/*global Blob,File*/
/**
* Module requirements
*/
var isArray = require('isarray');
var isBuf = require('./is-buffer');
var toString = Object.prototype.toString;
var withNativeBlob = typeof Blob === 'function' || (typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]');
var withNativeFile = typeof File === 'function' || (typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]');
/**
* Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
* Anything with blobs or files should be fed through removeBlobs before coming
* here.
*
* @param {Object} packet - socket.io event packet
* @return {Object} with deconstructed packet and list of buffers
* @api public
*/
exports.deconstructPacket = function(packet) {
var buffers = [];
var packetData = packet.data;
var pack = packet;
pack.data = _deconstructPacket(packetData, buffers);
pack.attachments = buffers.length; // number of binary 'attachments'
return {packet: pack, buffers: buffers};
};
function _deconstructPacket(data, buffers) {
if (!data) return data;
if (isBuf(data)) {
var placeholder = { _placeholder: true, num: buffers.length };
buffers.push(data);
return placeholder;
} else if (isArray(data)) {
var newData = new Array(data.length);
for (var i = 0; i < data.length; i++) {
newData[i] = _deconstructPacket(data[i], buffers);
}
return newData;
} else if (typeof data === 'object' && !(data instanceof Date)) {
var newData = {};
for (var key in data) {
newData[key] = _deconstructPacket(data[key], buffers);
}
return newData;
}
return data;
}
/**
* Reconstructs a binary packet from its placeholder packet and buffers
*
* @param {Object} packet - event packet with placeholders
* @param {Array} buffers - binary buffers to put in placeholder positions
* @return {Object} reconstructed packet
* @api public
*/
exports.reconstructPacket = function(packet, buffers) {
packet.data = _reconstructPacket(packet.data, buffers);
packet.attachments = undefined; // no longer useful
return packet;
};
function _reconstructPacket(data, buffers) {
if (!data) return data;
if (data && data._placeholder) {
return buffers[data.num]; // appropriate buffer (should be natural order anyway)
} else if (isArray(data)) {
for (var i = 0; i < data.length; i++) {
data[i] = _reconstructPacket(data[i], buffers);
}
} else if (typeof data === 'object') {
for (var key in data) {
data[key] = _reconstructPacket(data[key], buffers);
}
}
return data;
}
/**
* Asynchronously removes Blobs or Files from data via
* FileReader's readAsArrayBuffer method. Used before encoding
* data as msgpack. Calls callback with the blobless data.
*
* @param {Object} data
* @param {Function} callback
* @api private
*/
exports.removeBlobs = function(data, callback) {
function _removeBlobs(obj, curKey, containingObject) {
if (!obj) return obj;
// convert any blob
if ((withNativeBlob && obj instanceof Blob) ||
(withNativeFile && obj instanceof File)) {
pendingBlobs++;
// async filereader
var fileReader = new FileReader();
fileReader.onload = function() { // this.result == arraybuffer
if (containingObject) {
containingObject[curKey] = this.result;
}
else {
bloblessData = this.result;
}
// if nothing pending its callback time
if(! --pendingBlobs) {
callback(bloblessData);
}
};
fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
} else if (isArray(obj)) { // handle array
for (var i = 0; i < obj.length; i++) {
_removeBlobs(obj[i], i, obj);
}
} else if (typeof obj === 'object' && !isBuf(obj)) { // and object
for (var key in obj) {
_removeBlobs(obj[key], key, obj);
}
}
}
var pendingBlobs = 0;
var bloblessData = data;
_removeBlobs(bloblessData);
if (!pendingBlobs) {
callback(bloblessData);
}
};
},{"./is-buffer":202,"isarray":191}],201:[function(require,module,exports){
/**
* Module dependencies.
*/
var debug = require('debug')('socket.io-parser');
var Emitter = require('component-emitter');
var binary = require('./binary');
var isArray = require('isarray');
var isBuf = require('./is-buffer');
/**
* Protocol version.
*
* @api public
*/
exports.protocol = 4;
/**
* Packet types.
*
* @api public
*/
exports.types = [
'CONNECT',
'DISCONNECT',
'EVENT',
'ACK',
'ERROR',
'BINARY_EVENT',
'BINARY_ACK'
];
/**
* Packet type `connect`.
*
* @api public
*/
exports.CONNECT = 0;
/**
* Packet type `disconnect`.
*
* @api public
*/
exports.DISCONNECT = 1;
/**
* Packet type `event`.
*
* @api public
*/
exports.EVENT = 2;
/**
* Packet type `ack`.
*
* @api public
*/
exports.ACK = 3;
/**
* Packet type `error`.
*
* @api public
*/
exports.ERROR = 4;
/**
* Packet type 'binary event'
*
* @api public
*/
exports.BINARY_EVENT = 5;
/**
* Packet type `binary ack`. For acks with binary arguments.
*
* @api public
*/
exports.BINARY_ACK = 6;
/**
* Encoder constructor.
*
* @api public
*/
exports.Encoder = Encoder;
/**
* Decoder constructor.
*
* @api public
*/
exports.Decoder = Decoder;
/**
* A socket.io Encoder instance
*
* @api public
*/
function Encoder() {}
var ERROR_PACKET = exports.ERROR + '"encode error"';
/**
* Encode a packet as a single string if non-binary, or as a
* buffer sequence, depending on packet type.
*
* @param {Object} obj - packet object
* @param {Function} callback - function to handle encodings (likely engine.write)
* @return Calls callback with Array of encodings
* @api public
*/
Encoder.prototype.encode = function(obj, callback){
debug('encoding packet %j', obj);
if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) {
encodeAsBinary(obj, callback);
} else {
var encoding = encodeAsString(obj);
callback([encoding]);
}
};
/**
* Encode packet as string.
*
* @param {Object} packet
* @return {String} encoded
* @api private
*/
function encodeAsString(obj) {
// first is type
var str = '' + obj.type;
// attachments if we have them
if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) {
str += obj.attachments + '-';
}
// if we have a namespace other than `/`
// we append it followed by a comma `,`
if (obj.nsp && '/' !== obj.nsp) {
str += obj.nsp + ',';
}
// immediately followed by the id
if (null != obj.id) {
str += obj.id;
}
// json data
if (null != obj.data) {
var payload = tryStringify(obj.data);
if (payload !== false) {
str += payload;
} else {
return ERROR_PACKET;
}
}
debug('encoded %j as %s', obj, str);
return str;
}
function tryStringify(str) {
try {
return JSON.stringify(str);
} catch(e){
return false;
}
}
/**
* Encode packet as 'buffer sequence' by removing blobs, and
* deconstructing packet into object with placeholders and
* a list of buffers.
*
* @param {Object} packet
* @return {Buffer} encoded
* @api private
*/
function encodeAsBinary(obj, callback) {
function writeEncoding(bloblessData) {
var deconstruction = binary.deconstructPacket(bloblessData);
var pack = encodeAsString(deconstruction.packet);
var buffers = deconstruction.buffers;
buffers.unshift(pack); // add packet info to beginning of data list
callback(buffers); // write all the buffers
}
binary.removeBlobs(obj, writeEncoding);
}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
* @api public
*/
function Decoder() {
this.reconstructor = null;
}
/**
* Mix in `Emitter` with Decoder.
*/
Emitter(Decoder.prototype);
/**
* Decodes an encoded packet string into packet JSON.
*
* @param {String} obj - encoded packet
* @return {Object} packet
* @api public
*/
Decoder.prototype.add = function(obj) {
var packet;
if (typeof obj === 'string') {
packet = decodeString(obj);
if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { // binary packet's json
this.reconstructor = new BinaryReconstructor(packet);
// no attachments, labeled binary but no binary data to follow
if (this.reconstructor.reconPack.attachments === 0) {
this.emit('decoded', packet);
}
} else { // non-binary full packet
this.emit('decoded', packet);
}
} else if (isBuf(obj) || obj.base64) { // raw binary data
if (!this.reconstructor) {
throw new Error('got binary data when not reconstructing a packet');
} else {
packet = this.reconstructor.takeBinaryData(obj);
if (packet) { // received final buffer
this.reconstructor = null;
this.emit('decoded', packet);
}
}
} else {
throw new Error('Unknown type: ' + obj);
}
};
/**
* Decode a packet String (JSON data)
*
* @param {String} str
* @return {Object} packet
* @api private
*/
function decodeString(str) {
var i = 0;
// look up type
var p = {
type: Number(str.charAt(0))
};
if (null == exports.types[p.type]) {
return error('unknown packet type ' + p.type);
}
// look up attachments if type binary
if (exports.BINARY_EVENT === p.type || exports.BINARY_ACK === p.type) {
var start = i + 1;
while (str.charAt(++i) !== '-' && i != str.length) {}
var buf = str.substring(start, i);
if (buf != Number(buf) || str.charAt(i) !== '-') {
throw new Error('Illegal attachments');
}
p.attachments = Number(buf);
}
// look up namespace (if any)
if ('/' === str.charAt(i + 1)) {
var start = i + 1;
while (++i) {
var c = str.charAt(i);
if (',' === c) break;
if (i === str.length) break;
}
p.nsp = str.substring(start, i);
} else {
p.nsp = '/';
}
// look up id
var next = str.charAt(i + 1);
if ('' !== next && Number(next) == next) {
var start = i + 1;
while (++i) {
var c = str.charAt(i);
if (null == c || Number(c) != c) {
--i;
break;
}
if (i === str.length) break;
}
p.id = Number(str.substring(start, i + 1));
}
// look up json data
if (str.charAt(++i)) {
var payload = tryParse(str.substr(i));
var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload));
if (isPayloadValid) {
p.data = payload;
} else {
return error('invalid payload');
}
}
debug('decoded %s as %j', str, p);
return p;
}
function tryParse(str) {
try {
return JSON.parse(str);
} catch(e){
return false;
}
}
/**
* Deallocates a parser's resources
*
* @api public
*/
Decoder.prototype.destroy = function() {
if (this.reconstructor) {
this.reconstructor.finishedReconstruction();
}
};
/**
* A manager of a binary event's 'buffer sequence'. Should
* be constructed whenever a packet of type BINARY_EVENT is
* decoded.
*
* @param {Object} packet
* @return {BinaryReconstructor} initialized reconstructor
* @api private
*/
function BinaryReconstructor(packet) {
this.reconPack = packet;
this.buffers = [];
}
/**
* Method to be called when binary data received from connection
* after a BINARY_EVENT packet.
*
* @param {Buffer | ArrayBuffer} binData - the raw binary data received
* @return {null | Object} returns null if more binary data is expected or
* a reconstructed packet object if all buffers have been received.
* @api private
*/
BinaryReconstructor.prototype.takeBinaryData = function(binData) {
this.buffers.push(binData);
if (this.buffers.length === this.reconPack.attachments) { // done with buffer list
var packet = binary.reconstructPacket(this.reconPack, this.buffers);
this.finishedReconstruction();
return packet;
}
return null;
};
/**
* Cleans up binary packet reconstruction variables.
*
* @api private
*/
BinaryReconstructor.prototype.finishedReconstruction = function() {
this.reconPack = null;
this.buffers = [];
};
function error(msg) {
return {
type: exports.ERROR,
data: 'parser error: ' + msg
};
}
},{"./binary":200,"./is-buffer":202,"component-emitter":203,"debug":180,"isarray":191}],202:[function(require,module,exports){
(function (Buffer){(function (){
module.exports = isBuf;
var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function';
var withNativeArrayBuffer = typeof ArrayBuffer === 'function';
var isView = function (obj) {
return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : (obj.buffer instanceof ArrayBuffer);
};
/**
* Returns true if obj is a buffer or an arraybuffer.
*
* @api private
*/
function isBuf(obj) {
return (withNativeBuffer && Buffer.isBuffer(obj)) ||
(withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)));
}
}).call(this)}).call(this,require("buffer").Buffer)
},{"buffer":10}],203:[function(require,module,exports){
/**
* Expose `Emitter`.
*/
if (typeof module !== 'undefined') {
module.exports = Emitter;
}
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
// Remove event specific arrays for event types that no
// one is subscribed for to avoid memory leak.
if (callbacks.length === 0) {
delete this._callbacks['$' + event];
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = new Array(arguments.length - 1)
, callbacks = this._callbacks['$' + event];
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
},{}],204:[function(require,module,exports){
var tus = require('tus-js-client');
function isCordova() {
return typeof window !== 'undefined' && (typeof window.PhoneGap !== 'undefined' || typeof window.Cordova !== 'undefined' || typeof window.cordova !== 'undefined');
}
function isReactNative() {
return typeof navigator !== 'undefined' && typeof navigator.product === 'string' && navigator.product.toLowerCase() === 'reactnative';
} // We override tus fingerprint to uppy’s `file.id`, since the `file.id`
// now also includes `relativePath` for files added from folders.
// This means you can add 2 identical files, if one is in folder a,
// the other in folder b — `a/file.jpg` and `b/file.jpg`, when added
// together with a folder, will be treated as 2 separate files.
//
// For React Native and Cordova, we let tus-js-client’s default
// fingerprint handling take charge.
module.exports = function getFingerprint(uppyFileObj) {
return function (file, options) {
if (isCordova() || isReactNative()) {
return tus.defaultOptions.fingerprint(file, options);
}
var uppyFingerprint = ['tus', uppyFileObj.id, options.endpoint].join('-');
return Promise.resolve(uppyFingerprint);
};
};
},{"tus-js-client":48}],205:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var tus = require('tus-js-client');
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider,
RequestClient = _require2.RequestClient,
Socket = _require2.Socket;
var emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress');
var getSocketHost = require('@uppy/utils/lib/getSocketHost');
var settle = require('@uppy/utils/lib/settle');
var EventTracker = require('@uppy/utils/lib/EventTracker');
var NetworkError = require('@uppy/utils/lib/NetworkError');
var isNetworkError = require('@uppy/utils/lib/isNetworkError');
var RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue');
var hasProperty = require('@uppy/utils/lib/hasProperty');
var getFingerprint = require('./getFingerprint');
/** @typedef {import('..').TusOptions} TusOptions */
/** @typedef {import('tus-js-client').UploadOptions} RawTusOptions */
/** @typedef {import('@uppy/core').Uppy} Uppy */
/** @typedef {import('@uppy/core').UppyFile} UppyFile */
/** @typedef {import('@uppy/core').FailedUppyFile<{}>} FailedUppyFile */
/**
* Extracted from https://github.com/tus/tus-js-client/blob/master/lib/upload.js#L13
* excepted we removed 'fingerprint' key to avoid adding more dependencies
*
* @type {RawTusOptions}
*/
var tusDefaultOptions = {
endpoint: '',
uploadUrl: null,
metadata: {},
uploadSize: null,
onProgress: null,
onChunkComplete: null,
onSuccess: null,
onError: null,
overridePatchMethod: false,
headers: {},
addRequestId: false,
chunkSize: Infinity,
retryDelays: [0, 1000, 3000, 5000],
parallelUploads: 1,
storeFingerprintForResuming: true,
removeFingerprintOnSuccess: false,
uploadLengthDeferred: false,
uploadDataDuringCreation: false
};
/**
* Tus resumable file uploader
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Tus, _Plugin);
/**
* @param {Uppy} uppy
* @param {TusOptions} opts
*/
function Tus(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'uploader';
_this.id = _this.opts.id || 'Tus';
_this.title = 'Tus'; // set default options
var defaultOptions = {
autoRetry: true,
resume: true,
useFastRemoteRetry: true,
limit: 0,
retryDelays: [0, 1000, 3000, 5000],
withCredentials: false
}; // merge default options with the ones set by user
/** @type {import("..").TusOptions} */
_this.opts = _extends({}, defaultOptions, opts);
/**
* Simultaneous upload limiting is shared across all uploads with this plugin.
*
* @type {RateLimitedQueue}
*/
_this.requests = new RateLimitedQueue(_this.opts.limit);
_this.uploaders = Object.create(null);
_this.uploaderEvents = Object.create(null);
_this.uploaderSockets = Object.create(null);
_this.handleResetProgress = _this.handleResetProgress.bind(_assertThisInitialized(_this));
_this.handleUpload = _this.handleUpload.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = Tus.prototype;
_proto.handleResetProgress = function handleResetProgress() {
var files = _extends({}, this.uppy.getState().files);
Object.keys(files).forEach(function (fileID) {
// Only clone the file object if it has a Tus `uploadUrl` attached.
if (files[fileID].tus && files[fileID].tus.uploadUrl) {
var tusState = _extends({}, files[fileID].tus);
delete tusState.uploadUrl;
files[fileID] = _extends({}, files[fileID], {
tus: tusState
});
}
});
this.uppy.setState({
files: files
});
}
/**
* Clean up all references for a file's upload: the tus.Upload instance,
* any events related to the file, and the Companion WebSocket connection.
*
* @param {string} fileID
*/
;
_proto.resetUploaderReferences = function resetUploaderReferences(fileID, opts) {
if (opts === void 0) {
opts = {};
}
if (this.uploaders[fileID]) {
var uploader = this.uploaders[fileID];
uploader.abort();
if (opts.abort) {
// to avoid 423 error from tus server, we wait
// to be sure the previous request has been aborted before terminating the upload
// @todo remove the timeout when this "wait" is handled in tus-js-client internally
setTimeout(function () {
return uploader.abort(true);
}, 1000);
}
this.uploaders[fileID] = null;
}
if (this.uploaderEvents[fileID]) {
this.uploaderEvents[fileID].remove();
this.uploaderEvents[fileID] = null;
}
if (this.uploaderSockets[fileID]) {
this.uploaderSockets[fileID].close();
this.uploaderSockets[fileID] = null;
}
}
/**
* Create a new Tus upload.
*
* A lot can happen during an upload, so this is quite hard to follow!
* - First, the upload is started. If the file was already paused by the time the upload starts, nothing should happen.
* If the `limit` option is used, the upload must be queued onto the `this.requests` queue.
* When an upload starts, we store the tus.Upload instance, and an EventTracker instance that manages the event listeners
* for pausing, cancellation, removal, etc.
* - While the upload is in progress, it may be paused or cancelled.
* Pausing aborts the underlying tus.Upload, and removes the upload from the `this.requests` queue. All other state is
* maintained.
* Cancelling removes the upload from the `this.requests` queue, and completely aborts the upload--the tus.Upload instance
* is aborted and discarded, the EventTracker instance is destroyed (removing all listeners).
* Resuming the upload uses the `this.requests` queue as well, to prevent selectively pausing and resuming uploads from
* bypassing the limit.
* - After completing an upload, the tus.Upload and EventTracker instances are cleaned up, and the upload is marked as done
* in the `this.requests` queue.
* - When an upload completed with an error, the same happens as on successful completion, but the `upload()` promise is rejected.
*
* When working on this function, keep in mind:
* - When an upload is completed or cancelled for any reason, the tus.Upload and EventTracker instances need to be cleaned up using this.resetUploaderReferences().
* - When an upload is cancelled or paused, for any reason, it needs to be removed from the `this.requests` queue using `queuedRequest.abort()`.
* - When an upload is completed for any reason, including errors, it needs to be marked as such using `queuedRequest.done()`.
* - When an upload is started or resumed, it needs to go through the `this.requests` queue. The `queuedRequest` variable must be updated so the other uses of it are valid.
* - Before replacing the `queuedRequest` variable, the previous `queuedRequest` must be aborted, else it will keep taking up a spot in the queue.
*
* @param {UppyFile} file for use with upload
* @param {number} current file in a queue
* @param {number} total number of files in a queue
* @returns {Promise<void>}
*/
;
_proto.upload = function upload(file, current, total) {
var _this2 = this;
this.resetUploaderReferences(file.id); // Create a new tus upload
return new Promise(function (resolve, reject) {
_this2.uppy.emit('upload-started', file);
var opts = _extends({}, _this2.opts, file.tus || {});
/** @type {RawTusOptions} */
var uploadOptions = _extends({}, tusDefaultOptions, opts);
delete uploadOptions.resume; // Make `resume: true` work like it did in tus-js-client v1.
// TODO: Remove in @uppy/tus v2
if (opts.resume) {
uploadOptions.storeFingerprintForResuming = true;
} // We override tus fingerprint to uppy’s `file.id`, since the `file.id`
// now also includes `relativePath` for files added from folders.
// This means you can add 2 identical files, if one is in folder a,
// the other in folder b.
uploadOptions.fingerprint = getFingerprint(file);
uploadOptions.onBeforeRequest = function (req) {
var xhr = req.getUnderlyingObject();
xhr.withCredentials = !!opts.withCredentials;
if (typeof opts.onBeforeRequest === 'function') {
opts.onBeforeRequest(req);
}
};
uploadOptions.onError = function (err) {
_this2.uppy.log(err);
var xhr = err.originalRequest ? err.originalRequest.getUnderlyingObject() : null;
if (isNetworkError(xhr)) {
err = new NetworkError(err, xhr);
}
_this2.resetUploaderReferences(file.id);
queuedRequest.done();
_this2.uppy.emit('upload-error', file, err);
reject(err);
};
uploadOptions.onProgress = function (bytesUploaded, bytesTotal) {
_this2.onReceiveUploadUrl(file, upload.url);
_this2.uppy.emit('upload-progress', file, {
uploader: _this2,
bytesUploaded: bytesUploaded,
bytesTotal: bytesTotal
});
};
uploadOptions.onSuccess = function () {
var uploadResp = {
uploadURL: upload.url
};
_this2.resetUploaderReferences(file.id);
queuedRequest.done();
_this2.uppy.emit('upload-success', file, uploadResp);
if (upload.url) {
_this2.uppy.log("Download " + upload.file.name + " from " + upload.url);
}
resolve(upload);
};
var copyProp = function copyProp(obj, srcProp, destProp) {
if (hasProperty(obj, srcProp) && !hasProperty(obj, destProp)) {
obj[destProp] = obj[srcProp];
}
};
/** @type {Record<string, string>} */
var meta = {};
var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default.
: Object.keys(file.meta);
metaFields.forEach(function (item) {
meta[item] = file.meta[item];
}); // tusd uses metadata fields 'filetype' and 'filename'
copyProp(meta, 'type', 'filetype');
copyProp(meta, 'name', 'filename');
uploadOptions.metadata = meta;
var upload = new tus.Upload(file.data, uploadOptions);
_this2.uploaders[file.id] = upload;
_this2.uploaderEvents[file.id] = new EventTracker(_this2.uppy); // Make `resume: true` work like it did in tus-js-client v1.
// TODO: Remove in @uppy/tus v2.
if (opts.resume) {
upload.findPreviousUploads().then(function (previousUploads) {
var previousUpload = previousUploads[0];
if (previousUpload) {
_this2.uppy.log("[Tus] Resuming upload of " + file.id + " started at " + previousUpload.creationTime);
upload.resumeFromPreviousUpload(previousUpload);
}
});
}
var queuedRequest = _this2.requests.run(function () {
if (!file.isPaused) {
// Ensure this gets scheduled to run _after_ `findPreviousUploads()` returns.
// TODO: Remove in @uppy/tus v2.
Promise.resolve().then(function () {
upload.start();
});
} // Don't do anything here, the caller will take care of cancelling the upload itself
// using resetUploaderReferences(). This is because resetUploaderReferences() has to be
// called when this request is still in the queue, and has not been started yet, too. At
// that point this cancellation function is not going to be called.
// Also, we need to remove the request from the queue _without_ destroying everything
// related to this upload to handle pauses.
return function () {};
});
_this2.onFileRemove(file.id, function (targetFileID) {
queuedRequest.abort();
_this2.resetUploaderReferences(file.id, {
abort: !!upload.url
});
resolve("upload " + targetFileID + " was removed");
});
_this2.onPause(file.id, function (isPaused) {
if (isPaused) {
// Remove this file from the queue so another file can start in its place.
queuedRequest.abort();
upload.abort();
} else {
// Resuming an upload should be queued, else you could pause and then resume a queued upload to make it skip the queue.
queuedRequest.abort();
queuedRequest = _this2.requests.run(function () {
upload.start();
return function () {};
});
}
});
_this2.onPauseAll(file.id, function () {
queuedRequest.abort();
upload.abort();
});
_this2.onCancelAll(file.id, function () {
queuedRequest.abort();
_this2.resetUploaderReferences(file.id, {
abort: !!upload.url
});
resolve("upload " + file.id + " was canceled");
});
_this2.onResumeAll(file.id, function () {
queuedRequest.abort();
if (file.error) {
upload.abort();
}
queuedRequest = _this2.requests.run(function () {
upload.start();
return function () {};
});
});
}).catch(function (err) {
_this2.uppy.emit('upload-error', file, err);
throw err;
});
}
/**
* @param {UppyFile} file for use with upload
* @param {number} current file in a queue
* @param {number} total number of files in a queue
* @returns {Promise<void>}
*/
;
_proto.uploadRemote = function uploadRemote(file, current, total) {
var _this3 = this;
this.resetUploaderReferences(file.id);
var opts = _extends({}, this.opts);
if (file.tus) {
// Install file-specific upload overrides.
_extends(opts, file.tus);
}
this.uppy.emit('upload-started', file);
this.uppy.log(file.remote.url);
if (file.serverToken) {
return this.connectToServerSocket(file);
}
return new Promise(function (resolve, reject) {
var Client = file.remote.providerOptions.provider ? Provider : RequestClient;
var client = new Client(_this3.uppy, file.remote.providerOptions); // !! cancellation is NOT supported at this stage yet
client.post(file.remote.url, _extends({}, file.remote.body, {
endpoint: opts.endpoint,
uploadUrl: opts.uploadUrl,
protocol: 'tus',
size: file.data.size,
headers: opts.headers,
metadata: file.meta
})).then(function (res) {
_this3.uppy.setFileState(file.id, {
serverToken: res.token
});
file = _this3.uppy.getFile(file.id);
return _this3.connectToServerSocket(file);
}).then(function () {
resolve();
}).catch(function (err) {
_this3.uppy.emit('upload-error', file, err);
reject(err);
});
});
}
/**
* See the comment on the upload() method.
*
* Additionally, when an upload is removed, completed, or cancelled, we need to close the WebSocket connection. This is handled by the resetUploaderReferences() function, so the same guidelines apply as in upload().
*
* @param {UppyFile} file
*/
;
_proto.connectToServerSocket = function connectToServerSocket(file) {
var _this4 = this;
return new Promise(function (resolve, reject) {
var token = file.serverToken;
var host = getSocketHost(file.remote.companionUrl);
var socket = new Socket({
target: host + "/api/" + token,
autoOpen: false
});
_this4.uploaderSockets[file.id] = socket;
_this4.uploaderEvents[file.id] = new EventTracker(_this4.uppy);
_this4.onFileRemove(file.id, function () {
queuedRequest.abort(); // still send pause event in case we are dealing with older version of companion
// @todo don't send pause event in the next major release.
socket.send('pause', {});
socket.send('cancel', {});
_this4.resetUploaderReferences(file.id);
resolve("upload " + file.id + " was removed");
});
_this4.onPause(file.id, function (isPaused) {
if (isPaused) {
// Remove this file from the queue so another file can start in its place.
queuedRequest.abort();
socket.send('pause', {});
} else {
// Resuming an upload should be queued, else you could pause and then resume a queued upload to make it skip the queue.
queuedRequest.abort();
queuedRequest = _this4.requests.run(function () {
socket.send('resume', {});
return function () {};
});
}
});
_this4.onPauseAll(file.id, function () {
queuedRequest.abort();
socket.send('pause', {});
});
_this4.onCancelAll(file.id, function () {
queuedRequest.abort(); // still send pause event in case we are dealing with older version of companion
// @todo don't send pause event in the next major release.
socket.send('pause', {});
socket.send('cancel', {});
_this4.resetUploaderReferences(file.id);
resolve("upload " + file.id + " was canceled");
});
_this4.onResumeAll(file.id, function () {
queuedRequest.abort();
if (file.error) {
socket.send('pause', {});
}
queuedRequest = _this4.requests.run(function () {
socket.send('resume', {});
return function () {};
});
});
_this4.onRetry(file.id, function () {
// Only do the retry if the upload is actually in progress;
// else we could try to send these messages when the upload is still queued.
// We may need a better check for this since the socket may also be closed
// for other reasons, like network failures.
if (socket.isOpen) {
socket.send('pause', {});
socket.send('resume', {});
}
});
_this4.onRetryAll(file.id, function () {
// See the comment in the onRetry() call
if (socket.isOpen) {
socket.send('pause', {});
socket.send('resume', {});
}
});
socket.on('progress', function (progressData) {
return emitSocketProgress(_this4, progressData, file);
});
socket.on('error', function (errData) {
var message = errData.error.message;
var error = _extends(new Error(message), {
cause: errData.error
}); // If the remote retry optimisation should not be used,
// close the socket—this will tell companion to clear state and delete the file.
if (!_this4.opts.useFastRemoteRetry) {
_this4.resetUploaderReferences(file.id); // Remove the serverToken so that a new one will be created for the retry.
_this4.uppy.setFileState(file.id, {
serverToken: null
});
} else {
socket.close();
}
_this4.uppy.emit('upload-error', file, error);
queuedRequest.done();
reject(error);
});
socket.on('success', function (data) {
var uploadResp = {
uploadURL: data.url
};
_this4.uppy.emit('upload-success', file, uploadResp);
_this4.resetUploaderReferences(file.id);
queuedRequest.done();
resolve();
});
var queuedRequest = _this4.requests.run(function () {
socket.open();
if (file.isPaused) {
socket.send('pause', {});
} // Don't do anything here, the caller will take care of cancelling the upload itself
// using resetUploaderReferences(). This is because resetUploaderReferences() has to be
// called when this request is still in the queue, and has not been started yet, too. At
// that point this cancellation function is not going to be called.
// Also, we need to remove the request from the queue _without_ destroying everything
// related to this upload to handle pauses.
return function () {};
});
});
}
/**
* Store the uploadUrl on the file options, so that when Golden Retriever
* restores state, we will continue uploading to the correct URL.
*
* @param {UppyFile} file
* @param {string} uploadURL
*/
;
_proto.onReceiveUploadUrl = function onReceiveUploadUrl(file, uploadURL) {
var currentFile = this.uppy.getFile(file.id);
if (!currentFile) return; // Only do the update if we didn't have an upload URL yet.
if (!currentFile.tus || currentFile.tus.uploadUrl !== uploadURL) {
this.uppy.log('[Tus] Storing upload url');
this.uppy.setFileState(currentFile.id, {
tus: _extends({}, currentFile.tus, {
uploadUrl: uploadURL
})
});
}
}
/**
* @param {string} fileID
* @param {function(string): void} cb
*/
;
_proto.onFileRemove = function onFileRemove(fileID, cb) {
this.uploaderEvents[fileID].on('file-removed', function (file) {
if (fileID === file.id) cb(file.id);
});
}
/**
* @param {string} fileID
* @param {function(boolean): void} cb
*/
;
_proto.onPause = function onPause(fileID, cb) {
this.uploaderEvents[fileID].on('upload-pause', function (targetFileID, isPaused) {
if (fileID === targetFileID) {
// const isPaused = this.uppy.pauseResume(fileID)
cb(isPaused);
}
});
}
/**
* @param {string} fileID
* @param {function(): void} cb
*/
;
_proto.onRetry = function onRetry(fileID, cb) {
this.uploaderEvents[fileID].on('upload-retry', function (targetFileID) {
if (fileID === targetFileID) {
cb();
}
});
}
/**
* @param {string} fileID
* @param {function(): void} cb
*/
;
_proto.onRetryAll = function onRetryAll(fileID, cb) {
var _this5 = this;
this.uploaderEvents[fileID].on('retry-all', function (filesToRetry) {
if (!_this5.uppy.getFile(fileID)) return;
cb();
});
}
/**
* @param {string} fileID
* @param {function(): void} cb
*/
;
_proto.onPauseAll = function onPauseAll(fileID, cb) {
var _this6 = this;
this.uploaderEvents[fileID].on('pause-all', function () {
if (!_this6.uppy.getFile(fileID)) return;
cb();
});
}
/**
* @param {string} fileID
* @param {function(): void} cb
*/
;
_proto.onCancelAll = function onCancelAll(fileID, cb) {
var _this7 = this;
this.uploaderEvents[fileID].on('cancel-all', function () {
if (!_this7.uppy.getFile(fileID)) return;
cb();
});
}
/**
* @param {string} fileID
* @param {function(): void} cb
*/
;
_proto.onResumeAll = function onResumeAll(fileID, cb) {
var _this8 = this;
this.uploaderEvents[fileID].on('resume-all', function () {
if (!_this8.uppy.getFile(fileID)) return;
cb();
});
}
/**
* @param {(UppyFile | FailedUppyFile)[]} files
*/
;
_proto.uploadFiles = function uploadFiles(files) {
var _this9 = this;
var promises = files.map(function (file, i) {
var current = i + 1;
var total = files.length;
if ('error' in file && file.error) {
return Promise.reject(new Error(file.error));
}
if (file.isRemote) {
// We emit upload-started here, so that it's also emitted for files
// that have to wait due to the `limit` option.
// Don't double-emit upload-started for Golden Retriever-restored files that were already started
if (!file.progress.uploadStarted || !file.isRestored) {
_this9.uppy.emit('upload-started', file);
}
return _this9.uploadRemote(file, current, total);
} // Don't double-emit upload-started for Golden Retriever-restored files that were already started
if (!file.progress.uploadStarted || !file.isRestored) {
_this9.uppy.emit('upload-started', file);
}
return _this9.upload(file, current, total);
});
return settle(promises);
}
/**
* @param {string[]} fileIDs
*/
;
_proto.handleUpload = function handleUpload(fileIDs) {
var _this10 = this;
if (fileIDs.length === 0) {
this.uppy.log('[Tus] No files to upload');
return Promise.resolve();
}
if (this.opts.limit === 0) {
this.uppy.log('[Tus] When uploading multiple files at once, consider setting the `limit` option (to `10` for example), to limit the number of concurrent uploads, which helps prevent memory and network issues: https://uppy.io/docs/tus/#limit-0', 'warning');
}
this.uppy.log('[Tus] Uploading...');
var filesToUpload = fileIDs.map(function (fileID) {
return _this10.uppy.getFile(fileID);
});
return this.uploadFiles(filesToUpload).then(function () {
return null;
});
};
_proto.install = function install() {
this.uppy.setState({
capabilities: _extends({}, this.uppy.getState().capabilities, {
resumableUploads: true
})
});
this.uppy.addUploader(this.handleUpload);
this.uppy.on('reset-progress', this.handleResetProgress);
if (this.opts.autoRetry) {
this.uppy.on('back-online', this.uppy.retryAll);
}
};
_proto.uninstall = function uninstall() {
this.uppy.setState({
capabilities: _extends({}, this.uppy.getState().capabilities, {
resumableUploads: false
})
});
this.uppy.removeUploader(this.handleUpload);
if (this.opts.autoRetry) {
this.uppy.off('back-online', this.uppy.retryAll);
}
};
return Tus;
}(Plugin), _class.VERSION = "1.9.2", _temp);
},{"./getFingerprint":204,"@uppy/companion-client":75,"@uppy/core":78,"@uppy/utils/lib/EventTracker":213,"@uppy/utils/lib/NetworkError":215,"@uppy/utils/lib/RateLimitedQueue":217,"@uppy/utils/lib/emitSocketProgress":222,"@uppy/utils/lib/getSocketHost":237,"@uppy/utils/lib/hasProperty":241,"@uppy/utils/lib/isNetworkError":244,"@uppy/utils/lib/settle":251,"tus-js-client":48}],206:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var _require2 = require('preact'),
h = _require2.h;
var _require3 = require('@uppy/companion-client'),
SearchProvider = _require3.SearchProvider;
var _require4 = require('@uppy/provider-views'),
SearchProviderViews = _require4.SearchProviderViews;
/**
* Unsplash
*
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Unsplash, _Plugin);
function Unsplash(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'Unsplash';
_this.title = _this.opts.title || 'Unsplash';
_this.type = 'acquirer';
_this.icon = function () {
return h("svg", {
viewBox: "0 0 32 32",
height: "32",
width: "32",
"aria-hidden": "true"
}, h("path", {
d: "M46.575 10.883v-9h12v9zm12 5h10v18h-32v-18h10v9h12z",
fill: "#fff"
}), h("rect", {
className: "uppy-ProviderIconBg",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M13 12.5V8h6v4.5zm6 2.5h5v9H8v-9h5v4.5h6z",
fill: "#fff"
}));
};
var defaultOptions = {};
_this.opts = _extends({}, defaultOptions, opts);
_this.hostname = _this.opts.companionUrl;
if (!_this.hostname) {
throw new Error('Companion hostname is required, please consult https://uppy.io/docs/companion');
}
_this.provider = new SearchProvider(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders,
companionCookiesRule: _this.opts.companionCookiesRule,
provider: 'unsplash',
pluginId: _this.id
});
return _this;
}
var _proto = Unsplash.prototype;
_proto.install = function install() {
this.view = new SearchProviderViews(this, {
provider: this.provider
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.onFirstRender = function onFirstRender() {// do nothing
};
_proto.render = function render(state) {
return this.view.render(state);
};
_proto.uninstall = function uninstall() {
this.unmount();
};
return Unsplash;
}(Plugin), _class.VERSION = "0.1.13", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/provider-views":155,"preact":207}],207:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],208:[function(require,module,exports){
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var UrlUI = /*#__PURE__*/function (_Component) {
_inheritsLoose(UrlUI, _Component);
function UrlUI(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.handleKeyPress = _this.handleKeyPress.bind(_assertThisInitialized(_this));
_this.handleClick = _this.handleClick.bind(_assertThisInitialized(_this));
return _this;
}
var _proto = UrlUI.prototype;
_proto.componentDidMount = function componentDidMount() {
this.input.value = '';
};
_proto.handleKeyPress = function handleKeyPress(ev) {
if (ev.keyCode === 13) {
this.props.addFile(this.input.value);
}
};
_proto.handleClick = function handleClick() {
this.props.addFile(this.input.value);
};
_proto.render = function render() {
var _this2 = this;
return h("div", {
className: "uppy-Url"
}, h("input", {
className: "uppy-u-reset uppy-c-textInput uppy-Url-input",
type: "text",
"aria-label": this.props.i18n('enterUrlToImport'),
placeholder: this.props.i18n('enterUrlToImport'),
onKeyUp: this.handleKeyPress,
ref: function ref(input) {
_this2.input = input;
},
"data-uppy-super-focusable": true
}), h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Url-importButton",
type: "button",
onClick: this.handleClick
}, this.props.i18n('import')));
};
return UrlUI;
}(Component);
module.exports = UrlUI;
},{"preact":211}],209:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var _require2 = require('preact'),
h = _require2.h;
var _require3 = require('@uppy/companion-client'),
RequestClient = _require3.RequestClient;
var UrlUI = require('./UrlUI.js');
var forEachDroppedOrPastedUrl = require('./utils/forEachDroppedOrPastedUrl');
function UrlIcon() {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#FF753E",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M22.788 15.389l-2.199 2.19a3.184 3.184 0 0 1-.513.437c-.806.584-1.686.876-2.638.876a4.378 4.378 0 0 1-3.519-1.752c-.22-.292-.146-.802.147-1.021.293-.22.806-.146 1.026.146.953 1.313 2.785 1.532 4.105.583a.571.571 0 0 0 .293-.292l2.199-2.189c1.1-1.167 1.1-2.992-.073-4.086a2.976 2.976 0 0 0-4.105 0l-1.246 1.24a.71.71 0 0 1-1.026 0 .703.703 0 0 1 0-1.022l1.246-1.24a4.305 4.305 0 0 1 6.083 0c1.833 1.605 1.906 4.451.22 6.13zm-7.183 5.035l-1.246 1.24a2.976 2.976 0 0 1-4.105 0c-1.172-1.094-1.172-2.991-.073-4.086l2.2-2.19.292-.291c.66-.438 1.393-.657 2.2-.584.805.146 1.465.51 1.905 1.168.22.292.733.365 1.026.146.293-.22.367-.73.147-1.022-.733-.949-1.76-1.532-2.859-1.678-1.1-.22-2.272.073-3.225.802l-.44.438-2.199 2.19c-1.686 1.75-1.612 4.524.074 6.202.88.803 1.979 1.241 3.078 1.241 1.1 0 2.199-.438 3.079-1.24l1.246-1.241a.703.703 0 0 0 0-1.022c-.294-.292-.807-.365-1.1-.073z",
fill: "#FFF",
fillRule: "nonzero"
})));
}
/**
* Url
*
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Url, _Plugin);
function Url(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.id = _this.opts.id || 'Url';
_this.title = _this.opts.title || 'Link';
_this.type = 'acquirer';
_this.icon = function () {
return h(UrlIcon, null);
}; // Set default options and locale
_this.defaultLocale = {
strings: {
import: 'Import',
enterUrlToImport: 'Enter URL to import a file',
failedToFetch: 'Companion failed to fetch this URL, please make sure it’s correct',
enterCorrectUrl: 'Incorrect URL: Please make sure you are entering a direct link to a file'
}
};
var defaultOptions = {};
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this.hostname = _this.opts.companionUrl;
if (!_this.hostname) {
throw new Error('Companion hostname is required, please consult https://uppy.io/docs/companion');
} // Bind all event handlers for referencability
_this.getMeta = _this.getMeta.bind(_assertThisInitialized(_this));
_this.addFile = _this.addFile.bind(_assertThisInitialized(_this));
_this.handleRootDrop = _this.handleRootDrop.bind(_assertThisInitialized(_this));
_this.handleRootPaste = _this.handleRootPaste.bind(_assertThisInitialized(_this));
_this.client = new RequestClient(uppy, {
companionUrl: _this.opts.companionUrl,
companionHeaders: _this.opts.companionHeaders || _this.opts.serverHeaders,
companionCookiesRule: _this.opts.companionCookiesRule
});
return _this;
}
var _proto = Url.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.getFileNameFromUrl = function getFileNameFromUrl(url) {
return url.substring(url.lastIndexOf('/') + 1);
};
_proto.checkIfCorrectURL = function checkIfCorrectURL(url) {
if (!url) return false;
var protocol = url.match(/^([a-z0-9]+):\/\//)[1];
if (protocol !== 'http' && protocol !== 'https') {
return false;
}
return true;
};
_proto.addProtocolToURL = function addProtocolToURL(url) {
var protocolRegex = /^[a-z0-9]+:\/\//;
var defaultProtocol = 'http://';
if (protocolRegex.test(url)) {
return url;
}
return defaultProtocol + url;
};
_proto.getMeta = function getMeta(url) {
var _this2 = this;
return this.client.post('url/meta', {
url: url
}).then(function (res) {
if (res.error) {
_this2.uppy.log('[URL] Error:');
_this2.uppy.log(res.error);
throw new Error('Failed to fetch the file');
}
return res;
});
};
_proto.addFile = function addFile(url) {
var _this3 = this;
url = this.addProtocolToURL(url);
if (!this.checkIfCorrectURL(url)) {
this.uppy.log("[URL] Incorrect URL entered: " + url);
this.uppy.info(this.i18n('enterCorrectUrl'), 'error', 4000);
return;
}
return this.getMeta(url).then(function (meta) {
var tagFile = {
source: _this3.id,
name: _this3.getFileNameFromUrl(url),
type: meta.type,
data: {
size: meta.size
},
isRemote: true,
body: {
url: url
},
remote: {
companionUrl: _this3.opts.companionUrl,
url: _this3.hostname + "/url/get",
body: {
fileId: url,
url: url
},
providerOptions: _this3.client.opts
}
};
return tagFile;
}).then(function (tagFile) {
_this3.uppy.log('[Url] Adding remote file');
try {
return _this3.uppy.addFile(tagFile);
} catch (err) {
if (!err.isRestriction) {
_this3.uppy.log(err);
}
return err;
}
}).catch(function (err) {
_this3.uppy.log(err);
_this3.uppy.info({
message: _this3.i18n('failedToFetch'),
details: err
}, 'error', 4000);
return err;
});
};
_proto.handleRootDrop = function handleRootDrop(e) {
var _this4 = this;
forEachDroppedOrPastedUrl(e.dataTransfer, 'drop', function (url) {
_this4.uppy.log("[URL] Adding file from dropped url: " + url);
_this4.addFile(url);
});
};
_proto.handleRootPaste = function handleRootPaste(e) {
var _this5 = this;
forEachDroppedOrPastedUrl(e.clipboardData, 'paste', function (url) {
_this5.uppy.log("[URL] Adding file from pasted url: " + url);
_this5.addFile(url);
});
};
_proto.render = function render(state) {
return h(UrlUI, {
i18n: this.i18n,
addFile: this.addFile
});
};
_proto.install = function install() {
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
};
_proto.uninstall = function uninstall() {
this.unmount();
};
return Url;
}(Plugin), _class.VERSION = "1.5.23", _temp);
},{"./UrlUI.js":208,"./utils/forEachDroppedOrPastedUrl":210,"@uppy/companion-client":75,"@uppy/core":78,"@uppy/utils/lib/Translator":218,"preact":211}],210:[function(require,module,exports){
var toArray = require('@uppy/utils/lib/toArray');
/*
SITUATION
1. Cross-browser dataTransfer.items
paste in chrome [Copy Image]:
0: {kind: "file", type: "image/png"}
1: {kind: "string", type: "text/html"}
paste in safari [Copy Image]:
0: {kind: "file", type: "image/png"}
1: {kind: "string", type: "text/html"}
2: {kind: "string", type: "text/plain"}
3: {kind: "string", type: "text/uri-list"}
paste in firefox [Copy Image]:
0: {kind: "file", type: "image/png"}
1: {kind: "string", type: "text/html"}
paste in chrome [Copy Image Address]:
0: {kind: "string", type: "text/plain"}
paste in safari [Copy Image Address]:
0: {kind: "string", type: "text/plain"}
1: {kind: "string", type: "text/uri-list"}
paste in firefox [Copy Image Address]:
0: {kind: "string", type: "text/plain"}
drop in chrome [from browser]:
0: {kind: "string", type: "text/uri-list"}
1: {kind: "string", type: "text/html"}
drop in safari [from browser]:
0: {kind: "string", type: "text/uri-list"}
1: {kind: "string", type: "text/html"}
2: {kind: "file", type: "image/png"}
drop in firefox [from browser]:
0: {kind: "string", type: "text/uri-list"}
1: {kind: "string", type: "text/x-moz-url"}
2: {kind: "string", type: "text/plain"}
2. We can determine if it's a 'copypaste' or a 'drop', but we can't discern between [Copy Image] and [Copy Image Address].
CONCLUSION
1. 'paste' ([Copy Image] or [Copy Image Address], we can't discern between these two)
Don't do anything if there is 'file' item. .handlePaste in the DashboardPlugin will deal with all 'file' items.
If there are no 'file' items - handle 'text/plain' items.
2. 'drop'
Take 'text/uri-list' items. Safari has an additional item of .kind === 'file', and you may worry about the item being duplicated (first by DashboardPlugin, and then by UrlPlugin, now), but don't. Directory handling code won't pay attention to this particular item of kind 'file'.
*/
/**
* Finds all links dropped/pasted from one browser window to another.
*
* @param {object} dataTransfer - DataTransfer instance, e.g. e.clipboardData, or e.dataTransfer
* @param {string} isDropOrPaste - either 'drop' or 'paste'
* @param {Function} callback - (urlString) => {}
*/
module.exports = function forEachDroppedOrPastedUrl(dataTransfer, isDropOrPaste, callback) {
var items = toArray(dataTransfer.items);
var urlItems;
switch (isDropOrPaste) {
case 'paste':
{
var atLeastOneFileIsDragged = items.some(function (item) {
return item.kind === 'file';
});
if (atLeastOneFileIsDragged) {
return;
}
urlItems = items.filter(function (item) {
return item.kind === 'string' && item.type === 'text/plain';
});
break;
}
case 'drop':
{
urlItems = items.filter(function (item) {
return item.kind === 'string' && item.type === 'text/uri-list';
});
break;
}
default:
{
throw new Error("isDropOrPaste must be either 'drop' or 'paste', but it's " + isDropOrPaste);
}
}
urlItems.forEach(function (item) {
item.getAsString(function (urlString) {
return callback(urlString);
});
});
};
},{"@uppy/utils/lib/toArray":252}],211:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],212:[function(require,module,exports){
/**
* Little AbortController proxy module so we can swap out the implementation easily later.
*/
var _require = require('abortcontroller-polyfill/dist/abortcontroller'),
AbortController = _require.AbortController,
AbortSignal = _require.AbortSignal;
function createAbortError(message) {
if (message === void 0) {
message = 'Aborted';
}
try {
return new DOMException(message, 'AbortError');
} catch (_unused) {
// For Internet Explorer
var error = new Error(message);
error.name = 'AbortError';
return error;
}
}
exports.AbortController = AbortController;
exports.AbortSignal = AbortSignal;
exports.createAbortError = createAbortError;
},{"abortcontroller-polyfill/dist/abortcontroller":2}],213:[function(require,module,exports){
/**
* Create a wrapper around an event emitter with a `remove` method to remove
* all events that were added using the wrapped emitter.
*/
module.exports = /*#__PURE__*/function () {
function EventTracker(emitter) {
this._events = [];
this._emitter = emitter;
}
var _proto = EventTracker.prototype;
_proto.on = function on(event, fn) {
this._events.push([event, fn]);
return this._emitter.on(event, fn);
};
_proto.remove = function remove() {
var _this = this;
this._events.forEach(function (_ref) {
var event = _ref[0],
fn = _ref[1];
_this._emitter.off(event, fn);
});
};
return EventTracker;
}();
},{}],214:[function(require,module,exports){
module.exports = ['a[href]:not([tabindex^="-"]):not([inert]):not([aria-hidden])', 'area[href]:not([tabindex^="-"]):not([inert]):not([aria-hidden])', 'input:not([disabled]):not([inert]):not([aria-hidden])', 'select:not([disabled]):not([inert]):not([aria-hidden])', 'textarea:not([disabled]):not([inert]):not([aria-hidden])', 'button:not([disabled]):not([inert]):not([aria-hidden])', 'iframe:not([tabindex^="-"]):not([inert]):not([aria-hidden])', 'object:not([tabindex^="-"]):not([inert]):not([aria-hidden])', 'embed:not([tabindex^="-"]):not([inert]):not([aria-hidden])', '[contenteditable]:not([tabindex^="-"]):not([inert]):not([aria-hidden])', '[tabindex]:not([tabindex^="-"]):not([inert]):not([aria-hidden])'];
},{}],215:[function(require,module,exports){
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var NetworkError = /*#__PURE__*/function (_Error) {
_inheritsLoose(NetworkError, _Error);
function NetworkError(error, xhr) {
var _this;
if (xhr === void 0) {
xhr = null;
}
_this = _Error.call(this, "This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.\n\nSource error: [" + error + "]") || this;
_this.isNetworkError = true;
_this.request = xhr;
return _this;
}
return NetworkError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
module.exports = NetworkError;
},{}],216:[function(require,module,exports){
/**
* Helper to abort upload requests if there has not been any progress for `timeout` ms.
* Create an instance using `timer = new ProgressTimeout(10000, onTimeout)`
* Call `timer.progress()` to signal that there has been progress of any kind.
* Call `timer.done()` when the upload has completed.
*/
var ProgressTimeout = /*#__PURE__*/function () {
function ProgressTimeout(timeout, timeoutHandler) {
this._timeout = timeout;
this._onTimedOut = timeoutHandler;
this._isDone = false;
this._aliveTimer = null;
this._onTimedOut = this._onTimedOut.bind(this);
}
var _proto = ProgressTimeout.prototype;
_proto.progress = function progress() {
// Some browsers fire another progress event when the upload is
// cancelled, so we have to ignore progress after the timer was
// told to stop.
if (this._isDone) return;
if (this._timeout > 0) {
if (this._aliveTimer) clearTimeout(this._aliveTimer);
this._aliveTimer = setTimeout(this._onTimedOut, this._timeout);
}
};
_proto.done = function done() {
if (this._aliveTimer) {
clearTimeout(this._aliveTimer);
this._aliveTimer = null;
}
this._isDone = true;
};
return ProgressTimeout;
}();
module.exports = ProgressTimeout;
},{}],217:[function(require,module,exports){
var findIndex = require('./findIndex');
function createCancelError() {
return new Error('Cancelled');
}
module.exports = /*#__PURE__*/function () {
function RateLimitedQueue(limit) {
if (typeof limit !== 'number' || limit === 0) {
this.limit = Infinity;
} else {
this.limit = limit;
}
this.activeRequests = 0;
this.queuedHandlers = [];
}
var _proto = RateLimitedQueue.prototype;
_proto._call = function _call(fn) {
var _this = this;
this.activeRequests += 1;
var _done = false;
var cancelActive;
try {
cancelActive = fn();
} catch (err) {
this.activeRequests -= 1;
throw err;
}
return {
abort: function abort() {
if (_done) return;
_done = true;
_this.activeRequests -= 1;
cancelActive();
_this._queueNext();
},
done: function done() {
if (_done) return;
_done = true;
_this.activeRequests -= 1;
_this._queueNext();
}
};
};
_proto._queueNext = function _queueNext() {
var _this2 = this;
// Do it soon but not immediately, this allows clearing out the entire queue synchronously
// one by one without continuously _advancing_ it (and starting new tasks before immediately
// aborting them)
Promise.resolve().then(function () {
_this2._next();
});
};
_proto._next = function _next() {
if (this.activeRequests >= this.limit) {
return;
}
if (this.queuedHandlers.length === 0) {
return;
} // Dispatch the next request, and update the abort/done handlers
// so that cancelling it does the Right Thing (and doesn't just try
// to dequeue an already-running request).
var next = this.queuedHandlers.shift();
var handler = this._call(next.fn);
next.abort = handler.abort;
next.done = handler.done;
};
_proto._queue = function _queue(fn, options) {
var _this3 = this;
if (options === void 0) {
options = {};
}
var handler = {
fn: fn,
priority: options.priority || 0,
abort: function abort() {
_this3._dequeue(handler);
},
done: function done() {
throw new Error('Cannot mark a queued request as done: this indicates a bug');
}
};
var index = findIndex(this.queuedHandlers, function (other) {
return handler.priority > other.priority;
});
if (index === -1) {
this.queuedHandlers.push(handler);
} else {
this.queuedHandlers.splice(index, 0, handler);
}
return handler;
};
_proto._dequeue = function _dequeue(handler) {
var index = this.queuedHandlers.indexOf(handler);
if (index !== -1) {
this.queuedHandlers.splice(index, 1);
}
};
_proto.run = function run(fn, queueOptions) {
if (this.activeRequests < this.limit) {
return this._call(fn);
}
return this._queue(fn, queueOptions);
};
_proto.wrapPromiseFunction = function wrapPromiseFunction(fn, queueOptions) {
var _this4 = this;
return function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var queuedRequest;
var outerPromise = new Promise(function (resolve, reject) {
queuedRequest = _this4.run(function () {
var cancelError;
var innerPromise;
try {
innerPromise = Promise.resolve(fn.apply(void 0, args));
} catch (err) {
innerPromise = Promise.reject(err);
}
innerPromise.then(function (result) {
if (cancelError) {
reject(cancelError);
} else {
queuedRequest.done();
resolve(result);
}
}, function (err) {
if (cancelError) {
reject(cancelError);
} else {
queuedRequest.done();
reject(err);
}
});
return function () {
cancelError = createCancelError();
};
}, queueOptions);
});
outerPromise.abort = function () {
queuedRequest.abort();
};
return outerPromise;
};
};
return RateLimitedQueue;
}();
},{"./findIndex":226}],218:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var has = require('./hasProperty');
/**
* Translates strings with interpolation & pluralization support.
* Extensible with custom dictionaries and pluralization functions.
*
* Borrows heavily from and inspired by Polyglot https://github.com/airbnb/polyglot.js,
* basically a stripped-down version of it. Differences: pluralization functions are not hardcoded
* and can be easily added among with dictionaries, nested objects are used for pluralization
* as opposed to `||||` delimeter
*
* Usage example: `translator.translate('files_chosen', {smart_count: 3})`
*/
module.exports = /*#__PURE__*/function () {
/**
* @param {object|Array<object>} locales - locale or list of locales.
*/
function Translator(locales) {
var _this = this;
this.locale = {
strings: {},
pluralize: function pluralize(n) {
if (n === 1) {
return 0;
}
return 1;
}
};
if (Array.isArray(locales)) {
locales.forEach(function (locale) {
return _this._apply(locale);
});
} else {
this._apply(locales);
}
}
var _proto = Translator.prototype;
_proto._apply = function _apply(locale) {
if (!locale || !locale.strings) {
return;
}
var prevLocale = this.locale;
this.locale = _extends({}, prevLocale, {
strings: _extends({}, prevLocale.strings, locale.strings)
});
this.locale.pluralize = locale.pluralize || prevLocale.pluralize;
}
/**
* Takes a string with placeholder variables like `%{smart_count} file selected`
* and replaces it with values from options `{smart_count: 5}`
*
* @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
* taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
*
* @param {string} phrase that needs interpolation, with placeholders
* @param {object} options with values that will be used to replace placeholders
* @returns {any[]} interpolated
*/
;
_proto.interpolate = function interpolate(phrase, options) {
var _String$prototype = String.prototype,
split = _String$prototype.split,
replace = _String$prototype.replace;
var dollarRegex = /\$/g;
var dollarBillsYall = '$$$$';
var interpolated = [phrase];
for (var arg in options) {
if (arg !== '_' && has(options, arg)) {
// Ensure replacement value is escaped to prevent special $-prefixed
// regex replace tokens. the "$$$$" is needed because each "$" needs to
// be escaped with "$" itself, and we need two in the resulting output.
var replacement = options[arg];
if (typeof replacement === 'string') {
replacement = replace.call(options[arg], dollarRegex, dollarBillsYall);
} // We create a new `RegExp` each time instead of using a more-efficient
// string replace so that the same argument can be replaced multiple times
// in the same phrase.
interpolated = insertReplacement(interpolated, new RegExp("%\\{" + arg + "\\}", 'g'), replacement);
}
}
return interpolated;
function insertReplacement(source, rx, replacement) {
var newParts = [];
source.forEach(function (chunk) {
// When the source contains multiple placeholders for interpolation,
// we should ignore chunks that are not strings, because those
// can be JSX objects and will be otherwise incorrectly turned into strings.
// Without this condition we’d get this: [object Object] hello [object Object] my <button>
if (typeof chunk !== 'string') {
return newParts.push(chunk);
}
split.call(chunk, rx).forEach(function (raw, i, list) {
if (raw !== '') {
newParts.push(raw);
} // Interlace with the `replacement` value
if (i < list.length - 1) {
newParts.push(replacement);
}
});
});
return newParts;
}
}
/**
* Public translate method
*
* @param {string} key
* @param {object} options with values that will be used later to replace placeholders in string
* @returns {string} translated (and interpolated)
*/
;
_proto.translate = function translate(key, options) {
return this.translateArray(key, options).join('');
}
/**
* Get a translation and return the translated and interpolated parts as an array.
*
* @param {string} key
* @param {object} options with values that will be used to replace placeholders
* @returns {Array} The translated and interpolated parts, in order.
*/
;
_proto.translateArray = function translateArray(key, options) {
if (!has(this.locale.strings, key)) {
throw new Error("missing string: " + key);
}
var string = this.locale.strings[key];
var hasPluralForms = typeof string === 'object';
if (hasPluralForms) {
if (options && typeof options.smart_count !== 'undefined') {
var plural = this.locale.pluralize(options.smart_count);
return this.interpolate(string[plural], options);
}
throw new Error('Attempted to use a string with plural forms, but no value was given for %{smart_count}');
}
return this.interpolate(string, options);
};
return Translator;
}();
},{"./hasProperty":241}],219:[function(require,module,exports){
var dataURItoBlob = require('./dataURItoBlob');
/**
* Save a <canvas> element's content to a Blob object.
*
* @param {HTMLCanvasElement} canvas
* @returns {Promise}
*/
module.exports = function canvasToBlob(canvas, type, quality) {
if (canvas.toBlob) {
return new Promise(function (resolve) {
canvas.toBlob(resolve, type, quality);
});
}
return Promise.resolve().then(function () {
return dataURItoBlob(canvas.toDataURL(type, quality), {});
});
};
},{"./dataURItoBlob":220}],220:[function(require,module,exports){
module.exports = function dataURItoBlob(dataURI, opts, toFile) {
// get the base64 data
var data = dataURI.split(',')[1]; // user may provide mime type, if not get it from data URI
var mimeType = opts.mimeType || dataURI.split(',')[0].split(':')[1].split(';')[0]; // default to plain/text if data URI has no mimeType
if (mimeType == null) {
mimeType = 'plain/text';
}
var binary = atob(data);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
var bytes;
try {
bytes = new Uint8Array(array); // eslint-disable-line compat/compat
} catch (err) {
return null;
} // Convert to a File?
if (toFile) {
return new File([bytes], opts.name || '', {
type: mimeType
});
}
return new Blob([bytes], {
type: mimeType
});
};
},{}],221:[function(require,module,exports){
var _require = require('./AbortController'),
createAbortError = _require.createAbortError;
/**
* Return a Promise that resolves after `ms` milliseconds.
*
* @param {number} ms - Number of milliseconds to wait.
* @param {{ signal?: AbortSignal }} [opts] - An abort signal that can be used to cancel the delay early.
* @returns {Promise<void>} A Promise that resolves after the given amount of `ms`.
*/
module.exports = function delay(ms, opts) {
return new Promise(function (resolve, reject) {
if (opts && opts.signal && opts.signal.aborted) {
return reject(createAbortError());
}
function onabort() {
clearTimeout(timeout);
cleanup();
reject(createAbortError());
}
var timeout = setTimeout(function () {
cleanup();
resolve();
}, ms);
if (opts && opts.signal) {
opts.signal.addEventListener('abort', onabort);
}
function cleanup() {
if (opts && opts.signal) {
opts.signal.removeEventListener('abort', onabort);
}
}
});
};
},{"./AbortController":212}],222:[function(require,module,exports){
var throttle = require('lodash.throttle');
function _emitSocketProgress(uploader, progressData, file) {
var progress = progressData.progress,
bytesUploaded = progressData.bytesUploaded,
bytesTotal = progressData.bytesTotal;
if (progress) {
uploader.uppy.log("Upload progress: " + progress);
uploader.uppy.emit('upload-progress', file, {
uploader: uploader,
bytesUploaded: bytesUploaded,
bytesTotal: bytesTotal
});
}
}
module.exports = throttle(_emitSocketProgress, 300, {
leading: true,
trailing: true
});
},{"lodash.throttle":34}],223:[function(require,module,exports){
var NetworkError = require('./NetworkError');
/**
* Wrapper around window.fetch that throws a NetworkError when appropriate
*/
module.exports = function fetchWithNetworkError() {
return fetch.apply(void 0, arguments).catch(function (err) {
if (err.name === 'AbortError') {
throw err;
} else {
throw new NetworkError(err);
}
});
};
},{"./NetworkError":215}],224:[function(require,module,exports){
var isDOMElement = require('./isDOMElement');
/**
* Find one or more DOM elements.
*
* @param {string} element
* @returns {Array|null}
*/
module.exports = function findAllDOMElements(element) {
if (typeof element === 'string') {
var elements = [].slice.call(document.querySelectorAll(element));
return elements.length > 0 ? elements : null;
}
if (typeof element === 'object' && isDOMElement(element)) {
return [element];
}
};
},{"./isDOMElement":242}],225:[function(require,module,exports){
var isDOMElement = require('./isDOMElement');
/**
* Find a DOM element.
*
* @param {Node|string} element
* @returns {Node|null}
*/
module.exports = function findDOMElement(element, context) {
if (context === void 0) {
context = document;
}
if (typeof element === 'string') {
return context.querySelector(element);
}
if (isDOMElement(element)) {
return element;
}
};
},{"./isDOMElement":242}],226:[function(require,module,exports){
/**
* Array.prototype.findIndex ponyfill for old browsers.
*
* @param {Array} array
* @param {Function} predicate
* @returns {number}
*/
module.exports = function findIndex(array, predicate) {
for (var i = 0; i < array.length; i++) {
if (predicate(array[i])) return i;
}
return -1;
};
},{}],227:[function(require,module,exports){
/**
* Takes a file object and turns it into fileID, by converting file.name to lowercase,
* removing extra characters and adding type, size and lastModified
*
* @param {object} file
* @returns {string} the fileID
*/
module.exports = function generateFileID(file) {
// It's tempting to do `[items].filter(Boolean).join('-')` here, but that
// is slower! simple string concatenation is fast
var id = 'uppy';
if (typeof file.name === 'string') {
id += "-" + encodeFilename(file.name.toLowerCase());
}
if (file.type !== undefined) {
id += "-" + file.type;
}
if (file.meta && typeof file.meta.relativePath === 'string') {
id += "-" + encodeFilename(file.meta.relativePath.toLowerCase());
}
if (file.data.size !== undefined) {
id += "-" + file.data.size;
}
if (file.data.lastModified !== undefined) {
id += "-" + file.data.lastModified;
}
return id;
};
function encodeFilename(name) {
var suffix = '';
return name.replace(/[^A-Z0-9]/ig, function (character) {
suffix += "-" + encodeCharacter(character);
return '/';
}) + suffix;
}
function encodeCharacter(character) {
return character.charCodeAt(0).toString(32);
}
},{}],228:[function(require,module,exports){
module.exports = function getBytesRemaining(fileProgress) {
return fileProgress.bytesTotal - fileProgress.bytesUploaded;
};
},{}],229:[function(require,module,exports){
var webkitGetAsEntryApi = require('./utils/webkitGetAsEntryApi/index');
var fallbackApi = require('./utils/fallbackApi');
/**
* Returns a promise that resolves to the array of dropped files (if a folder is dropped, and browser supports folder parsing - promise resolves to the flat array of all files in all directories).
* Each file has .relativePath prop appended to it (e.g. "/docs/Prague/ticket_from_prague_to_ufa.pdf") if browser supports it. Otherwise it's undefined.
*
* @param {DataTransfer} dataTransfer
* @param {Function} logDropError - a function that's called every time some folder or some file error out (e.g. because of the folder name being too long on Windows). Notice that resulting promise will always be resolved anyway.
*
* @returns {Promise} - Array<File>
*/
module.exports = function getDroppedFiles(dataTransfer, _temp) {
var _ref = _temp === void 0 ? {} : _temp,
_ref$logDropError = _ref.logDropError,
logDropError = _ref$logDropError === void 0 ? function () {} : _ref$logDropError;
// Get all files from all subdirs. Works (at least) in Chrome, Mozilla, and Safari
if (dataTransfer.items && dataTransfer.items[0] && 'webkitGetAsEntry' in dataTransfer.items[0]) {
return webkitGetAsEntryApi(dataTransfer, logDropError); // Otherwise just return all first-order files
}
return fallbackApi(dataTransfer);
};
},{"./utils/fallbackApi":230,"./utils/webkitGetAsEntryApi/index":233}],230:[function(require,module,exports){
var toArray = require('../../toArray'); // .files fallback, should be implemented in any browser
module.exports = function fallbackApi(dataTransfer) {
var files = toArray(dataTransfer.files);
return Promise.resolve(files);
};
},{"../../toArray":252}],231:[function(require,module,exports){
/**
* Recursive function, calls the original callback() when the directory is entirely parsed.
*
* @param {FileSystemDirectoryReader} directoryReader
* @param {Array} oldEntries
* @param {Function} logDropError
* @param {Function} callback - called with ([ all files and directories in that directoryReader ])
*/
module.exports = function getFilesAndDirectoriesFromDirectory(directoryReader, oldEntries, logDropError, _ref) {
var onSuccess = _ref.onSuccess;
directoryReader.readEntries(function (entries) {
var newEntries = [].concat(oldEntries, entries); // According to the FileSystem API spec, getFilesAndDirectoriesFromDirectory() must be called until it calls the onSuccess with an empty array.
if (entries.length) {
setTimeout(function () {
getFilesAndDirectoriesFromDirectory(directoryReader, newEntries, logDropError, {
onSuccess: onSuccess
});
}, 0); // Done iterating this particular directory
} else {
onSuccess(newEntries);
}
}, // Make sure we resolve on error anyway, it's fine if only one directory couldn't be parsed!
function (error) {
logDropError(error);
onSuccess(oldEntries);
});
};
},{}],232:[function(require,module,exports){
/**
* Get the relative path from the FileEntry#fullPath, because File#webkitRelativePath is always '', at least onDrop.
*
* @param {FileEntry} fileEntry
*
* @returns {string|null} - if file is not in a folder - return null (this is to be consistent with .relativePath-s of files selected from My Device). If file is in a folder - return its fullPath, e.g. '/simpsons/hi.jpeg'.
*/
module.exports = function getRelativePath(fileEntry) {
// fileEntry.fullPath - "/simpsons/hi.jpeg" or undefined (for browsers that don't support it)
// fileEntry.name - "hi.jpeg"
if (!fileEntry.fullPath || fileEntry.fullPath === "/" + fileEntry.name) {
return null;
}
return fileEntry.fullPath;
};
},{}],233:[function(require,module,exports){
var toArray = require('../../../toArray');
var getRelativePath = require('./getRelativePath');
var getFilesAndDirectoriesFromDirectory = require('./getFilesAndDirectoriesFromDirectory');
module.exports = function webkitGetAsEntryApi(dataTransfer, logDropError) {
var files = [];
var rootPromises = [];
/**
* Returns a resolved promise, when :files array is enhanced
*
* @param {(FileSystemFileEntry|FileSystemDirectoryEntry)} entry
* @returns {Promise} - empty promise that resolves when :files is enhanced with a file
*/
var createPromiseToAddFileOrParseDirectory = function createPromiseToAddFileOrParseDirectory(entry) {
return new Promise(function (resolve) {
// This is a base call
if (entry.isFile) {
// Creates a new File object which can be used to read the file.
entry.file(function (file) {
file.relativePath = getRelativePath(entry);
files.push(file);
resolve();
}, // Make sure we resolve on error anyway, it's fine if only one file couldn't be read!
function (error) {
logDropError(error);
resolve();
}); // This is a recursive call
} else if (entry.isDirectory) {
var directoryReader = entry.createReader();
getFilesAndDirectoriesFromDirectory(directoryReader, [], logDropError, {
onSuccess: function onSuccess(entries) {
var promises = entries.map(function (entry) {
return createPromiseToAddFileOrParseDirectory(entry);
});
Promise.all(promises).then(function () {
return resolve();
});
}
});
}
});
}; // For each dropped item, - make sure it's a file/directory, and start deepening in!
toArray(dataTransfer.items).forEach(function (item) {
var entry = item.webkitGetAsEntry(); // :entry can be null when we drop the url e.g.
if (entry) {
rootPromises.push(createPromiseToAddFileOrParseDirectory(entry));
}
});
return Promise.all(rootPromises).then(function () {
return files;
});
};
},{"../../../toArray":252,"./getFilesAndDirectoriesFromDirectory":231,"./getRelativePath":232}],234:[function(require,module,exports){
/**
* Takes a full filename string and returns an object {name, extension}
*
* @param {string} fullFileName
* @returns {object} {name, extension}
*/
module.exports = function getFileNameAndExtension(fullFileName) {
var lastDot = fullFileName.lastIndexOf('.'); // these count as no extension: "no-dot", "trailing-dot."
if (lastDot === -1 || lastDot === fullFileName.length - 1) {
return {
name: fullFileName,
extension: undefined
};
}
return {
name: fullFileName.slice(0, lastDot),
extension: fullFileName.slice(lastDot + 1)
};
};
},{}],235:[function(require,module,exports){
var getFileNameAndExtension = require('./getFileNameAndExtension');
var mimeTypes = require('./mimeTypes');
module.exports = function getFileType(file) {
var fileExtension = file.name ? getFileNameAndExtension(file.name).extension : null;
fileExtension = fileExtension ? fileExtension.toLowerCase() : null;
if (file.type) {
// if mime type is set in the file object already, use that
return file.type;
}
if (fileExtension && mimeTypes[fileExtension]) {
// else, see if we can map extension to a mime type
return mimeTypes[fileExtension];
} // if all fails, fall back to a generic byte stream type
return 'application/octet-stream';
};
},{"./getFileNameAndExtension":234,"./mimeTypes":247}],236:[function(require,module,exports){
// TODO Check which types are actually supported in browsers. Chrome likes webm
// from my testing, but we may need more.
// We could use a library but they tend to contain dozens of KBs of mappings,
// most of which will go unused, so not sure if that's worth it.
var mimeToExtensions = {
'audio/mp3': 'mp3',
'audio/mp4': 'mp4',
'audio/ogg': 'ogg',
'audio/webm': 'webm',
'image/gif': 'gif',
'image/heic': 'heic',
'image/heif': 'heif',
'image/jpeg': 'jpg',
'image/png': 'png',
'image/svg+xml': 'svg',
'video/mp4': 'mp4',
'video/ogg': 'ogv',
'video/quicktime': 'mov',
'video/webm': 'webm',
'video/x-matroska': 'mkv',
'video/x-msvideo': 'avi'
};
module.exports = function getFileTypeExtension(mimeType) {
// Remove the ; bit in 'video/x-matroska;codecs=avc1'
mimeType = mimeType.replace(/;.*$/, '');
return mimeToExtensions[mimeType] || null;
};
},{}],237:[function(require,module,exports){
module.exports = function getSocketHost(url) {
// get the host domain
var regex = /^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/i;
var host = regex.exec(url)[1];
var socketProtocol = /^http:\/\//i.test(url) ? 'ws' : 'wss';
return socketProtocol + "://" + host;
};
},{}],238:[function(require,module,exports){
module.exports = function getSpeed(fileProgress) {
if (!fileProgress.bytesUploaded) return 0;
var timeElapsed = new Date() - fileProgress.uploadStarted;
var uploadSpeed = fileProgress.bytesUploaded / (timeElapsed / 1000);
return uploadSpeed;
};
},{}],239:[function(require,module,exports){
/**
* Get the declared text direction for an element.
*
* @param {Node} element
* @returns {string|undefined}
*/
function getTextDirection(element) {
// There is another way to determine text direction using getComputedStyle(), as done here:
// https://github.com/pencil-js/text-direction/blob/2a235ce95089b3185acec3b51313cbba921b3811/text-direction.js
//
// We do not use that approach because we are interested specifically in the _declared_ text direction.
// If no text direction is declared, we have to provide our own explicit text direction so our
// bidirectional CSS style sheets work.
while (element && !element.dir) {
element = element.parentNode;
}
return element ? element.dir : undefined;
}
module.exports = getTextDirection;
},{}],240:[function(require,module,exports){
/**
* Returns a timestamp in the format of `hours:minutes:seconds`
*/
module.exports = function getTimeStamp() {
var date = new Date();
var hours = pad(date.getHours().toString());
var minutes = pad(date.getMinutes().toString());
var seconds = pad(date.getSeconds().toString());
return hours + ":" + minutes + ":" + seconds;
};
/**
* Adds zero to strings shorter than two characters
*/
function pad(str) {
return str.length !== 2 ? 0 + str : str;
}
},{}],241:[function(require,module,exports){
module.exports = function has(object, key) {
return Object.prototype.hasOwnProperty.call(object, key);
};
},{}],242:[function(require,module,exports){
/**
* Check if an object is a DOM element. Duck-typing based on `nodeType`.
*
* @param {*} obj
*/
module.exports = function isDOMElement(obj) {
return obj && typeof obj === 'object' && obj.nodeType === Node.ELEMENT_NODE;
};
},{}],243:[function(require,module,exports){
/**
* Checks if the browser supports Drag & Drop (not supported on mobile devices, for example).
*
* @returns {boolean}
*/
module.exports = function isDragDropSupported() {
var div = document.createElement('div');
if (!('draggable' in div) || !('ondragstart' in div && 'ondrop' in div)) {
return false;
}
if (!('FormData' in window)) {
return false;
}
if (!('FileReader' in window)) {
return false;
}
return true;
};
},{}],244:[function(require,module,exports){
function isNetworkError(xhr) {
if (!xhr) {
return false;
}
return xhr.readyState !== 0 && xhr.readyState !== 4 || xhr.status === 0;
}
module.exports = isNetworkError;
},{}],245:[function(require,module,exports){
/**
* Check if a URL string is an object URL from `URL.createObjectURL`.
*
* @param {string} url
* @returns {boolean}
*/
module.exports = function isObjectURL(url) {
return url.indexOf('blob:') === 0;
};
},{}],246:[function(require,module,exports){
module.exports = function isPreviewSupported(fileType) {
if (!fileType) return false;
var fileTypeSpecific = fileType.split('/')[1]; // list of images that browsers can preview
if (/^(jpe?g|gif|png|svg|svg\+xml|bmp|webp|avif)$/.test(fileTypeSpecific)) {
return true;
}
return false;
};
},{}],247:[function(require,module,exports){
// ___Why not add the mime-types package?
// It's 19.7kB gzipped, and we only need mime types for well-known extensions (for file previews).
// ___Where to take new extensions from?
// https://github.com/jshttp/mime-db/blob/master/db.json
module.exports = {
md: 'text/markdown',
markdown: 'text/markdown',
mp4: 'video/mp4',
mp3: 'audio/mp3',
svg: 'image/svg+xml',
jpg: 'image/jpeg',
png: 'image/png',
gif: 'image/gif',
heic: 'image/heic',
heif: 'image/heif',
yaml: 'text/yaml',
yml: 'text/yaml',
csv: 'text/csv',
tsv: 'text/tab-separated-values',
tab: 'text/tab-separated-values',
avi: 'video/x-msvideo',
mks: 'video/x-matroska',
mkv: 'video/x-matroska',
mov: 'video/quicktime',
doc: 'application/msword',
docm: 'application/vnd.ms-word.document.macroenabled.12',
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
dot: 'application/msword',
dotm: 'application/vnd.ms-word.template.macroenabled.12',
dotx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
xla: 'application/vnd.ms-excel',
xlam: 'application/vnd.ms-excel.addin.macroenabled.12',
xlc: 'application/vnd.ms-excel',
xlf: 'application/x-xliff+xml',
xlm: 'application/vnd.ms-excel',
xls: 'application/vnd.ms-excel',
xlsb: 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
xlsm: 'application/vnd.ms-excel.sheet.macroenabled.12',
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
xlt: 'application/vnd.ms-excel',
xltm: 'application/vnd.ms-excel.template.macroenabled.12',
xltx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
xlw: 'application/vnd.ms-excel',
txt: 'text/plain',
text: 'text/plain',
conf: 'text/plain',
log: 'text/plain',
pdf: 'application/pdf',
zip: 'application/zip',
'7z': 'application/x-7z-compressed',
rar: 'application/x-rar-compressed',
tar: 'application/x-tar',
gz: 'application/gzip',
dmg: 'application/x-apple-diskimage'
};
},{}],248:[function(require,module,exports){
var secondsToTime = require('./secondsToTime');
module.exports = function prettyETA(seconds) {
var time = secondsToTime(seconds); // Only display hours and minutes if they are greater than 0 but always
// display minutes if hours is being displayed
// Display a leading zero if the there is a preceding unit: 1m 05s, but 5s
var hoursStr = time.hours ? time.hours + "h " : '';
var minutesVal = time.hours ? ("0" + time.minutes).substr(-2) : time.minutes;
var minutesStr = minutesVal ? minutesVal + "m" : '';
var secondsVal = minutesVal ? ("0" + time.seconds).substr(-2) : time.seconds;
var secondsStr = time.hours ? '' : minutesVal ? " " + secondsVal + "s" : secondsVal + "s";
return "" + hoursStr + minutesStr + secondsStr;
};
},{"./secondsToTime":250}],249:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var getFileNameAndExtension = require('./getFileNameAndExtension');
module.exports = function remoteFileObjToLocal(file) {
return _extends({}, file, {
type: file.mimeType,
extension: file.name ? getFileNameAndExtension(file.name).extension : null
});
};
},{"./getFileNameAndExtension":234}],250:[function(require,module,exports){
module.exports = function secondsToTime(rawSeconds) {
var hours = Math.floor(rawSeconds / 3600) % 24;
var minutes = Math.floor(rawSeconds / 60) % 60;
var seconds = Math.floor(rawSeconds % 60);
return {
hours: hours,
minutes: minutes,
seconds: seconds
};
};
},{}],251:[function(require,module,exports){
module.exports = function settle(promises) {
var resolutions = [];
var rejections = [];
function resolved(value) {
resolutions.push(value);
}
function rejected(error) {
rejections.push(error);
}
var wait = Promise.all(promises.map(function (promise) {
return promise.then(resolved, rejected);
}));
return wait.then(function () {
return {
successful: resolutions,
failed: rejections
};
});
};
},{}],252:[function(require,module,exports){
/**
* Converts list into array
*/
module.exports = function toArray(list) {
return Array.prototype.slice.call(list || [], 0);
};
},{}],253:[function(require,module,exports){
/**
* Truncates a string to the given number of chars (maxLength) by inserting '...' in the middle of that string.
* Partially taken from https://stackoverflow.com/a/5723274/3192470.
*
* @param {string} string - string to be truncated
* @param {number} maxLength - maximum size of the resulting string
* @returns {string}
*/
module.exports = function truncateString(string, maxLength) {
var separator = '...'; // Return original string if it's already shorter than maxLength
if (string.length <= maxLength) {
return string; // Return truncated substring without '...' if string can't be meaningfully truncated
}
if (maxLength <= separator.length) {
return string.substr(0, maxLength); // Return truncated string divided in half by '...'
}
var charsToShow = maxLength - separator.length;
var frontChars = Math.ceil(charsToShow / 2);
var backChars = Math.floor(charsToShow / 2);
return string.substr(0, frontChars) + separator + string.substr(string.length - backChars);
};
},{}],254:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
fill: "#0097DC",
width: "66",
height: "55",
viewBox: "0 0 66 55"
}, h("path", {
d: "M57.3 8.433c4.59 0 8.1 3.51 8.1 8.1v29.7c0 4.59-3.51 8.1-8.1 8.1H8.7c-4.59 0-8.1-3.51-8.1-8.1v-29.7c0-4.59 3.51-8.1 8.1-8.1h9.45l4.59-7.02c.54-.54 1.35-1.08 2.16-1.08h16.2c.81 0 1.62.54 2.16 1.08l4.59 7.02h9.45zM33 14.64c-8.62 0-15.393 6.773-15.393 15.393 0 8.62 6.773 15.393 15.393 15.393 8.62 0 15.393-6.773 15.393-15.393 0-8.62-6.773-15.393-15.393-15.393zM33 40c-5.648 0-9.966-4.319-9.966-9.967 0-5.647 4.318-9.966 9.966-9.966s9.966 4.319 9.966 9.966C42.966 35.681 38.648 40 33 40z",
fillRule: "evenodd"
}));
};
},{"preact":266}],255:[function(require,module,exports){
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
/* eslint-disable jsx-a11y/media-has-caption */
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
var SnapshotButton = require('./SnapshotButton');
var RecordButton = require('./RecordButton');
var RecordingLength = require('./RecordingLength');
var VideoSourceSelect = require('./VideoSourceSelect');
var SubmitButton = require('./SubmitButton');
var DiscardButton = require('./DiscardButton');
function isModeAvailable(modes, mode) {
return modes.indexOf(mode) !== -1;
}
var CameraScreen = /*#__PURE__*/function (_Component) {
_inheritsLoose(CameraScreen, _Component);
function CameraScreen() {
return _Component.apply(this, arguments) || this;
}
var _proto = CameraScreen.prototype;
_proto.componentDidMount = function componentDidMount() {
var onFocus = this.props.onFocus;
onFocus();
};
_proto.componentWillUnmount = function componentWillUnmount() {
var onStop = this.props.onStop;
onStop();
};
_proto.render = function render() {
var _this = this;
var _this$props = this.props,
src = _this$props.src,
recordedVideo = _this$props.recordedVideo,
recording = _this$props.recording,
modes = _this$props.modes,
supportsRecording = _this$props.supportsRecording,
videoSources = _this$props.videoSources,
showVideoSourceDropdown = _this$props.showVideoSourceDropdown,
showRecordingLength = _this$props.showRecordingLength,
onSubmit = _this$props.onSubmit,
i18n = _this$props.i18n,
mirror = _this$props.mirror,
onSnapshot = _this$props.onSnapshot,
onStartRecording = _this$props.onStartRecording,
onStopRecording = _this$props.onStopRecording,
onDiscardRecordedVideo = _this$props.onDiscardRecordedVideo,
recordingLengthSeconds = _this$props.recordingLengthSeconds;
var hasRecordedVideo = !!recordedVideo;
var shouldShowRecordButton = !hasRecordedVideo && supportsRecording && (isModeAvailable(modes, 'video-only') || isModeAvailable(modes, 'audio-only') || isModeAvailable(modes, 'video-audio'));
var shouldShowSnapshotButton = !hasRecordedVideo && isModeAvailable(modes, 'picture');
var shouldShowRecordingLength = supportsRecording && showRecordingLength;
var shouldShowVideoSourceDropdown = showVideoSourceDropdown && videoSources && videoSources.length > 1;
var videoProps = {
playsinline: true
};
if (recordedVideo) {
videoProps.muted = false;
videoProps.controls = true;
videoProps.src = recordedVideo; // reset srcObject in dom. If not resetted, stream sticks in element
if (this.videoElement) {
this.videoElement.srcObject = undefined;
}
} else {
videoProps.muted = true;
videoProps.autoplay = true;
videoProps.srcObject = src;
}
return h("div", {
className: "uppy uppy-Webcam-container"
}, h("div", {
className: "uppy-Webcam-videoContainer"
}, h("video", _extends({
/* eslint-disable-next-line no-return-assign */
ref: function ref(videoElement) {
return _this.videoElement = videoElement;
},
className: "uppy-Webcam-video " + (mirror ? 'uppy-Webcam-video--mirrored' : '')
/* eslint-disable-next-line react/jsx-props-no-spreading */
}, videoProps))), h("div", {
className: "uppy-Webcam-footer"
}, h("div", {
className: "uppy-Webcam-videoSourceContainer"
}, shouldShowVideoSourceDropdown ? VideoSourceSelect(this.props) : null), h("div", {
className: "uppy-Webcam-buttonContainer"
}, shouldShowSnapshotButton && h(SnapshotButton, {
onSnapshot: onSnapshot,
i18n: i18n
}), shouldShowRecordButton && h(RecordButton, {
recording: recording,
onStartRecording: onStartRecording,
onStopRecording: onStopRecording,
i18n: i18n
}), hasRecordedVideo && h(SubmitButton, {
onSubmit: onSubmit,
i18n: i18n
}), hasRecordedVideo && h(DiscardButton, {
onDiscard: onDiscardRecordedVideo,
i18n: i18n
})), shouldShowRecordingLength && h("div", {
className: "uppy-Webcam-recordingLength"
}, h(RecordingLength, {
recordingLengthSeconds: recordingLengthSeconds,
i18n: i18n
}))));
};
return CameraScreen;
}(Component);
module.exports = CameraScreen;
},{"./DiscardButton":256,"./RecordButton":258,"./RecordingLength":259,"./SnapshotButton":260,"./SubmitButton":261,"./VideoSourceSelect":262,"preact":266}],256:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
function DiscardButton(_ref) {
var onDiscard = _ref.onDiscard,
i18n = _ref.i18n;
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",
type: "button",
title: i18n('discardRecordedFile'),
"aria-label": i18n('discardRecordedFile'),
onClick: onDiscard,
"data-uppy-super-focusable": true
}, h("svg", {
width: "13",
height: "13",
viewBox: "0 0 13 13",
xmlns: "http://www.w3.org/2000/svg",
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon"
}, h("g", {
fill: "#FFF",
fillRule: "evenodd"
}, h("path", {
d: "M.496 11.367L11.103.76l1.414 1.414L1.911 12.781z"
}), h("path", {
d: "M11.104 12.782L.497 2.175 1.911.76l10.607 10.606z"
}))));
}
module.exports = DiscardButton;
},{"preact":266}],257:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (props) {
return h("div", {
className: "uppy-Webcam-permissons"
}, h("div", {
className: "uppy-Webcam-permissonsIcon"
}, props.icon()), h("h1", {
className: "uppy-Webcam-title"
}, props.hasCamera ? props.i18n('allowAccessTitle') : props.i18n('noCameraTitle')), h("p", null, props.hasCamera ? props.i18n('allowAccessDescription') : props.i18n('noCameraDescription')));
};
},{"preact":266}],258:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function RecordButton(_ref) {
var recording = _ref.recording,
onStartRecording = _ref.onStartRecording,
onStopRecording = _ref.onStopRecording,
i18n = _ref.i18n;
if (recording) {
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",
type: "button",
title: i18n('stopRecording'),
"aria-label": i18n('stopRecording'),
onClick: onStopRecording,
"data-uppy-super-focusable": true
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "100",
height: "100",
viewBox: "0 0 100 100"
}, h("rect", {
x: "15",
y: "15",
width: "70",
height: "70"
})));
}
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",
type: "button",
title: i18n('startRecording'),
"aria-label": i18n('startRecording'),
onClick: onStartRecording,
"data-uppy-super-focusable": true
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon",
width: "100",
height: "100",
viewBox: "0 0 100 100"
}, h("circle", {
cx: "50",
cy: "50",
r: "40"
})));
};
},{"preact":266}],259:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var formatSeconds = require('./formatSeconds');
module.exports = function RecordingLength(_ref) {
var recordingLengthSeconds = _ref.recordingLengthSeconds,
i18n = _ref.i18n;
var formattedRecordingLengthSeconds = formatSeconds(recordingLengthSeconds);
return h("span", {
"aria-label": i18n('recordingLength', {
recording_length: formattedRecordingLengthSeconds
})
}, formattedRecordingLengthSeconds);
};
},{"./formatSeconds":263,"preact":266}],260:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
var CameraIcon = require('./CameraIcon');
module.exports = function (_ref) {
var onSnapshot = _ref.onSnapshot,
i18n = _ref.i18n;
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--picture",
type: "button",
title: i18n('takePicture'),
"aria-label": i18n('takePicture'),
onClick: onSnapshot,
"data-uppy-super-focusable": true
}, CameraIcon());
};
},{"./CameraIcon":254,"preact":266}],261:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
function SubmitButton(_ref) {
var onSubmit = _ref.onSubmit,
i18n = _ref.i18n;
return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--submit",
type: "button",
title: i18n('submitRecordedFile'),
"aria-label": i18n('submitRecordedFile'),
onClick: onSubmit,
"data-uppy-super-focusable": true
}, h("svg", {
width: "12",
height: "9",
viewBox: "0 0 12 9",
xmlns: "http://www.w3.org/2000/svg",
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon"
}, h("path", {
fill: "#fff",
fillRule: "nonzero",
d: "M10.66 0L12 1.31 4.136 9 0 4.956l1.34-1.31L4.136 6.38z"
})));
}
module.exports = SubmitButton;
},{"preact":266}],262:[function(require,module,exports){
var _require = require('preact'),
h = _require.h;
module.exports = function (_ref) {
var currentDeviceId = _ref.currentDeviceId,
videoSources = _ref.videoSources,
onChangeVideoSource = _ref.onChangeVideoSource;
return h("div", {
className: "uppy-Webcam-videoSource"
}, h("select", {
className: "uppy-u-reset uppy-Webcam-videoSource-select",
onChange: function onChange(event) {
onChangeVideoSource(event.target.value);
}
}, videoSources.map(function (videoSource) {
return h("option", {
key: videoSource.deviceId,
value: videoSource.deviceId,
selected: videoSource.deviceId === currentDeviceId
}, videoSource.label);
})));
};
},{"preact":266}],263:[function(require,module,exports){
/**
* Takes an Integer value of seconds (e.g. 83) and converts it into a human-readable formatted string (e.g. '1:23').
*
* @param {Integer} seconds
* @returns {string} the formatted seconds (e.g. '1:23' for 1 minute and 23 seconds)
*
*/
module.exports = function formatSeconds(seconds) {
return Math.floor(seconds / 60) + ":" + String(seconds % 60).padStart(2, 0);
};
},{}],264:[function(require,module,exports){
var _class, _temp;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var _require = require('preact'),
h = _require.h;
var _require2 = require('@uppy/core'),
Plugin = _require2.Plugin;
var Translator = require('@uppy/utils/lib/Translator');
var getFileTypeExtension = require('@uppy/utils/lib/getFileTypeExtension');
var mimeTypes = require('@uppy/utils/lib/mimeTypes');
var canvasToBlob = require('@uppy/utils/lib/canvasToBlob');
var supportsMediaRecorder = require('./supportsMediaRecorder');
var CameraIcon = require('./CameraIcon');
var CameraScreen = require('./CameraScreen');
var PermissionsScreen = require('./PermissionsScreen');
/**
* Normalize a MIME type or file extension into a MIME type.
*
* @param {string} fileType - MIME type or a file extension prefixed with `.`.
* @returns {string|undefined} The MIME type or `undefined` if the fileType is an extension and is not known.
*/
function toMimeType(fileType) {
if (fileType[0] === '.') {
return mimeTypes[fileType.slice(1)];
}
return fileType;
}
/**
* Is this MIME type a video?
*
* @param {string} mimeType - MIME type.
* @returns {boolean}
*/
function isVideoMimeType(mimeType) {
return /^video\/[^*]+$/.test(mimeType);
}
/**
* Is this MIME type an image?
*
* @param {string} mimeType - MIME type.
* @returns {boolean}
*/
function isImageMimeType(mimeType) {
return /^image\/[^*]+$/.test(mimeType);
}
/**
* Setup getUserMedia, with polyfill for older browsers
* Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
*/
function getMediaDevices() {
// eslint-disable-next-line compat/compat
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// eslint-disable-next-line compat/compat
return navigator.mediaDevices;
}
var _getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
if (!_getUserMedia) {
return null;
}
return {
getUserMedia: function getUserMedia(opts) {
return new Promise(function (resolve, reject) {
_getUserMedia.call(navigator, opts, resolve, reject);
});
}
};
}
/**
* Webcam
*/
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Webcam, _Plugin);
// eslint-disable-next-line global-require
function Webcam(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.mediaDevices = getMediaDevices();
_this.supportsUserMedia = !!_this.mediaDevices; // eslint-disable-next-line no-restricted-globals
_this.protocol = location.protocol.match(/https/i) ? 'https' : 'http';
_this.id = _this.opts.id || 'Webcam';
_this.title = _this.opts.title || 'Camera';
_this.type = 'acquirer';
_this.capturedMediaFile = null;
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#03BFEF",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M22 11c1.133 0 2 .867 2 2v7.333c0 1.134-.867 2-2 2H10c-1.133 0-2-.866-2-2V13c0-1.133.867-2 2-2h2.333l1.134-1.733C13.6 9.133 13.8 9 14 9h4c.2 0 .4.133.533.267L19.667 11H22zm-6 1.533a3.764 3.764 0 0 0-3.8 3.8c0 2.129 1.672 3.801 3.8 3.801s3.8-1.672 3.8-3.8c0-2.13-1.672-3.801-3.8-3.801zm0 6.261c-1.395 0-2.46-1.066-2.46-2.46 0-1.395 1.065-2.461 2.46-2.461s2.46 1.066 2.46 2.46c0 1.395-1.065 2.461-2.46 2.461z",
fill: "#FFF",
fillRule: "nonzero"
})));
};
_this.defaultLocale = {
strings: {
smile: 'Smile!',
takePicture: 'Take a picture',
startRecording: 'Begin video recording',
stopRecording: 'Stop video recording',
allowAccessTitle: 'Please allow access to your camera',
allowAccessDescription: 'In order to take pictures or record video with your camera, please allow camera access for this site.',
noCameraTitle: 'Camera Not Available',
noCameraDescription: 'In order to take pictures or record video, please connect a camera device',
recordingStoppedMaxSize: 'Recording stopped because the file size is about to exceed the limit',
recordingLength: 'Recording length %{recording_length}',
submitRecordedFile: 'Submit recorded file',
discardRecordedFile: 'Discard recorded file'
}
}; // set default options
var defaultOptions = {
onBeforeSnapshot: function onBeforeSnapshot() {
return Promise.resolve();
},
countdown: false,
modes: ['video-audio', 'video-only', 'audio-only', 'picture'],
mirror: true,
showVideoSourceDropdown: false,
facingMode: 'user',
preferredImageMimeType: null,
preferredVideoMimeType: null,
showRecordingLength: false
};
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this.install = _this.install.bind(_assertThisInitialized(_this));
_this.setPluginState = _this.setPluginState.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this)); // Camera controls
_this.start = _this.start.bind(_assertThisInitialized(_this));
_this.stop = _this.stop.bind(_assertThisInitialized(_this));
_this.takeSnapshot = _this.takeSnapshot.bind(_assertThisInitialized(_this));
_this.startRecording = _this.startRecording.bind(_assertThisInitialized(_this));
_this.stopRecording = _this.stopRecording.bind(_assertThisInitialized(_this));
_this.discardRecordedVideo = _this.discardRecordedVideo.bind(_assertThisInitialized(_this));
_this.submit = _this.submit.bind(_assertThisInitialized(_this));
_this.oneTwoThreeSmile = _this.oneTwoThreeSmile.bind(_assertThisInitialized(_this));
_this.focus = _this.focus.bind(_assertThisInitialized(_this));
_this.changeVideoSource = _this.changeVideoSource.bind(_assertThisInitialized(_this));
_this.webcamActive = false;
if (_this.opts.countdown) {
_this.opts.onBeforeSnapshot = _this.oneTwoThreeSmile;
}
_this.setPluginState({
hasCamera: false,
cameraReady: false,
cameraError: null,
recordingLengthSeconds: 0,
videoSources: [],
currentDeviceId: null
});
return _this;
}
var _proto = Webcam.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, _extends({}, newOpts, {
videoConstraints: _extends({}, this.opts.videoConstraints, newOpts == null ? void 0 : newOpts.videoConstraints)
}));
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.hasCameraCheck = function hasCameraCheck() {
if (!this.mediaDevices) {
return Promise.resolve(false);
}
return this.mediaDevices.enumerateDevices().then(function (devices) {
return devices.some(function (device) {
return device.kind === 'videoinput';
});
});
};
_proto.isAudioOnly = function isAudioOnly() {
return this.opts.modes.length === 1 && this.opts.modes[0] === 'audio-only';
};
_proto.getConstraints = function getConstraints(deviceId) {
var _this$opts$videoConst;
if (deviceId === void 0) {
deviceId = null;
}
var acceptsAudio = this.opts.modes.indexOf('video-audio') !== -1 || this.opts.modes.indexOf('audio-only') !== -1;
var acceptsVideo = !this.isAudioOnly() && (this.opts.modes.indexOf('video-audio') !== -1 || this.opts.modes.indexOf('video-only') !== -1 || this.opts.modes.indexOf('picture') !== -1);
var videoConstraints = _extends({}, (_this$opts$videoConst = this.opts.videoConstraints) != null ? _this$opts$videoConst : {
facingMode: this.opts.facingMode
}, deviceId ? {
deviceId: deviceId,
facingMode: null
} : {});
return {
audio: acceptsAudio,
video: acceptsVideo ? videoConstraints : false
};
} // eslint-disable-next-line consistent-return
;
_proto.start = function start(options) {
var _this2 = this;
if (options === void 0) {
options = null;
}
if (!this.supportsUserMedia) {
return Promise.reject(new Error('Webcam access not supported'));
}
this.webcamActive = true;
this.opts.mirror = true;
var constraints = this.getConstraints(options && options.deviceId ? options.deviceId : null);
this.hasCameraCheck().then(function (hasCamera) {
_this2.setPluginState({
hasCamera: hasCamera
}); // ask user for access to their camera
return _this2.mediaDevices.getUserMedia(constraints).then(function (stream) {
_this2.stream = stream;
var currentDeviceId = null;
var tracks = _this2.isAudioOnly() ? stream.getAudioTracks() : stream.getVideoTracks();
if (!options || !options.deviceId) {
currentDeviceId = tracks[0].getSettings().deviceId;
} else {
tracks.forEach(function (track) {
if (track.getSettings().deviceId === options.deviceId) {
currentDeviceId = track.getSettings().deviceId;
}
});
} // Update the sources now, so we can access the names.
_this2.updateVideoSources();
_this2.setPluginState({
currentDeviceId: currentDeviceId,
cameraReady: true
});
}).catch(function (err) {
_this2.setPluginState({
cameraReady: false,
cameraError: err
});
_this2.uppy.info(err.message, 'error');
});
});
}
/**
* @returns {object}
*/
;
_proto.getMediaRecorderOptions = function getMediaRecorderOptions() {
var options = {}; // Try to use the `opts.preferredVideoMimeType` or one of the `allowedFileTypes` for the recording.
// If the browser doesn't support it, we'll fall back to the browser default instead.
// Safari doesn't have the `isTypeSupported` API.
if (MediaRecorder.isTypeSupported) {
var restrictions = this.uppy.opts.restrictions;
var preferredVideoMimeTypes = [];
if (this.opts.preferredVideoMimeType) {
preferredVideoMimeTypes = [this.opts.preferredVideoMimeType];
} else if (restrictions.allowedFileTypes) {
preferredVideoMimeTypes = restrictions.allowedFileTypes.map(toMimeType).filter(isVideoMimeType);
}
var filterSupportedTypes = function filterSupportedTypes(candidateType) {
return MediaRecorder.isTypeSupported(candidateType) && getFileTypeExtension(candidateType);
};
var acceptableMimeTypes = preferredVideoMimeTypes.filter(filterSupportedTypes);
if (acceptableMimeTypes.length > 0) {
// eslint-disable-next-line prefer-destructuring
options.mimeType = acceptableMimeTypes[0];
}
}
return options;
};
_proto.startRecording = function startRecording() {
var _this3 = this;
// only used if supportsMediaRecorder() returned true
// eslint-disable-next-line compat/compat
this.recorder = new MediaRecorder(this.stream, this.getMediaRecorderOptions());
this.recordingChunks = [];
var stoppingBecauseOfMaxSize = false;
this.recorder.addEventListener('dataavailable', function (event) {
_this3.recordingChunks.push(event.data);
var restrictions = _this3.uppy.opts.restrictions;
if (_this3.recordingChunks.length > 1 && restrictions.maxFileSize != null && !stoppingBecauseOfMaxSize) {
var totalSize = _this3.recordingChunks.reduce(function (acc, chunk) {
return acc + chunk.size;
}, 0); // Exclude the initial chunk from the average size calculation because it is likely to be a very small outlier
var averageChunkSize = (totalSize - _this3.recordingChunks[0].size) / (_this3.recordingChunks.length - 1);
var expectedEndChunkSize = averageChunkSize * 3;
var maxSize = Math.max(0, restrictions.maxFileSize - expectedEndChunkSize);
if (totalSize > maxSize) {
stoppingBecauseOfMaxSize = true;
_this3.uppy.info(_this3.i18n('recordingStoppedMaxSize'), 'warning', 4000);
_this3.stopRecording();
}
}
}); // use a "time slice" of 500ms: ondataavailable will be called each 500ms
// smaller time slices mean we can more accurately check the max file size restriction
this.recorder.start(500);
if (this.opts.showRecordingLength) {
// Start the recordingLengthTimer if we are showing the recording length.
this.recordingLengthTimer = setInterval(function () {
var currentRecordingLength = _this3.getPluginState().recordingLengthSeconds;
_this3.setPluginState({
recordingLengthSeconds: currentRecordingLength + 1
});
}, 1000);
}
this.setPluginState({
isRecording: true
});
};
_proto.stopRecording = function stopRecording() {
var _this4 = this;
var stopped = new Promise(function (resolve) {
_this4.recorder.addEventListener('stop', function () {
resolve();
});
_this4.recorder.stop();
if (_this4.opts.showRecordingLength) {
// Stop the recordingLengthTimer if we are showing the recording length.
clearInterval(_this4.recordingLengthTimer);
_this4.setPluginState({
recordingLengthSeconds: 0
});
}
});
return stopped.then(function () {
_this4.setPluginState({
isRecording: false
});
return _this4.getVideo();
}).then(function (file) {
try {
_this4.capturedMediaFile = file; // create object url for capture result preview
_this4.setPluginState({
// eslint-disable-next-line compat/compat
recordedVideo: URL.createObjectURL(file.data)
});
_this4.opts.mirror = false;
} catch (err) {
// Logging the error, exept restrictions, which is handled in Core
if (!err.isRestriction) {
_this4.uppy.log(err);
}
}
}).then(function () {
_this4.recordingChunks = null;
_this4.recorder = null;
}, function (error) {
_this4.recordingChunks = null;
_this4.recorder = null;
throw error;
});
};
_proto.discardRecordedVideo = function discardRecordedVideo() {
this.setPluginState({
recordedVideo: null
});
this.opts.mirror = true;
this.capturedMediaFile = null;
};
_proto.submit = function submit() {
try {
if (this.capturedMediaFile) {
this.uppy.addFile(this.capturedMediaFile);
}
} catch (err) {
// Logging the error, exept restrictions, which is handled in Core
if (!err.isRestriction) {
this.uppy.log(err, 'error');
}
}
};
_proto.stop = function stop() {
if (this.stream) {
this.stream.getAudioTracks().forEach(function (track) {
track.stop();
});
this.stream.getVideoTracks().forEach(function (track) {
track.stop();
});
}
this.webcamActive = false;
this.stream = null;
this.setPluginState({
recordedVideo: null
});
};
_proto.getVideoElement = function getVideoElement() {
return this.el.querySelector('.uppy-Webcam-video');
};
_proto.oneTwoThreeSmile = function oneTwoThreeSmile() {
var _this5 = this;
return new Promise(function (resolve, reject) {
var count = _this5.opts.countdown; // eslint-disable-next-line consistent-return
var countDown = setInterval(function () {
if (!_this5.webcamActive) {
clearInterval(countDown);
_this5.captureInProgress = false;
return reject(new Error('Webcam is not active'));
}
if (count > 0) {
_this5.uppy.info(count + "...", 'warning', 800);
count--;
} else {
clearInterval(countDown);
_this5.uppy.info(_this5.i18n('smile'), 'success', 1500);
setTimeout(function () {
return resolve();
}, 1500);
}
}, 1000);
});
};
_proto.takeSnapshot = function takeSnapshot() {
var _this6 = this;
if (this.captureInProgress) return;
this.captureInProgress = true;
this.opts.onBeforeSnapshot().catch(function (err) {
var message = typeof err === 'object' ? err.message : err;
_this6.uppy.info(message, 'error', 5000);
return Promise.reject(new Error("onBeforeSnapshot: " + message));
}).then(function () {
return _this6.getImage();
}).then(function (tagFile) {
_this6.captureInProgress = false;
try {
_this6.uppy.addFile(tagFile);
} catch (err) {
// Logging the error, except restrictions, which is handled in Core
if (!err.isRestriction) {
_this6.uppy.log(err);
}
}
}, function (error) {
_this6.captureInProgress = false;
throw error;
});
};
_proto.getImage = function getImage() {
var _this7 = this;
var video = this.getVideoElement();
if (!video) {
return Promise.reject(new Error('No video element found, likely due to the Webcam tab being closed.'));
}
var width = video.videoWidth;
var height = video.videoHeight;
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0);
var restrictions = this.uppy.opts.restrictions;
var preferredImageMimeTypes = [];
if (this.opts.preferredImageMimeType) {
preferredImageMimeTypes = [this.opts.preferredImageMimeType];
} else if (restrictions.allowedFileTypes) {
preferredImageMimeTypes = restrictions.allowedFileTypes.map(toMimeType).filter(isImageMimeType);
}
var mimeType = preferredImageMimeTypes[0] || 'image/jpeg';
var ext = getFileTypeExtension(mimeType) || 'jpg';
var name = "cam-" + Date.now() + "." + ext;
return canvasToBlob(canvas, mimeType).then(function (blob) {
return {
source: _this7.id,
name: name,
data: new Blob([blob], {
type: mimeType
}),
type: mimeType
};
});
};
_proto.getVideo = function getVideo() {
// Sometimes in iOS Safari, Blobs (especially the first Blob in the recordingChunks Array)
// have empty 'type' attributes (e.g. '') so we need to find a Blob that has a defined 'type'
// attribute in order to determine the correct MIME type.
var mimeType = this.recordingChunks.find(function (blob) {
var _blob$type;
return ((_blob$type = blob.type) == null ? void 0 : _blob$type.length) > 0;
}).type;
var fileExtension = getFileTypeExtension(mimeType);
if (!fileExtension) {
return Promise.reject(new Error("Could not retrieve recording: Unsupported media type \"" + mimeType + "\""));
}
var name = "webcam-" + Date.now() + "." + fileExtension;
var blob = new Blob(this.recordingChunks, {
type: mimeType
});
var file = {
source: this.id,
name: name,
data: new Blob([blob], {
type: mimeType
}),
type: mimeType
};
return Promise.resolve(file);
};
_proto.focus = function focus() {
var _this8 = this;
if (!this.opts.countdown) return;
setTimeout(function () {
_this8.uppy.info(_this8.i18n('smile'), 'success', 1500);
}, 1000);
};
_proto.changeVideoSource = function changeVideoSource(deviceId) {
this.stop();
this.start({
deviceId: deviceId
});
};
_proto.updateVideoSources = function updateVideoSources() {
var _this9 = this;
this.mediaDevices.enumerateDevices().then(function (devices) {
_this9.setPluginState({
videoSources: devices.filter(function (device) {
return device.kind === 'videoinput';
})
});
});
};
_proto.render = function render() {
if (!this.webcamActive) {
this.start();
}
var webcamState = this.getPluginState();
if (!webcamState.cameraReady || !webcamState.hasCamera) {
return h(PermissionsScreen, {
icon: CameraIcon,
i18n: this.i18n,
hasCamera: webcamState.hasCamera
});
}
return h(CameraScreen // eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, webcamState, {
onChangeVideoSource: this.changeVideoSource,
onSnapshot: this.takeSnapshot,
onStartRecording: this.startRecording,
onStopRecording: this.stopRecording,
onDiscardRecordedVideo: this.discardRecordedVideo,
onSubmit: this.submit,
onFocus: this.focus,
onStop: this.stop,
i18n: this.i18n,
modes: this.opts.modes,
showRecordingLength: this.opts.showRecordingLength,
showVideoSourceDropdown: this.opts.showVideoSourceDropdown,
supportsRecording: supportsMediaRecorder(),
recording: webcamState.isRecording,
mirror: this.opts.mirror,
src: this.stream
}));
};
_proto.install = function install() {
var _this10 = this;
this.setPluginState({
cameraReady: false,
recordingLengthSeconds: 0
});
var target = this.opts.target;
if (target) {
this.mount(target, this);
}
if (this.mediaDevices) {
this.updateVideoSources();
this.mediaDevices.ondevicechange = function () {
_this10.updateVideoSources();
if (_this10.stream) {
var restartStream = true;
var _this10$getPluginStat = _this10.getPluginState(),
videoSources = _this10$getPluginStat.videoSources,
currentDeviceId = _this10$getPluginStat.currentDeviceId;
videoSources.forEach(function (videoSource) {
if (currentDeviceId === videoSource.deviceId) {
restartStream = false;
}
});
if (restartStream) {
_this10.stop();
_this10.start();
}
}
};
}
};
_proto.uninstall = function uninstall() {
if (this.stream) {
this.stop();
}
this.unmount();
};
return Webcam;
}(Plugin), _class.VERSION = "1.8.13", _temp);
},{"./CameraIcon":254,"./CameraScreen":255,"./PermissionsScreen":257,"./supportsMediaRecorder":265,"@uppy/core":78,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/canvasToBlob":219,"@uppy/utils/lib/getFileTypeExtension":236,"@uppy/utils/lib/mimeTypes":247,"preact":266}],265:[function(require,module,exports){
module.exports = function supportsMediaRecorder() {
/* eslint-disable compat/compat */
return typeof MediaRecorder === 'function' && !!MediaRecorder.prototype && typeof MediaRecorder.prototype.start === 'function';
/* eslint-enable compat/compat */
};
},{}],266:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"dup":69}],267:[function(require,module,exports){
var _class, _temp;
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _require = require('@uppy/core'),
Plugin = _require.Plugin;
var cuid = require('cuid');
var Translator = require('@uppy/utils/lib/Translator');
var _require2 = require('@uppy/companion-client'),
Provider = _require2.Provider,
RequestClient = _require2.RequestClient,
Socket = _require2.Socket;
var emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress');
var getSocketHost = require('@uppy/utils/lib/getSocketHost');
var settle = require('@uppy/utils/lib/settle');
var EventTracker = require('@uppy/utils/lib/EventTracker');
var ProgressTimeout = require('@uppy/utils/lib/ProgressTimeout');
var RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue');
var NetworkError = require('@uppy/utils/lib/NetworkError');
var isNetworkError = require('@uppy/utils/lib/isNetworkError');
function buildResponseError(xhr, error) {
// No error message
if (!error) error = new Error('Upload error'); // Got an error message string
if (typeof error === 'string') error = new Error(error); // Got something else
if (!(error instanceof Error)) {
error = _extends(new Error('Upload error'), {
data: error
});
}
if (isNetworkError(xhr)) {
error = new NetworkError(error, xhr);
return error;
}
error.request = xhr;
return error;
}
/**
* Set `data.type` in the blob to `file.meta.type`,
* because we might have detected a more accurate file type in Uppy
* https://stackoverflow.com/a/50875615
*
* @param {object} file File object with `data`, `size` and `meta` properties
* @returns {object} blob updated with the new `type` set from `file.meta.type`
*/
function setTypeInBlob(file) {
var dataWithUpdatedType = file.data.slice(0, file.data.size, file.meta.type);
return dataWithUpdatedType;
}
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(XHRUpload, _Plugin);
function XHRUpload(uppy, opts) {
var _this;
_this = _Plugin.call(this, uppy, opts) || this;
_this.type = 'uploader';
_this.id = _this.opts.id || 'XHRUpload';
_this.title = 'XHRUpload';
_this.defaultLocale = {
strings: {
timedOut: 'Upload stalled for %{seconds} seconds, aborting.'
}
}; // Default options
var defaultOptions = {
formData: true,
fieldName: 'files[]',
method: 'post',
metaFields: null,
responseUrlFieldName: 'url',
bundle: false,
headers: {},
timeout: 30 * 1000,
limit: 0,
withCredentials: false,
responseType: '',
/**
* @typedef respObj
* @property {string} responseText
* @property {number} status
* @property {string} statusText
* @property {object.<string, string>} headers
*
* @param {string} responseText the response body string
* @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
*/
getResponseData: function getResponseData(responseText, response) {
var parsedResponse = {};
try {
parsedResponse = JSON.parse(responseText);
} catch (err) {
console.log(err);
}
return parsedResponse;
},
/**
*
* @param {string} responseText the response body string
* @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
*/
getResponseError: function getResponseError(responseText, response) {
var error = new Error('Upload error');
if (isNetworkError(response)) {
error = new NetworkError(error, response);
}
return error;
},
/**
* Check if the response from the upload endpoint indicates that the upload was successful.
*
* @param {number} status the response status code
* @param {string} responseText the response body string
* @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
*/
validateStatus: function validateStatus(status, responseText, response) {
return status >= 200 && status < 300;
}
};
_this.opts = _extends({}, defaultOptions, opts);
_this.i18nInit();
_this.handleUpload = _this.handleUpload.bind(_assertThisInitialized(_this)); // Simultaneous upload limiting is shared across all uploads with this plugin.
// __queue is for internal Uppy use only!
if (_this.opts.__queue instanceof RateLimitedQueue) {
_this.requests = _this.opts.__queue;
} else {
_this.requests = new RateLimitedQueue(_this.opts.limit);
}
if (_this.opts.bundle && !_this.opts.formData) {
throw new Error('`opts.formData` must be true when `opts.bundle` is enabled.');
}
_this.uploaderEvents = Object.create(null);
return _this;
}
var _proto = XHRUpload.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, newOpts);
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.getOptions = function getOptions(file) {
var overrides = this.uppy.getState().xhrUpload;
var headers = this.opts.headers;
var opts = _extends({}, this.opts, overrides || {}, file.xhrUpload || {}, {
headers: {}
}); // Support for `headers` as a function, only in the XHRUpload settings.
// Options set by other plugins in Uppy state or on the files themselves are still merged in afterward.
//
// ```js
// headers: (file) => ({ expires: file.meta.expires })
// ```
if (typeof headers === 'function') {
opts.headers = headers(file);
} else {
_extends(opts.headers, this.opts.headers);
}
if (overrides) {
_extends(opts.headers, overrides.headers);
}
if (file.xhrUpload) {
_extends(opts.headers, file.xhrUpload.headers);
}
return opts;
};
_proto.addMetadata = function addMetadata(formData, meta, opts) {
var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default.
: Object.keys(meta);
metaFields.forEach(function (item) {
formData.append(item, meta[item]);
});
};
_proto.createFormDataUpload = function createFormDataUpload(file, opts) {
var formPost = new FormData();
this.addMetadata(formPost, file.meta, opts);
var dataWithUpdatedType = setTypeInBlob(file);
if (file.name) {
formPost.append(opts.fieldName, dataWithUpdatedType, file.meta.name);
} else {
formPost.append(opts.fieldName, dataWithUpdatedType);
}
return formPost;
};
_proto.createBundledUpload = function createBundledUpload(files, opts) {
var _this2 = this;
var formPost = new FormData();
var _this$uppy$getState = this.uppy.getState(),
meta = _this$uppy$getState.meta;
this.addMetadata(formPost, meta, opts);
files.forEach(function (file) {
var opts = _this2.getOptions(file);
var dataWithUpdatedType = setTypeInBlob(file);
if (file.name) {
formPost.append(opts.fieldName, dataWithUpdatedType, file.name);
} else {
formPost.append(opts.fieldName, dataWithUpdatedType);
}
});
return formPost;
};
_proto.createBareUpload = function createBareUpload(file, opts) {
return file.data;
};
_proto.upload = function upload(file, current, total) {
var _this3 = this;
var opts = this.getOptions(file);
this.uppy.log("uploading " + current + " of " + total);
return new Promise(function (resolve, reject) {
_this3.uppy.emit('upload-started', file);
var data = opts.formData ? _this3.createFormDataUpload(file, opts) : _this3.createBareUpload(file, opts);
var xhr = new XMLHttpRequest();
_this3.uploaderEvents[file.id] = new EventTracker(_this3.uppy);
var timer = new ProgressTimeout(opts.timeout, function () {
xhr.abort();
queuedRequest.done();
var error = new Error(_this3.i18n('timedOut', {
seconds: Math.ceil(opts.timeout / 1000)
}));
_this3.uppy.emit('upload-error', file, error);
reject(error);
});
var id = cuid();
xhr.upload.addEventListener('loadstart', function (ev) {
_this3.uppy.log("[XHRUpload] " + id + " started");
});
xhr.upload.addEventListener('progress', function (ev) {
_this3.uppy.log("[XHRUpload] " + id + " progress: " + ev.loaded + " / " + ev.total); // Begin checking for timeouts when progress starts, instead of loading,
// to avoid timing out requests on browser concurrency queue
timer.progress();
if (ev.lengthComputable) {
_this3.uppy.emit('upload-progress', file, {
uploader: _this3,
bytesUploaded: ev.loaded,
bytesTotal: ev.total
});
}
});
xhr.addEventListener('load', function (ev) {
_this3.uppy.log("[XHRUpload] " + id + " finished");
timer.done();
queuedRequest.done();
if (_this3.uploaderEvents[file.id]) {
_this3.uploaderEvents[file.id].remove();
_this3.uploaderEvents[file.id] = null;
}
if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
var _body = opts.getResponseData(xhr.responseText, xhr);
var uploadURL = _body[opts.responseUrlFieldName];
var uploadResp = {
status: ev.target.status,
body: _body,
uploadURL: uploadURL
};
_this3.uppy.emit('upload-success', file, uploadResp);
if (uploadURL) {
_this3.uppy.log("Download " + file.name + " from " + uploadURL);
}
return resolve(file);
}
var body = opts.getResponseData(xhr.responseText, xhr);
var error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr));
var response = {
status: ev.target.status,
body: body
};
_this3.uppy.emit('upload-error', file, error, response);
return reject(error);
});
xhr.addEventListener('error', function (ev) {
_this3.uppy.log("[XHRUpload] " + id + " errored");
timer.done();
queuedRequest.done();
if (_this3.uploaderEvents[file.id]) {
_this3.uploaderEvents[file.id].remove();
_this3.uploaderEvents[file.id] = null;
}
var error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr));
_this3.uppy.emit('upload-error', file, error);
return reject(error);
});
xhr.open(opts.method.toUpperCase(), opts.endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType`
// before `open()` is called.
xhr.withCredentials = opts.withCredentials;
if (opts.responseType !== '') {
xhr.responseType = opts.responseType;
}
var queuedRequest = _this3.requests.run(function () {
// When using an authentication system like JWT, the bearer token goes as a header. This
// header needs to be fresh each time the token is refreshed so computing and setting the
// headers just before the upload starts enables this kind of authentication to work properly.
// Otherwise, half-way through the list of uploads the token could be stale and the upload would fail.
var currentOpts = _this3.getOptions(file);
Object.keys(currentOpts.headers).forEach(function (header) {
xhr.setRequestHeader(header, currentOpts.headers[header]);
});
xhr.send(data);
return function () {
timer.done();
xhr.abort();
};
});
_this3.onFileRemove(file.id, function () {
queuedRequest.abort();
reject(new Error('File removed'));
});
_this3.onCancelAll(file.id, function () {
queuedRequest.abort();
reject(new Error('Upload cancelled'));
});
});
};
_proto.uploadRemote = function uploadRemote(file, current, total) {
var _this4 = this;
var opts = this.getOptions(file);
return new Promise(function (resolve, reject) {
_this4.uppy.emit('upload-started', file);
var fields = {};
var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default.
: Object.keys(file.meta);
metaFields.forEach(function (name) {
fields[name] = file.meta[name];
});
var Client = file.remote.providerOptions.provider ? Provider : RequestClient;
var client = new Client(_this4.uppy, file.remote.providerOptions);
client.post(file.remote.url, _extends({}, file.remote.body, {
endpoint: opts.endpoint,
size: file.data.size,
fieldname: opts.fieldName,
metadata: fields,
httpMethod: opts.method,
useFormData: opts.formData,
headers: opts.headers
})).then(function (res) {
var token = res.token;
var host = getSocketHost(file.remote.companionUrl);
var socket = new Socket({
target: host + "/api/" + token,
autoOpen: false
});
_this4.uploaderEvents[file.id] = new EventTracker(_this4.uppy);
_this4.onFileRemove(file.id, function () {
socket.send('pause', {});
queuedRequest.abort();
resolve("upload " + file.id + " was removed");
});
_this4.onCancelAll(file.id, function () {
socket.send('pause', {});
queuedRequest.abort();
resolve("upload " + file.id + " was canceled");
});
_this4.onRetry(file.id, function () {
socket.send('pause', {});
socket.send('resume', {});
});
_this4.onRetryAll(file.id, function () {
socket.send('pause', {});
socket.send('resume', {});
});
socket.on('progress', function (progressData) {
return emitSocketProgress(_this4, progressData, file);
});
socket.on('success', function (data) {
var body = opts.getResponseData(data.response.responseText, data.response);
var uploadURL = body[opts.responseUrlFieldName];
var uploadResp = {
status: data.response.status,
body: body,
uploadURL: uploadURL
};
_this4.uppy.emit('upload-success', file, uploadResp);
queuedRequest.done();
if (_this4.uploaderEvents[file.id]) {
_this4.uploaderEvents[file.id].remove();
_this4.uploaderEvents[file.id] = null;
}
return resolve();
});
socket.on('error', function (errData) {
var resp = errData.response;
var error = resp ? opts.getResponseError(resp.responseText, resp) : _extends(new Error(errData.error.message), {
cause: errData.error
});
_this4.uppy.emit('upload-error', file, error);
queuedRequest.done();
if (_this4.uploaderEvents[file.id]) {
_this4.uploaderEvents[file.id].remove();
_this4.uploaderEvents[file.id] = null;
}
reject(error);
});
var queuedRequest = _this4.requests.run(function () {
socket.open();
if (file.isPaused) {
socket.send('pause', {});
}
return function () {
return socket.close();
};
});
}).catch(function (err) {
_this4.uppy.emit('upload-error', file, err);
reject(err);
});
});
};
_proto.uploadBundle = function uploadBundle(files) {
var _this5 = this;
return new Promise(function (resolve, reject) {
var endpoint = _this5.opts.endpoint;
var method = _this5.opts.method;
var optsFromState = _this5.uppy.getState().xhrUpload;
var formData = _this5.createBundledUpload(files, _extends({}, _this5.opts, optsFromState || {}));
var xhr = new XMLHttpRequest();
var timer = new ProgressTimeout(_this5.opts.timeout, function () {
xhr.abort();
var error = new Error(_this5.i18n('timedOut', {
seconds: Math.ceil(_this5.opts.timeout / 1000)
}));
emitError(error);
reject(error);
});
var emitError = function emitError(error) {
files.forEach(function (file) {
_this5.uppy.emit('upload-error', file, error);
});
};
xhr.upload.addEventListener('loadstart', function (ev) {
_this5.uppy.log('[XHRUpload] started uploading bundle');
timer.progress();
});
xhr.upload.addEventListener('progress', function (ev) {
timer.progress();
if (!ev.lengthComputable) return;
files.forEach(function (file) {
_this5.uppy.emit('upload-progress', file, {
uploader: _this5,
bytesUploaded: ev.loaded / ev.total * file.size,
bytesTotal: file.size
});
});
});
xhr.addEventListener('load', function (ev) {
timer.done();
if (_this5.opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
var body = _this5.opts.getResponseData(xhr.responseText, xhr);
var uploadResp = {
status: ev.target.status,
body: body
};
files.forEach(function (file) {
_this5.uppy.emit('upload-success', file, uploadResp);
});
return resolve();
}
var error = _this5.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error');
error.request = xhr;
emitError(error);
return reject(error);
});
xhr.addEventListener('error', function (ev) {
timer.done();
var error = _this5.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error');
emitError(error);
return reject(error);
});
_this5.uppy.on('cancel-all', function () {
timer.done();
xhr.abort();
});
xhr.open(method.toUpperCase(), endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType`
// before `open()` is called.
xhr.withCredentials = _this5.opts.withCredentials;
if (_this5.opts.responseType !== '') {
xhr.responseType = _this5.opts.responseType;
}
Object.keys(_this5.opts.headers).forEach(function (header) {
xhr.setRequestHeader(header, _this5.opts.headers[header]);
});
xhr.send(formData);
files.forEach(function (file) {
_this5.uppy.emit('upload-started', file);
});
});
};
_proto.uploadFiles = function uploadFiles(files) {
var _this6 = this;
var promises = files.map(function (file, i) {
var current = parseInt(i, 10) + 1;
var total = files.length;
if (file.error) {
return Promise.reject(new Error(file.error));
}
if (file.isRemote) {
return _this6.uploadRemote(file, current, total);
}
return _this6.upload(file, current, total);
});
return settle(promises);
};
_proto.onFileRemove = function onFileRemove(fileID, cb) {
this.uploaderEvents[fileID].on('file-removed', function (file) {
if (fileID === file.id) cb(file.id);
});
};
_proto.onRetry = function onRetry(fileID, cb) {
this.uploaderEvents[fileID].on('upload-retry', function (targetFileID) {
if (fileID === targetFileID) {
cb();
}
});
};
_proto.onRetryAll = function onRetryAll(fileID, cb) {
var _this7 = this;
this.uploaderEvents[fileID].on('retry-all', function (filesToRetry) {
if (!_this7.uppy.getFile(fileID)) return;
cb();
});
};
_proto.onCancelAll = function onCancelAll(fileID, cb) {
var _this8 = this;
this.uploaderEvents[fileID].on('cancel-all', function () {
if (!_this8.uppy.getFile(fileID)) return;
cb();
});
};
_proto.handleUpload = function handleUpload(fileIDs) {
var _this9 = this;
if (fileIDs.length === 0) {
this.uppy.log('[XHRUpload] No files to upload!');
return Promise.resolve();
} // no limit configured by the user, and no RateLimitedQueue passed in by a "parent" plugin (basically just AwsS3) using the top secret `__queue` option
if (this.opts.limit === 0 && !this.opts.__queue) {
this.uppy.log('[XHRUpload] When uploading multiple files at once, consider setting the `limit` option (to `10` for example), to limit the number of concurrent uploads, which helps prevent memory and network issues: https://uppy.io/docs/xhr-upload/#limit-0', 'warning');
}
this.uppy.log('[XHRUpload] Uploading...');
var files = fileIDs.map(function (fileID) {
return _this9.uppy.getFile(fileID);
});
if (this.opts.bundle) {
// if bundle: true, we don’t support remote uploads
var isSomeFileRemote = files.some(function (file) {
return file.isRemote;
});
if (isSomeFileRemote) {
throw new Error('Can’t upload remote files when the `bundle: true` option is set');
}
if (typeof this.opts.headers === 'function') {
throw new TypeError('`headers` may not be a function when the `bundle: true` option is set');
}
return this.uploadBundle(files);
}
return this.uploadFiles(files).then(function () {
return null;
});
};
_proto.install = function install() {
if (this.opts.bundle) {
var _this$uppy$getState2 = this.uppy.getState(),
capabilities = _this$uppy$getState2.capabilities;
this.uppy.setState({
capabilities: _extends({}, capabilities, {
individualCancellation: false
})
});
}
this.uppy.addUploader(this.handleUpload);
};
_proto.uninstall = function uninstall() {
if (this.opts.bundle) {
var _this$uppy$getState3 = this.uppy.getState(),
capabilities = _this$uppy$getState3.capabilities;
this.uppy.setState({
capabilities: _extends({}, capabilities, {
individualCancellation: true
})
});
}
this.uppy.removeUploader(this.handleUpload);
};
return XHRUpload;
}(Plugin), _class.VERSION = "1.7.5", _temp);
},{"@uppy/companion-client":75,"@uppy/core":78,"@uppy/utils/lib/EventTracker":213,"@uppy/utils/lib/NetworkError":215,"@uppy/utils/lib/ProgressTimeout":216,"@uppy/utils/lib/RateLimitedQueue":217,"@uppy/utils/lib/Translator":218,"@uppy/utils/lib/emitSocketProgress":222,"@uppy/utils/lib/getSocketHost":237,"@uppy/utils/lib/isNetworkError":244,"@uppy/utils/lib/settle":251,"cuid":15}],268:[function(require,module,exports){
require('es6-promise/auto');
require('whatwg-fetch');
module.exports = require('./');
},{"./":269,"es6-promise/auto":22,"whatwg-fetch":60}],269:[function(require,module,exports){
// Core
exports.Core = require('@uppy/core');
exports.debugLogger = exports.Core.debugLogger; // Utilities
exports.server = require('@uppy/companion-client');
exports.views = {
ProviderView: require('@uppy/provider-views')
}; // Stores
exports.DefaultStore = require('@uppy/store-default');
exports.ReduxStore = require('@uppy/store-redux'); // UI plugins
exports.Dashboard = require('@uppy/dashboard');
exports.DragDrop = require('@uppy/drag-drop');
exports.DropTarget = require('@uppy/drop-target');
exports.FileInput = require('@uppy/file-input');
exports.Informer = require('@uppy/informer');
exports.ProgressBar = require('@uppy/progress-bar');
exports.StatusBar = require('@uppy/status-bar');
exports.ImageEditor = require('@uppy/image-editor'); // Acquirers
exports.Dropbox = require('@uppy/dropbox');
exports.GoogleDrive = require('@uppy/google-drive');
exports.Instagram = require('@uppy/instagram');
exports.OneDrive = require('@uppy/onedrive');
exports.Box = require('@uppy/box');
exports.Facebook = require('@uppy/facebook');
exports.Unsplash = require('@uppy/unsplash');
exports.Url = require('@uppy/url');
exports.Webcam = require('@uppy/webcam');
exports.ScreenCapture = require('@uppy/screen-capture'); // Uploaders
exports.AwsS3 = require('@uppy/aws-s3');
exports.AwsS3Multipart = require('@uppy/aws-s3-multipart');
exports.Transloadit = require('@uppy/transloadit');
exports.Tus = require('@uppy/tus');
exports.XHRUpload = require('@uppy/xhr-upload'); // Miscellaneous
exports.Form = require('@uppy/form');
exports.GoldenRetriever = require('@uppy/golden-retriever');
exports.ReduxDevTools = require('@uppy/redux-dev-tools');
exports.ThumbnailGenerator = require('@uppy/thumbnail-generator');
exports.locales = {};
},{"@uppy/aws-s3":66,"@uppy/aws-s3-multipart":64,"@uppy/box":68,"@uppy/companion-client":75,"@uppy/core":78,"@uppy/dashboard":98,"@uppy/drag-drop":106,"@uppy/drop-target":108,"@uppy/dropbox":109,"@uppy/facebook":111,"@uppy/file-input":113,"@uppy/form":115,"@uppy/golden-retriever":119,"@uppy/google-drive":121,"@uppy/image-editor":124,"@uppy/informer":126,"@uppy/instagram":128,"@uppy/onedrive":130,"@uppy/progress-bar":132,"@uppy/provider-views":155,"@uppy/redux-dev-tools":157,"@uppy/screen-capture":164,"@uppy/status-bar":168,"@uppy/store-default":170,"@uppy/store-redux":171,"@uppy/thumbnail-generator":172,"@uppy/transloadit":177,"@uppy/tus":205,"@uppy/unsplash":206,"@uppy/url":209,"@uppy/webcam":264,"@uppy/xhr-upload":267}]},{},[268])(268)
});
//# sourceMappingURL=uppy.js.map