1(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.tus = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ 2"use strict"; 3 4Object.defineProperty(exports, "__esModule", { 5 value: true 6}); 7exports.default = fingerprint; 8/** 9 * Generate a fingerprint for a file which will be used the store the endpoint 10 * 11 * @param {File} file 12 * @return {String} 13 */ 14function fingerprint(file) { 15 return ["tus", file.name, file.type, file.size, file.lastModified].join("-"); 16} 17 18},{}],2:[function(_dereq_,module,exports){ 19"use strict"; 20 21var _upload = _dereq_("./upload"); 22 23var _upload2 = _interopRequireDefault(_upload); 24 25function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 26 27var defaultOptions = _upload2.default.defaultOptions; /* global window */ 28 29var _window = window; 30var XMLHttpRequest = _window.XMLHttpRequest; 31var localStorage = _window.localStorage; 32var Blob = _window.Blob; 33 34var isSupported = XMLHttpRequest && localStorage && Blob && typeof Blob.prototype.slice === "function"; 35 36// The usage of the commonjs exporting syntax instead of the new ECMAScript 37// one is actually inteded and prevents weird behaviour if we are trying to 38// import this module in another module using Babel. 39module.exports = { 40 Upload: _upload2.default, 41 isSupported: isSupported, 42 defaultOptions: defaultOptions 43}; 44 45},{"./upload":3}],3:[function(_dereq_,module,exports){ 46"use strict"; 47 48var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); /* global window, XMLHttpRequest */ 49 50Object.defineProperty(exports, "__esModule", { 51 value: true 52}); 53 54var _fingerprint = _dereq_("./fingerprint"); 55 56var _fingerprint2 = _interopRequireDefault(_fingerprint); 57 58var _extend = _dereq_("extend"); 59 60var _extend2 = _interopRequireDefault(_extend); 61 62function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 63 64function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 65 66var _window = window; 67var localStorage = _window.localStorage; 68var btoa = _window.btoa; 69 70var defaultOptions = { 71 endpoint: "", 72 fingerprint: _fingerprint2.default, 73 resume: true, 74 onProgress: null, 75 onChunkComplete: null, 76 onSuccess: null, 77 onError: null, 78 headers: {}, 79 chunkSize: Infinity, 80 withCredentials: false 81}; 82 83var Upload = (function () { 84 function Upload(file, options) { 85 _classCallCheck(this, Upload); 86 87 this.options = (0, _extend2.default)(true, {}, defaultOptions, options); 88 89 // The underlying File/Blob object 90 this.file = file; 91 92 // The URL against which the file will be uploaded 93 this.url = null; 94 95 // The underlying XHR object for the current PATCH request 96 this._xhr = null; 97 98 // The fingerpinrt for the current file (set after start()) 99 this._fingerprint = null; 100 101 // The offset used in the current PATCH request 102 this._offset = null; 103 104 // True if the current PATCH request has been aborted 105 this._aborted = false; 106 } 107 108 _createClass(Upload, [{ 109 key: "start", 110 value: function start() { 111 var file = this.file; 112 113 if (!file) { 114 this._emitError(new Error("tus: no file to upload provided")); 115 return; 116 } 117 118 if (!this.options.endpoint) { 119 this._emitError(new Error("tus: no endpoint provided")); 120 return; 121 } 122 123 // A URL has manually been specified, so we try to resume 124 if (this.url !== null) { 125 this._resumeUpload(); 126 return; 127 } 128 129 // Try to find the endpoint for the file in the localStorage 130 if (this.options.resume) { 131 this._fingerprint = this.options.fingerprint(file); 132 var resumedUrl = localStorage.getItem(this._fingerprint); 133 134 if (resumedUrl != null) { 135 this.url = resumedUrl; 136 this._resumeUpload(); 137 return; 138 } 139 } 140 141 // An upload has not started for the file yet, so we start a new one 142 this._createUpload(); 143 } 144 }, { 145 key: "abort", 146 value: function abort() { 147 if (this._xhr !== null) { 148 this._xhr.abort(); 149 this._aborted = true; 150 } 151 } 152 }, { 153 key: "_emitXhrError", 154 value: function _emitXhrError(xhr, err) { 155 err.originalRequest = xhr; 156 this._emitError(err); 157 } 158 }, { 159 key: "_emitError", 160 value: function _emitError(err) { 161 if (typeof this.options.onError === "function") { 162 this.options.onError(err); 163 } else { 164 throw err; 165 } 166 } 167 }, { 168 key: "_emitSuccess", 169 value: function _emitSuccess() { 170 if (typeof this.options.onSuccess === "function") { 171 this.options.onSuccess(); 172 } 173 } 174 175 /** 176 * Publishes notification when data has been sent to the server. This 177 * data may not have been accepted by the server yet. 178 * @param {number} bytesSent Number of bytes sent to the server.
179 * @param {number} bytesTotal Total number of bytes to be sent to the server. 180 */ 181 182 }, { 183 key: "_emitProgress", 184 value: function _emitProgress(bytesSent, bytesTotal) { 185 if (typeof this.options.onProgress === "function") { 186 this.options.onProgress(bytesSent, bytesTotal); 187 } 188 } 189 190 /** 191 * Publishes notification when a chunk of data has been sent to the server 192 * and accepted by the server. 193 * @param {number} chunkSize Size of the chunk that was accepted by the 194 * server. 195 * @param {number} bytesAccepted Total number of bytes that have been 196 * accepted by the server. 197 * @param {number} bytesTotal Total number of bytes to be sent to the server. 198 */ 199 200 }, { 201 key: "_emitChunkComplete", 202 value: function _emitChunkComplete(chunkSize, bytesAccepted, bytesTotal) { 203 if (typeof this.options.onChunkComplete === "function") { 204 this.options.onChunkComplete(chunkSize, bytesAccepted, bytesTotal); 205 } 206 } 207 208 /** 209 * Set the headers used in the request and the withCredentials property 210 * as defined in the options 211 * 212 * @param {XMLHttpRequest} xhr 213 */ 214 215 }, { 216 key: "_setupXHR", 217 value: function _setupXHR(xhr) { 218 xhr.setRequestHeader("Tus-Resumable", "1.0.0"); 219 var headers = this.options.headers; 220 221 for (var name in headers) { 222 xhr.setRequestHeader(name, headers[name]); 223 } 224 225 xhr.withCredentials = this.options.withCredentials; 226 } 227 228 /** 229 * Create a new upload using the creation extension by sending a POST 230 * request to the endpoint. After successful creation the file will be 231 * uploaded 232 * 233 * @api private 234 */ 235 236 }, { 237 key: "_createUpload", 238 value: function _createUpload() { 239 var _this = this; 240 241 var xhr = new XMLHttpRequest(); 242 xhr.open("POST", this.options.endpoint, true); 243 244 xhr.onload = function () { 245 if (!(xhr.status >= 200 && xhr.status < 300)) { 246 _this._emitXhrError(xhr, new Error("tus: unexpected response while creating upload")); 247 return; 248 } 249 250 _this.url = xhr.getResponseHeader("Location"); 251 252 if (_this.options.resume) { 253 localStorage.setItem(_this._fingerprint, _this.url); 254 } 255 256 _this._offset = 0; 257 _this._startUpload(); 258 }; 259 260 xhr.onerror = function () { 261 alert(xhr.status + ";" + xhr.responseText); 262 _this._emitXhrError(xhr, new Error("tus: failed to create upload")); 263 }; 264 265 this._setupXHR(xhr); 266 xhr.setRequestHeader("Upload-Length", this.file.size); 267 268 // Add metadata if values have been added 269 var metadata = encodeMetadata(this.options.metadata); 270 if (metadata !== "") { 271 xhr.setRequestHeader("Upload-Metadata", metadata); 272 } 273 274 xhr.send(null); 275 } 276 277 /* 278 * Try to resume an existing upload. First a HEAD request will be sent 279 * to retrieve the offset. If the request fails a new upload will be 280 * created. In the case of a successful response the file will be uploaded. 281 * 282 * @api private 283 */ 284 285 }, { 286 key: "_resumeUpload", 287 value: function _resumeUpload() { 288 var _this2 = this; 289 290 var xhr = new XMLHttpRequest(); 291 xhr.open("HEAD", this.url, true); 292 293 xhr.onload = function () { 294 if (!(xhr.status >= 200 && xhr.status < 300)) { 295 if (_this2.options.resume) { 296 // Remove stored fingerprint and corresponding endpoint, 297 // since the file can not be found 298 localStorage.removeItem(_this2._fingerprint); 299 } 300 301 // Try to create a new upload 302 _this2.url = null; 303 _this2._createUpload(); 304 return; 305 } 306 307 var offset = parseInt(xhr.getResponseHeader("Upload-Offset"), 10); 308 if (isNaN(offset)) { 309 _this2._emitXhrError(xhr, new Error("tus: invalid or missing offset value")); 310 return; 311 } 312 313 _this2._offset = offset; 314 _this2._startUpload(); 315 }; 316 317 xhr.onerror = function () { 318 _this2._emitXhrError(xhr, new Error("tus: failed to resume upload")); 319 }; 320 321 this._setupXHR(xhr); 322 xhr.send(null); 323 } 324 325 /** 326 * Start uploading the file using PATCH requests. The file will be divided 327 * into chunks as specified in the chunkSize option. During the upload 328 * the onProgress event handler may be invoked multiple times. 329 * 330 * @api private 331 */ 332 333 }, { 334 key: "_startUpload", 335 value: function _startUpload() { 336 var _this3 = this; 337 338 var xhr = this._xhr = new XMLHttpRequest(); 339 xhr.open("PATCH", this.url, true); 340 341 xhr.onload = function () { 342 if (!(xhr.status >= 200 && xhr.status < 300)) { 343 _this3._emitXhrError(xhr, new Error("tus: unexpected response while creating upload")); 344 return; 345 } 346 347 var offset = parseInt(xhr.getResponseHeader("Upload-Offset"), 10); 348 if (isNaN(offset)) {
349 _this3._emitXhrError(xhr, new Error("tus: invalid or missing offset value")); 350 return; 351 } 352 353 _this3._emitChunkComplete(offset - _this3._offset, offset, _this3.file.size); 354 355 _this3._offset = offset; 356 357 if (offset == _this3.file.size) { 358 // Yay, finally done :) 359 // Emit a last progress event 360 _this3._emitProgress(offset, offset); 361 _this3._emitSuccess(); 362 return; 363 } 364 365 _this3._startUpload(); 366 }; 367 368 xhr.onerror = function () { 369 // Don't emit an error if the upload was aborted manually 370 if (_this3._aborted) { 371 return; 372 } 373 374 _this3._emitXhrError(xhr, new Error("tus: failed to upload chunk at offset " + _this3._offset)); 375 }; 376 377 // Test support for progress events before attaching an event listener 378 if ("upload" in xhr) { 379 xhr.upload.onprogress = function (e) { 380 if (!e.lengthComputable) { 381 return; 382 } 383 384 _this3._emitProgress(start + e.loaded, _this3.file.size); 385 }; 386 } 387 388 this._setupXHR(xhr); 389 390 xhr.setRequestHeader("Upload-Offset", this._offset); 391 xhr.setRequestHeader("Content-Type", "application/offset+octet-stream"); 392 393 var start = this._offset; 394 var end = this._offset + this.options.chunkSize; 395 396 if (end === Infinity) { 397 end = this.file.size; 398 } 399 400 xhr.send(this.file.slice(start, end)); 401 } 402 }]); 403 404 return Upload; 405})(); 406 407function encodeMetadata(metadata) { 408 if (!("btoa" in window)) { 409 return ""; 410 } 411 412 var encoded = []; 413 414 for (var key in metadata) { 415 encoded.push(key + " " + btoa(unescape(encodeURIComponent(metadata[key])))); 416 } 417 418 return encoded.join(","); 419} 420 421Upload.defaultOptions = defaultOptions; 422 423exports.default = Upload; 424 425},{"./fingerprint":1,"extend":4}],4:[function(_dereq_,module,exports){ 426'use strict'; 427 428var hasOwn = Object.prototype.hasOwnProperty; 429var toStr = Object.prototype.toString; 430 431var isArray = function isArray(arr) { 432 if (typeof Array.isArray === 'function') { 433 return Array.isArray(arr); 434 } 435 436 return toStr.call(arr) === '[object Array]'; 437}; 438 439var isPlainObject = function isPlainObject(obj) { 440 if (!obj || toStr.call(obj) !== '[object Object]') { 441 return false; 442 } 443 444 var hasOwnConstructor = hasOwn.call(obj, 'constructor'); 445 var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); 446 // Not own constructor property must be Object 447 if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { 448 return false; 449 } 450 451 // Own properties are enumerated firstly, so to speed up, 452 // if last one is own, then all properties are own. 453 var key; 454 for (key in obj) {/**/} 455 456 return typeof key === 'undefined' || hasOwn.call(obj, key); 457}; 458 459module.exports = function extend() { 460 var options, name, src, copy, copyIsArray, clone, 461 target = arguments[0], 462 i = 1, 463 length = arguments.length, 464 deep = false; 465 466 // Handle a deep copy situation 467 if (typeof target === 'boolean') { 468 deep = target; 469 target = arguments[1] || {}; 470 // skip the boolean and the target 471 i = 2; 472 } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { 473 target = {}; 474 } 475 476 for (; i < length; ++i) { 477 options = arguments[i]; 478 // Only deal with non-null/undefined values 479 if (options != null) { 480 // Extend the base object 481 for (name in options) { 482 src = target[name]; 483 copy = options[name]; 484 485 // Prevent never-ending loop 486 if (target !== copy) { 487 // Recurse if we're merging plain objects or arrays 488 if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { 489 if (copyIsArray) { 490 copyIsArray = false; 491 clone = src && isArray(src) ? src : []; 492 } else { 493 clone = src && isPlainObject(src) ? src : {}; 494 } 495 496 // Never move original objects, clone them 497 target[name] = extend(deep, clone, copy); 498 499 // Don't bring in undefined values 500 } else if (typeof copy !== 'undefined') { 501 target[name] = copy; 502 } 503 } 504 } 505 } 506 } 507 508 // Return the modified object 509 return target; 510}; 511 512 513},{}]},{},[2])(2) 514});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.