// Generated by CoffeeScript 1.6.2 (function() { var Dropbox, DropboxChromeOnMessage, DropboxChromeSendMessage, DropboxClient, DropboxXhrArrayBufferView, DropboxXhrCanSendForms, DropboxXhrDoesPreflight, DropboxXhrIeMode, DropboxXhrRequest, DropboxXhrSendArrayBufferView, DropboxXhrWrapBlob, add32, arrayToBase64, atob, atobNibble, base64Digits, base64HmacSha1, base64Sha1, blobError, btoa, btoaNibble, crypto, dropboxEncodeKey, hmacSha1, name, requireError, rotateLeft32, sha1, stringToArray, value, _base64Digits, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Dropbox = function() { return null; }; Dropbox.Util = {}; Dropbox.EventSource = (function() { function EventSource(options) { this._cancelable = options && options.cancelable; this._listeners = []; } EventSource.prototype.addListener = function(listener) { if (typeof listener !== 'function') { throw new TypeError('Invalid listener type; expected function'); } if (__indexOf.call(this._listeners, listener) < 0) { this._listeners.push(listener); } return this; }; EventSource.prototype.removeListener = function(listener) { var i, index, subscriber, _i, _len, _ref; if (this._listeners.indexOf) { index = this._listeners.indexOf(listener); if (index !== -1) { this._listeners.splice(index, 1); } } else { _ref = this._listeners; for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { subscriber = _ref[i]; if (subscriber === listener) { this._listeners.splice(i, 1); break; } } } return this; }; EventSource.prototype.dispatch = function(event) { var listener, returnValue, _i, _len, _ref; _ref = this._listeners; for (_i = 0, _len = _ref.length; _i < _len; _i++) { listener = _ref[_i]; returnValue = listener(event); if (this._cancelable && returnValue === false) { return false; } } return true; }; return EventSource; })(); Dropbox.ApiError = (function() { ApiError.prototype.status = void 0; ApiError.prototype.method = void 0; ApiError.prototype.url = void 0; ApiError.prototype.responseText = void 0; ApiError.prototype.response = void 0; ApiError.NETWORK_ERROR = 0; ApiError.INVALID_PARAM = 400; ApiError.INVALID_TOKEN = 401; ApiError.OAUTH_ERROR = 403; ApiError.NOT_FOUND = 404; ApiError.INVALID_METHOD = 405; ApiError.RATE_LIMITED = 503; ApiError.OVER_QUOTA = 507; function ApiError(xhr, method, url) { var text, xhrError; this.method = method; this.url = url; this.status = xhr.status; if (xhr.responseType) { try { text = xhr.response || xhr.responseText; } catch (_error) { xhrError = _error; try { text = xhr.responseText; } catch (_error) { xhrError = _error; text = null; } } } else { try { text = xhr.responseText; } catch (_error) { xhrError = _error; text = null; } } if (text) { try { this.responseText = text.toString(); this.response = JSON.parse(text); } catch (_error) { xhrError = _error; this.response = null; } } else { this.responseText = '(no response)'; this.response = null; } } ApiError.prototype.toString = function() { return "Dropbox API error " + this.status + " from " + this.method + " " + this.url + " :: " + this.responseText; }; ApiError.prototype.inspect = function() { return this.toString(); }; return ApiError; })(); Dropbox.AuthDriver = (function() { function AuthDriver() {} AuthDriver.prototype.url = function(token) { return "https://some.url?dboauth_token=" + (Dropbox.Xhr.urlEncode(token)); }; AuthDriver.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { return callback('oauth-token'); }; AuthDriver.prototype.onAuthStateChange = function(client, callback) { return callback(); }; return AuthDriver; })(); Dropbox.Drivers = {}; if (typeof atob === 'function' && typeof btoa === 'function') { atob = function(string) { return window.atob(string); }; btoa = function(base64) { return window.btoa(base64); }; } else if ((typeof window !== 'undefined' || typeof self !== 'undefined') && (typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string')) { base64Digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; btoaNibble = function(accumulator, bytes, result) { var i, limit; limit = 3 - bytes; accumulator <<= limit * 8; i = 3; while (i >= limit) { result.push(base64Digits.charAt((accumulator >> (i * 6)) & 0x3F)); i -= 1; } i = bytes; while (i < 3) { result.push('='); i += 1; } return null; }; atobNibble = function(accumulator, digits, result) { var i, limit; limit = 4 - digits; accumulator <<= limit * 6; i = 2; while (i >= limit) { result.push(String.fromCharCode((accumulator >> (8 * i)) & 0xFF)); i -= 1; } return null; }; btoa = function(string) { var accumulator, bytes, i, result, _i, _ref; result = []; accumulator = 0; bytes = 0; for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { accumulator = (accumulator << 8) | string.charCodeAt(i); bytes += 1; if (bytes === 3) { btoaNibble(accumulator, bytes, result); accumulator = bytes = 0; } } if (bytes > 0) { btoaNibble(accumulator, bytes, result); } return result.join(''); }; atob = function(base64) { var accumulator, digit, digits, i, result, _i, _ref; result = []; accumulator = 0; digits = 0; for (i = _i = 0, _ref = base64.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { digit = base64.charAt(i); if (digit === '=') { break; } accumulator = (accumulator << 6) | base64Digits.indexOf(digit); digits += 1; if (digits === 4) { atobNibble(accumulator, digits, result); accumulator = digits = 0; } } if (digits > 0) { atobNibble(accumulator, digits, result); } return result.join(''); }; } else { atob = function(arg) { var buffer, i; buffer = new Buffer(arg, 'base64'); return ((function() { var _i, _ref, _results; _results = []; for (i = _i = 0, _ref = buffer.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { _results.push(String.fromCharCode(buffer[i])); } return _results; })()).join(''); }; btoa = function(arg) { var buffer, i; buffer = new Buffer((function() { var _i, _ref, _results; _results = []; for (i = _i = 0, _ref = arg.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { _results.push(arg.charCodeAt(i)); } return _results; })()); return buffer.toString('base64'); }; } Dropbox.Util.atob = atob; Dropbox.Util.btoa = btoa; Dropbox.Client = (function() { function Client(options) { var _this = this; this.sandbox = options.sandbox || false; this.apiServer = options.server || this.defaultApiServer(); this.authServer = options.authServer || this.defaultAuthServer(); this.fileServer = options.fileServer || this.defaultFileServer(); this.downloadServer = options.downloadServer || this.defaultDownloadServer(); this.onXhr = new Dropbox.EventSource({ cancelable: true }); this.onError = new Dropbox.EventSource; this.onAuthStateChange = new Dropbox.EventSource; this.xhrOnErrorHandler = function(error, callback) { return _this.handleXhrError(error, callback); }; this.oauth = new Dropbox.Oauth(options); this.driver = null; this.filter = null; this.uid = null; this.authState = null; this.authError = null; this._credentials = null; this.setCredentials(options); this.setupUrls(); } Client.prototype.authDriver = function(driver) { this.driver = driver; return this; }; Client.prototype.onXhr = null; Client.prototype.onError = null; Client.prototype.onAuthStateChange = null; Client.prototype.dropboxUid = function() { return this.uid; }; Client.prototype.credentials = function() { if (!this._credentials) { this.computeCredentials(); } return this._credentials; }; Client.prototype.authenticate = function(options, callback) { var interactive, oldAuthState, _fsmStep, _this = this; if (!callback && typeof options === 'function') { callback = options; options = null; } if (options && 'interactive' in options) { interactive = options.interactive; } else { interactive = true; } if (!(this.driver || this.authState === DropboxClient.DONE)) { throw new Error('Call authDriver to set an authentication driver'); } if (this.authState === DropboxClient.ERROR) { throw new Error('Client got in an error state. Call reset() to reuse it!'); } oldAuthState = null; _fsmStep = function() { var authUrl; if (oldAuthState !== _this.authState) { oldAuthState = _this.authState; if (_this.driver && _this.driver.onAuthStateChange) { _this.driver.onAuthStateChange(_this, _fsmStep); return; } } switch (_this.authState) { case DropboxClient.RESET: if (!interactive) { if (callback) { callback(null, _this); } return; } return _this.requestToken(function(error, data) { var token, tokenSecret; if (error) { _this.authError = error; _this.authState = DropboxClient.ERROR; } else { token = data.oauth_token; tokenSecret = data.oauth_token_secret; _this.oauth.setToken(token, tokenSecret); _this.authState = DropboxClient.REQUEST; } _this._credentials = null; _this.onAuthStateChange.dispatch(_this); return _fsmStep(); }); case DropboxClient.REQUEST: if (!interactive) { if (callback) { callback(null, _this); } return; } authUrl = _this.authorizeUrl(_this.oauth.token); return _this.driver.doAuthorize(authUrl, _this.oauth.token, _this.oauth.tokenSecret, function() { _this.authState = DropboxClient.AUTHORIZED; _this._credentials = null; _this.onAuthStateChange.dispatch(_this); return _fsmStep(); }); case DropboxClient.AUTHORIZED: return _this.getAccessToken(function(error, data) { if (error) { _this.authError = error; _this.authState = DropboxClient.ERROR; } else { _this.oauth.setToken(data.oauth_token, data.oauth_token_secret); _this.uid = data.uid; _this.authState = DropboxClient.DONE; } _this._credentials = null; _this.onAuthStateChange.dispatch(_this); return _fsmStep(); }); case DropboxClient.DONE: if (callback) { callback(null, _this); } break; case DropboxClient.SIGNED_OFF: _this.authState = DropboxClient.RESET; _this.reset(); return _fsmStep(); case DropboxClient.ERROR: if (callback) { callback(_this.authError, _this); } } }; _fsmStep(); return this; }; Client.prototype.isAuthenticated = function() { return this.authState === DropboxClient.DONE; }; Client.prototype.signOut = function(callback) { var xhr, _this = this; xhr = new Dropbox.Xhr('POST', this.urls.signOut); xhr.signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error) { if (error) { if (callback) { callback(error); } return; } _this.authState = DropboxClient.RESET; _this.reset(); _this.authState = DropboxClient.SIGNED_OFF; _this.onAuthStateChange.dispatch(_this); if (_this.driver && _this.driver.onAuthStateChange) { return _this.driver.onAuthStateChange(_this, function() { if (callback) { return callback(error); } }); } else { if (callback) { return callback(error); } } }); }; Client.prototype.signOff = function(callback) { return this.signOut(callback); }; Client.prototype.getUserInfo = function(options, callback) { var httpCache, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } httpCache = false; if (options && options.httpCache) { httpCache = true; } xhr = new Dropbox.Xhr('GET', this.urls.accountInfo); xhr.signWithOauth(this.oauth, httpCache); return this.dispatchXhr(xhr, function(error, userData) { return callback(error, Dropbox.UserInfo.parse(userData), userData); }); }; Client.prototype.readFile = function(path, options, callback) { var httpCache, params, rangeEnd, rangeHeader, rangeStart, responseType, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } params = {}; responseType = 'text'; rangeHeader = null; httpCache = false; if (options) { if (options.versionTag) { params.rev = options.versionTag; } else if (options.rev) { params.rev = options.rev; } if (options.arrayBuffer) { responseType = 'arraybuffer'; } else if (options.blob) { responseType = 'blob'; } else if (options.buffer) { responseType = 'buffer'; } else if (options.binary) { responseType = 'b'; } if (options.length) { if (options.start != null) { rangeStart = options.start; rangeEnd = options.start + options.length - 1; } else { rangeStart = ''; rangeEnd = options.length; } rangeHeader = "bytes=" + rangeStart + "-" + rangeEnd; } else if (options.start != null) { rangeHeader = "bytes=" + options.start + "-"; } if (options.httpCache) { httpCache = true; } } xhr = new Dropbox.Xhr('GET', "" + this.urls.getFile + "/" + (this.urlEncodePath(path))); xhr.setParams(params).signWithOauth(this.oauth, httpCache); xhr.setResponseType(responseType); if (rangeHeader) { if (rangeHeader) { xhr.setHeader('Range', rangeHeader); } xhr.reportResponseHeaders(); } return this.dispatchXhr(xhr, function(error, data, metadata, headers) { var rangeInfo; if (headers) { rangeInfo = Dropbox.RangeInfo.parse(headers['content-range']); } else { rangeInfo = null; } return callback(error, data, Dropbox.Stat.parse(metadata), rangeInfo); }); }; Client.prototype.writeFile = function(path, data, options, callback) { var useForm; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } useForm = Dropbox.Xhr.canSendForms && typeof data === 'object'; if (useForm) { return this.writeFileUsingForm(path, data, options, callback); } else { return this.writeFileUsingPut(path, data, options, callback); } }; Client.prototype.writeFileUsingForm = function(path, data, options, callback) { var fileName, params, slashIndex, xhr; slashIndex = path.lastIndexOf('/'); if (slashIndex === -1) { fileName = path; path = ''; } else { fileName = path.substring(slashIndex); path = path.substring(0, slashIndex); } params = { file: fileName }; if (options) { if (options.noOverwrite) { params.overwrite = 'false'; } if (options.lastVersionTag) { params.parent_rev = options.lastVersionTag; } else if (options.parentRev || options.parent_rev) { params.parent_rev = options.parentRev || options.parent_rev; } } xhr = new Dropbox.Xhr('POST', "" + this.urls.postFile + "/" + (this.urlEncodePath(path))); xhr.setParams(params).signWithOauth(this.oauth).setFileField('file', fileName, data, 'application/octet-stream'); delete params.file; return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.writeFileUsingPut = function(path, data, options, callback) { var params, xhr; params = {}; if (options) { if (options.noOverwrite) { params.overwrite = 'false'; } if (options.lastVersionTag) { params.parent_rev = options.lastVersionTag; } else if (options.parentRev || options.parent_rev) { params.parent_rev = options.parentRev || options.parent_rev; } } xhr = new Dropbox.Xhr('POST', "" + this.urls.putFile + "/" + (this.urlEncodePath(path))); xhr.setBody(data).setParams(params).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.resumableUploadStep = function(data, cursor, callback) { var params, xhr; if (cursor) { params = { offset: cursor.offset }; if (cursor.tag) { params.upload_id = cursor.tag; } } else { params = { offset: 0 }; } xhr = new Dropbox.Xhr('POST', this.urls.chunkedUpload); xhr.setBody(data).setParams(params).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, cursor) { if (error && error.status === Dropbox.ApiError.INVALID_PARAM && error.response && error.response.upload_id && error.response.offset) { return callback(null, Dropbox.UploadCursor.parse(error.response)); } else { return callback(error, Dropbox.UploadCursor.parse(cursor)); } }); }; Client.prototype.resumableUploadFinish = function(path, cursor, options, callback) { var params, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } params = { upload_id: cursor.tag }; if (options) { if (options.lastVersionTag) { params.parent_rev = options.lastVersionTag; } else if (options.parentRev || options.parent_rev) { params.parent_rev = options.parentRev || options.parent_rev; } if (options.noOverwrite) { params.overwrite = 'false'; } } xhr = new Dropbox.Xhr('POST', "" + this.urls.commitChunkedUpload + "/" + (this.urlEncodePath(path))); xhr.setParams(params).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.stat = function(path, options, callback) { var httpCache, params, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } params = {}; httpCache = false; if (options) { if (options.version != null) { params.rev = options.version; } if (options.removed || options.deleted) { params.include_deleted = 'true'; } if (options.readDir) { params.list = 'true'; if (options.readDir !== true) { params.file_limit = options.readDir.toString(); } } if (options.cacheHash) { params.hash = options.cacheHash; } if (options.httpCache) { httpCache = true; } } params.include_deleted || (params.include_deleted = 'false'); params.list || (params.list = 'false'); xhr = new Dropbox.Xhr('GET', "" + this.urls.metadata + "/" + (this.urlEncodePath(path))); xhr.setParams(params).signWithOauth(this.oauth, httpCache); return this.dispatchXhr(xhr, function(error, metadata) { var entries, entry, stat; stat = Dropbox.Stat.parse(metadata); if (metadata != null ? metadata.contents : void 0) { entries = (function() { var _i, _len, _ref, _results; _ref = metadata.contents; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { entry = _ref[_i]; _results.push(Dropbox.Stat.parse(entry)); } return _results; })(); } else { entries = void 0; } return callback(error, stat, entries); }); }; Client.prototype.readdir = function(path, options, callback) { var statOptions; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } statOptions = { readDir: true }; if (options) { if (options.limit != null) { statOptions.readDir = options.limit; } if (options.versionTag) { statOptions.versionTag = options.versionTag; } if (options.removed || options.deleted) { statOptions.removed = options.removed || options.deleted; } if (options.httpCache) { statOptions.httpCache = options.httpCache; } } return this.stat(path, statOptions, function(error, stat, entry_stats) { var entries, entry_stat; if (entry_stats) { entries = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = entry_stats.length; _i < _len; _i++) { entry_stat = entry_stats[_i]; _results.push(entry_stat.name); } return _results; })(); } else { entries = null; } return callback(error, entries, stat, entry_stats); }); }; Client.prototype.metadata = function(path, options, callback) { return this.stat(path, options, callback); }; Client.prototype.makeUrl = function(path, options, callback) { var isDirect, params, url, useDownloadHack, xhr, _this = this; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } if (options && (options['long'] || options.longUrl || options.downloadHack)) { params = { short_url: 'false' }; } else { params = {}; } path = this.urlEncodePath(path); url = "" + this.urls.shares + "/" + path; isDirect = false; useDownloadHack = false; if (options) { if (options.downloadHack) { isDirect = true; useDownloadHack = true; } else if (options.download) { isDirect = true; url = "" + this.urls.media + "/" + path; } } xhr = new Dropbox.Xhr('POST', url).setParams(params).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, urlData) { if (useDownloadHack && (urlData != null ? urlData.url : void 0)) { urlData.url = urlData.url.replace(_this.authServer, _this.downloadServer); } return callback(error, Dropbox.PublicUrl.parse(urlData, isDirect)); }); }; Client.prototype.history = function(path, options, callback) { var httpCache, params, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } params = {}; httpCache = false; if (options) { if (options.limit != null) { params.rev_limit = options.limit; } if (options.httpCache) { httpCache = true; } } xhr = new Dropbox.Xhr('GET', "" + this.urls.revisions + "/" + (this.urlEncodePath(path))); xhr.setParams(params).signWithOauth(this.oauth, httpCache); return this.dispatchXhr(xhr, function(error, versions) { var metadata, stats; if (versions) { stats = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = versions.length; _i < _len; _i++) { metadata = versions[_i]; _results.push(Dropbox.Stat.parse(metadata)); } return _results; })(); } else { stats = void 0; } return callback(error, stats); }); }; Client.prototype.revisions = function(path, options, callback) { return this.history(path, options, callback); }; Client.prototype.thumbnailUrl = function(path, options) { var xhr; xhr = this.thumbnailXhr(path, options); return xhr.paramsToUrl().url; }; Client.prototype.readThumbnail = function(path, options, callback) { var responseType, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } responseType = 'b'; if (options) { if (options.blob) { responseType = 'blob'; } if (options.arrayBuffer) { responseType = 'arraybuffer'; } if (options.buffer) { responseType = 'buffer'; } } xhr = this.thumbnailXhr(path, options); xhr.setResponseType(responseType); return this.dispatchXhr(xhr, function(error, data, metadata) { return callback(error, data, Dropbox.Stat.parse(metadata)); }); }; Client.prototype.thumbnailXhr = function(path, options) { var params, xhr; params = {}; if (options) { if (options.format) { params.format = options.format; } else if (options.png) { params.format = 'png'; } if (options.size) { params.size = options.size; } } xhr = new Dropbox.Xhr('GET', "" + this.urls.thumbnails + "/" + (this.urlEncodePath(path))); return xhr.setParams(params).signWithOauth(this.oauth); }; Client.prototype.revertFile = function(path, versionTag, callback) { var xhr; xhr = new Dropbox.Xhr('POST', "" + this.urls.restore + "/" + (this.urlEncodePath(path))); xhr.setParams({ rev: versionTag }).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.restore = function(path, versionTag, callback) { return this.revertFile(path, versionTag, callback); }; Client.prototype.findByName = function(path, namePattern, options, callback) { var httpCache, params, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } params = { query: namePattern }; httpCache = false; if (options) { if (options.limit != null) { params.file_limit = options.limit; } if (options.removed || options.deleted) { params.include_deleted = true; } if (options.httpCache) { httpCache = true; } } xhr = new Dropbox.Xhr('GET', "" + this.urls.search + "/" + (this.urlEncodePath(path))); xhr.setParams(params).signWithOauth(this.oauth, httpCache); return this.dispatchXhr(xhr, function(error, results) { var metadata, stats; if (results) { stats = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = results.length; _i < _len; _i++) { metadata = results[_i]; _results.push(Dropbox.Stat.parse(metadata)); } return _results; })(); } else { stats = void 0; } return callback(error, stats); }); }; Client.prototype.search = function(path, namePattern, options, callback) { return this.findByName(path, namePattern, options, callback); }; Client.prototype.makeCopyReference = function(path, callback) { var xhr; xhr = new Dropbox.Xhr('GET', "" + this.urls.copyRef + "/" + (this.urlEncodePath(path))); xhr.signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, refData) { return callback(error, Dropbox.CopyReference.parse(refData)); }); }; Client.prototype.copyRef = function(path, callback) { return this.makeCopyReference(path, callback); }; Client.prototype.pullChanges = function(cursor, callback) { var params, xhr; if ((!callback) && (typeof cursor === 'function')) { callback = cursor; cursor = null; } if (cursor) { if (cursor.cursorTag) { params = { cursor: cursor.cursorTag }; } else { params = { cursor: cursor }; } } else { params = {}; } xhr = new Dropbox.Xhr('POST', this.urls.delta); xhr.setParams(params).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, deltaInfo) { return callback(error, Dropbox.PulledChanges.parse(deltaInfo)); }); }; Client.prototype.delta = function(cursor, callback) { return this.pullChanges(cursor, callback); }; Client.prototype.mkdir = function(path, callback) { var xhr; xhr = new Dropbox.Xhr('POST', this.urls.fileopsCreateFolder); xhr.setParams({ root: this.fileRoot, path: this.normalizePath(path) }).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.remove = function(path, callback) { var xhr; xhr = new Dropbox.Xhr('POST', this.urls.fileopsDelete); xhr.setParams({ root: this.fileRoot, path: this.normalizePath(path) }).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.unlink = function(path, callback) { return this.remove(path, callback); }; Client.prototype["delete"] = function(path, callback) { return this.remove(path, callback); }; Client.prototype.copy = function(from, toPath, callback) { var options, params, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } params = { root: this.fileRoot, to_path: this.normalizePath(toPath) }; if (from instanceof Dropbox.CopyReference) { params.from_copy_ref = from.tag; } else { params.from_path = this.normalizePath(from); } xhr = new Dropbox.Xhr('POST', this.urls.fileopsCopy); xhr.setParams(params).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.move = function(fromPath, toPath, callback) { var options, xhr; if ((!callback) && (typeof options === 'function')) { callback = options; options = null; } xhr = new Dropbox.Xhr('POST', this.urls.fileopsMove); xhr.setParams({ root: this.fileRoot, from_path: this.normalizePath(fromPath), to_path: this.normalizePath(toPath) }).signWithOauth(this.oauth); return this.dispatchXhr(xhr, function(error, metadata) { if (callback) { return callback(error, Dropbox.Stat.parse(metadata)); } }); }; Client.prototype.reset = function() { var oldAuthState; this.uid = null; this.oauth.setToken(null, ''); oldAuthState = this.authState; this.authState = DropboxClient.RESET; if (oldAuthState !== this.authState) { this.onAuthStateChange.dispatch(this); } this.authError = null; this._credentials = null; return this; }; Client.prototype.setCredentials = function(credentials) { var oldAuthState; oldAuthState = this.authState; this.oauth.reset(credentials); this.uid = credentials.uid || null; if (credentials.authState) { this.authState = credentials.authState; } else { if (credentials.token) { this.authState = DropboxClient.DONE; } else { this.authState = DropboxClient.RESET; } } this.authError = null; this._credentials = null; if (oldAuthState !== this.authState) { this.onAuthStateChange.dispatch(this); } return this; }; Client.prototype.appHash = function() { return this.oauth.appHash(); }; Client.prototype.setupUrls = function() { this.fileRoot = this.sandbox ? 'sandbox' : 'dropbox'; return this.urls = { requestToken: "" + this.apiServer + "/1/oauth/request_token", authorize: "" + this.authServer + "/1/oauth/authorize", accessToken: "" + this.apiServer + "/1/oauth/access_token", signOut: "" + this.apiServer + "/1/unlink_access_token", accountInfo: "" + this.apiServer + "/1/account/info", getFile: "" + this.fileServer + "/1/files/" + this.fileRoot, postFile: "" + this.fileServer + "/1/files/" + this.fileRoot, putFile: "" + this.fileServer + "/1/files_put/" + this.fileRoot, metadata: "" + this.apiServer + "/1/metadata/" + this.fileRoot, delta: "" + this.apiServer + "/1/delta", revisions: "" + this.apiServer + "/1/revisions/" + this.fileRoot, restore: "" + this.apiServer + "/1/restore/" + this.fileRoot, search: "" + this.apiServer + "/1/search/" + this.fileRoot, shares: "" + this.apiServer + "/1/shares/" + this.fileRoot, media: "" + this.apiServer + "/1/media/" + this.fileRoot, copyRef: "" + this.apiServer + "/1/copy_ref/" + this.fileRoot, thumbnails: "" + this.fileServer + "/1/thumbnails/" + this.fileRoot, chunkedUpload: "" + this.fileServer + "/1/chunked_upload", commitChunkedUpload: "" + this.fileServer + "/1/commit_chunked_upload/" + this.fileRoot, fileopsCopy: "" + this.apiServer + "/1/fileops/copy", fileopsCreateFolder: "" + this.apiServer + "/1/fileops/create_folder", fileopsDelete: "" + this.apiServer + "/1/fileops/delete", fileopsMove: "" + this.apiServer + "/1/fileops/move" }; }; Client.prototype.authState = null; Client.ERROR = 0; Client.RESET = 1; Client.REQUEST = 2; Client.AUTHORIZED = 3; Client.DONE = 4; Client.SIGNED_OFF = 5; Client.prototype.urlEncodePath = function(path) { return Dropbox.Xhr.urlEncodeValue(this.normalizePath(path)).replace(/%2F/gi, '/'); }; Client.prototype.normalizePath = function(path) { var i; if (path.substring(0, 1) === '/') { i = 1; while (path.substring(i, i + 1) === '/') { i += 1; } return path.substring(i); } else { return path; } }; Client.prototype.requestToken = function(callback) { var xhr; xhr = new Dropbox.Xhr('POST', this.urls.requestToken).signWithOauth(this.oauth); return this.dispatchXhr(xhr, callback); }; Client.prototype.authorizeUrl = function(token) { var callbackUrl, params; callbackUrl = this.driver.url(token); if (callbackUrl === null) { params = { oauth_token: token }; } else { params = { oauth_token: token, oauth_callback: callbackUrl }; } return ("" + this.urls.authorize + "?") + Dropbox.Xhr.urlEncode(params); }; Client.prototype.getAccessToken = function(callback) { var xhr; xhr = new Dropbox.Xhr('POST', this.urls.accessToken).signWithOauth(this.oauth); return this.dispatchXhr(xhr, callback); }; Client.prototype.dispatchXhr = function(xhr, callback) { var nativeXhr; xhr.setCallback(callback); xhr.onError = this.xhrOnErrorHandler; xhr.prepare(); nativeXhr = xhr.xhr; if (this.onXhr.dispatch(xhr)) { xhr.send(); } return nativeXhr; }; Client.prototype.handleXhrError = function(error, callback) { var _this = this; if (error.status === Dropbox.ApiError.INVALID_TOKEN && this.authState === DropboxClient.DONE) { this.authError = error; this.authState = DropboxClient.ERROR; this.onAuthStateChange.dispatch(this); if (this.driver && this.driver.onAuthStateChange) { this.driver.onAuthStateChange(this, function() { _this.onError.dispatch(error); return callback(error); }); return null; } } this.onError.dispatch(error); callback(error); return null; }; Client.prototype.defaultApiServer = function() { return 'https://api.dropbox.com'; }; Client.prototype.defaultAuthServer = function() { return this.apiServer.replace('api.', 'www.'); }; Client.prototype.defaultFileServer = function() { return this.apiServer.replace('api.', 'api-content.'); }; Client.prototype.defaultDownloadServer = function() { return this.apiServer.replace('api.', 'dl.'); }; Client.prototype.computeCredentials = function() { var value; value = { key: this.oauth.key, sandbox: this.sandbox }; if (this.oauth.secret) { value.secret = this.oauth.secret; } if (this.oauth.token) { value.token = this.oauth.token; value.tokenSecret = this.oauth.tokenSecret; } if (this.uid) { value.uid = this.uid; } if (this.authState !== DropboxClient.ERROR && this.authState !== DropboxClient.RESET && this.authState !== DropboxClient.DONE && this.authState !== DropboxClient.SIGNED_OFF) { value.authState = this.authState; } if (this.apiServer !== this.defaultApiServer()) { value.server = this.apiServer; } if (this.authServer !== this.defaultAuthServer()) { value.authServer = this.authServer; } if (this.fileServer !== this.defaultFileServer()) { value.fileServer = this.fileServer; } if (this.downloadServer !== this.defaultDownloadServer()) { value.downloadServer = this.downloadServer; } return this._credentials = value; }; return Client; })(); DropboxClient = Dropbox.Client; Dropbox.Drivers.BrowserBase = (function() { function BrowserBase(options) { this.rememberUser = (options != null ? options.rememberUser : void 0) || false; this.useQuery = (options != null ? options.useQuery : void 0) || false; this.scope = (options != null ? options.scope : void 0) || 'default'; this.storageKey = null; this.dbTokenRe = new RegExp("(#|\\?|&)dboauth_token=([^&#]+)(&|#|$)"); this.rejectedRe = new RegExp("(#|\\?|&)not_approved=true(&|#|$)"); this.tokenRe = new RegExp("(#|\\?|&)oauth_token=([^&#]+)(&|#|$)"); } BrowserBase.prototype.onAuthStateChange = function(client, callback) { var _this = this; this.setStorageKey(client); switch (client.authState) { case DropboxClient.RESET: return this.loadCredentials(function(credentials) { if (!credentials) { return callback(); } if (credentials.authState) { client.setCredentials(credentials); return callback(); } if (!_this.rememberUser) { return _this.forgetCredentials(callback); } client.setCredentials(credentials); return client.getUserInfo(function(error) { if (error) { client.reset(); return _this.forgetCredentials(callback); } else { return callback(); } }); }); case DropboxClient.REQUEST: return this.storeCredentials(client.credentials(), callback); case DropboxClient.DONE: if (this.rememberUser) { return this.storeCredentials(client.credentials(), callback); } return this.forgetCredentials(callback); case DropboxClient.SIGNED_OFF: return this.forgetCredentials(callback); case DropboxClient.ERROR: return this.forgetCredentials(callback); default: callback(); return this; } }; BrowserBase.prototype.setStorageKey = function(client) { this.storageKey = "dropbox-auth:" + this.scope + ":" + (client.appHash()); return this; }; BrowserBase.prototype.storeCredentials = function(credentials, callback) { localStorage.setItem(this.storageKey, JSON.stringify(credentials)); callback(); return this; }; BrowserBase.prototype.loadCredentials = function(callback) { var jsonError, jsonString; jsonString = localStorage.getItem(this.storageKey); if (!jsonString) { callback(null); return this; } try { callback(JSON.parse(jsonString)); } catch (_error) { jsonError = _error; callback(null); } return this; }; BrowserBase.prototype.forgetCredentials = function(callback) { localStorage.removeItem(this.storageKey); callback(); return this; }; BrowserBase.prototype.computeUrl = function(baseUrl) { var fragment, location, locationPair, querySuffix; querySuffix = "_dropboxjs_scope=" + (encodeURIComponent(this.scope)) + "&dboauth_token="; location = baseUrl; if (location.indexOf('#') === -1) { fragment = null; } else { locationPair = location.split('#', 2); location = locationPair[0]; fragment = locationPair[1]; } if (this.useQuery) { if (location.indexOf('?') === -1) { location += "?" + querySuffix; } else { location += "&" + querySuffix; } if (fragment) { return [location, '#' + fragment]; } else { return [location, '']; } } else { return [location + '#?' + querySuffix, '']; } }; BrowserBase.prototype.locationToken = function(url) { var location, match, scopePattern; location = url || Dropbox.Drivers.BrowserBase.currentLocation(); scopePattern = "_dropboxjs_scope=" + (encodeURIComponent(this.scope)) + "&"; if ((typeof location.indexOf === "function" ? location.indexOf(scopePattern) : void 0) === -1) { return null; } if (this.rejectedRe.test(location)) { match = this.dbTokenRe.exec(location); if (match) { return decodeURIComponent(match[2]); } else { return null; } } match = this.tokenRe.exec(location); if (match) { return decodeURIComponent(match[2]); } return null; }; BrowserBase.currentLocation = function() { return window.location.href; }; return BrowserBase; })(); Dropbox.Drivers.Redirect = (function(_super) { __extends(Redirect, _super); function Redirect(options) { var _ref; Redirect.__super__.constructor.call(this, options); _ref = this.computeUrl(Dropbox.Drivers.BrowserBase.currentLocation()), this.receiverUrl1 = _ref[0], this.receiverUrl2 = _ref[1]; } Redirect.prototype.onAuthStateChange = function(client, callback) { var superCall, _this = this; superCall = (function() { return function() { return Redirect.__super__.onAuthStateChange.call(_this, client, callback); }; })(); this.setStorageKey(client); if (client.authState === DropboxClient.RESET) { return this.loadCredentials(function(credentials) { if (credentials && credentials.authState) { if (credentials.token === _this.locationToken() && credentials.authState === DropboxClient.REQUEST) { credentials.authState = DropboxClient.AUTHORIZED; return _this.storeCredentials(credentials, superCall); } else { return _this.forgetCredentials(superCall); } } return superCall(); }); } else { return superCall(); } }; Redirect.prototype.url = function(token) { return this.receiverUrl1 + encodeURIComponent(token) + this.receiverUrl2; }; Redirect.prototype.doAuthorize = function(authUrl) { return window.location.assign(authUrl); }; return Redirect; })(Dropbox.Drivers.BrowserBase); Dropbox.Drivers.Popup = (function(_super) { __extends(Popup, _super); function Popup(options) { var _ref; Popup.__super__.constructor.call(this, options); _ref = this.computeUrl(this.baseUrl(options)), this.receiverUrl1 = _ref[0], this.receiverUrl2 = _ref[1]; } Popup.prototype.onAuthStateChange = function(client, callback) { var superCall, _this = this; superCall = (function() { return function() { return Popup.__super__.onAuthStateChange.call(_this, client, callback); }; })(); this.setStorageKey(client); if (client.authState === DropboxClient.RESET) { return this.loadCredentials(function(credentials) { if (credentials && credentials.authState) { return _this.forgetCredentials(superCall); } return superCall(); }); } else { return superCall(); } }; Popup.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { this.listenForMessage(token, callback); return this.openWindow(authUrl); }; Popup.prototype.url = function(token) { return this.receiverUrl1 + encodeURIComponent(token) + this.receiverUrl2; }; Popup.prototype.baseUrl = function(options) { var fragments; if (options) { if (options.receiverUrl) { return options.receiverUrl; } else if (options.receiverFile) { fragments = Dropbox.Drivers.BrowserBase.currentLocation().split('/'); fragments[fragments.length - 1] = options.receiverFile; return fragments.join('/'); } } return Dropbox.Drivers.BrowserBase.currentLocation(); }; Popup.prototype.openWindow = function(url) { return window.open(url, '_dropboxOauthSigninWindow', this.popupWindowSpec(980, 700)); }; Popup.prototype.popupWindowSpec = function(popupWidth, popupHeight) { var height, popupLeft, popupTop, width, x0, y0, _ref, _ref1, _ref2, _ref3; x0 = (_ref = window.screenX) != null ? _ref : window.screenLeft; y0 = (_ref1 = window.screenY) != null ? _ref1 : window.screenTop; width = (_ref2 = window.outerWidth) != null ? _ref2 : document.documentElement.clientWidth; height = (_ref3 = window.outerHeight) != null ? _ref3 : document.documentElement.clientHeight; popupLeft = Math.round(x0 + (width - popupWidth) / 2); popupTop = Math.round(y0 + (height - popupHeight) / 2.5); if (popupLeft < x0) { popupLeft = x0; } if (popupTop < y0) { popupTop = y0; } return ("width=" + popupWidth + ",height=" + popupHeight + ",") + ("left=" + popupLeft + ",top=" + popupTop) + 'dialog=yes,dependent=yes,scrollbars=yes,location=yes'; }; Popup.prototype.listenForMessage = function(token, callback) { var listener, _this = this; listener = function(event) { var data; if (event.data) { data = event.data; } else { data = event; } if (_this.locationToken(data) === token) { token = null; window.removeEventListener('message', listener); Dropbox.Drivers.Popup.onMessage.removeListener(listener); return callback(); } }; window.addEventListener('message', listener, false); return Dropbox.Drivers.Popup.onMessage.addListener(listener); }; Popup.oauthReceiver = function() { return window.addEventListener('load', function() { var frameError, ieError, opener; opener = window.opener; if (window.parent !== window.top) { opener || (opener = window.parent); } if (opener) { try { opener.postMessage(window.location.href, '*'); } catch (_error) { ieError = _error; } try { opener.Dropbox.Drivers.Popup.onMessage.dispatch(window.location.href); } catch (_error) { frameError = _error; } } return window.close(); }); }; Popup.onMessage = new Dropbox.EventSource; return Popup; })(Dropbox.Drivers.BrowserBase); DropboxChromeOnMessage = null; DropboxChromeSendMessage = null; if (typeof chrome !== "undefined" && chrome !== null) { if (chrome.runtime) { if (chrome.runtime.onMessage) { DropboxChromeOnMessage = chrome.runtime.onMessage; } if (chrome.runtime.sendMessage) { DropboxChromeSendMessage = function(m) { return chrome.runtime.sendMessage(m); }; } } if (chrome.extension) { if (chrome.extension.onMessage) { DropboxChromeOnMessage || (DropboxChromeOnMessage = chrome.extension.onMessage); } if (chrome.extension.sendMessage) { DropboxChromeSendMessage || (DropboxChromeSendMessage = function(m) { return chrome.extension.sendMessage(m); }); } } if (!DropboxChromeOnMessage) { (function() { var page, pageHack; pageHack = function(page) { if (page.Dropbox) { Dropbox.Drivers.Chrome.prototype.onMessage = page.Dropbox.Drivers.Chrome.onMessage; return Dropbox.Drivers.Chrome.prototype.sendMessage = page.Dropbox.Drivers.Chrome.sendMessage; } else { page.Dropbox = Dropbox; Dropbox.Drivers.Chrome.prototype.onMessage = new Dropbox.EventSource; return Dropbox.Drivers.Chrome.prototype.sendMessage = function(m) { return Dropbox.Drivers.Chrome.prototype.onMessage.dispatch(m); }; } }; if (chrome.extension && chrome.extension.getBackgroundPage) { if (page = chrome.extension.getBackgroundPage()) { return pageHack(page); } } if (chrome.runtime && chrome.runtime.getBackgroundPage) { return chrome.runtime.getBackgroundPage(function(page) { return pageHack(page); }); } })(); } } Dropbox.Drivers.Chrome = (function(_super) { __extends(Chrome, _super); Chrome.prototype.onMessage = DropboxChromeOnMessage; Chrome.prototype.sendMessage = DropboxChromeSendMessage; Chrome.prototype.expandUrl = function(url) { if (chrome.runtime && chrome.runtime.getURL) { return chrome.runtime.getURL(url); } if (chrome.extension && chrome.extension.getURL) { return chrome.extension.getURL(url); } return url; }; function Chrome(options) { var receiverPath, _ref; Chrome.__super__.constructor.call(this, options); receiverPath = (options && options.receiverPath) || 'chrome_oauth_receiver.html'; this.rememberUser = true; this.useQuery = true; _ref = this.computeUrl(this.expandUrl(receiverPath)), this.receiverUrl = _ref[0], this.receiverUrl2 = _ref[1]; this.storageKey = "dropbox_js_" + this.scope + "_credentials"; } Chrome.prototype.onAuthStateChange = function(client, callback) { var _this = this; switch (client.authState) { case Dropbox.Client.RESET: return this.loadCredentials(function(credentials) { if (credentials) { if (credentials.authState) { return _this.forgetCredentials(callback); } client.setCredentials(credentials); } return callback(); }); case Dropbox.Client.DONE: return this.storeCredentials(client.credentials(), callback); case Dropbox.Client.SIGNED_OFF: return this.forgetCredentials(callback); case Dropbox.Client.ERROR: return this.forgetCredentials(callback); default: return callback(); } }; Chrome.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { var window, _ref, _ref1, _ref2, _this = this; if ((_ref = chrome.identity) != null ? _ref.launchWebAuthFlow : void 0) { return chrome.identity.launchWebAuthFlow({ url: authUrl, interactive: true }, function(redirectUrl) { if (_this.locationToken(redirectUrl) === token) { return callback(); } }); } else if ((_ref1 = chrome.experimental) != null ? (_ref2 = _ref1.identity) != null ? _ref2.launchWebAuthFlow : void 0 : void 0) { return chrome.experimental.identity.launchWebAuthFlow({ url: authUrl, interactive: true }, function(redirectUrl) { if (_this.locationToken(redirectUrl) === token) { return callback(); } }); } else { window = { handle: null }; this.listenForMessage(token, window, callback); return this.openWindow(authUrl, function(handle) { return window.handle = handle; }); } }; Chrome.prototype.openWindow = function(url, callback) { if (chrome.tabs && chrome.tabs.create) { chrome.tabs.create({ url: url, active: true, pinned: false }, function(tab) { return callback(tab); }); return this; } return this; }; Chrome.prototype.closeWindow = function(handle) { if (chrome.tabs && chrome.tabs.remove && handle.id) { chrome.tabs.remove(handle.id); return this; } if (chrome.app && chrome.app.window && handle.close) { handle.close(); return this; } return this; }; Chrome.prototype.url = function(token) { return this.receiverUrl + encodeURIComponent(token); }; Chrome.prototype.listenForMessage = function(token, window, callback) { var listener, _this = this; listener = function(message, sender) { if (sender && sender.tab) { if (sender.tab.url.substring(0, _this.receiverUrl.length) !== _this.receiverUrl) { return; } } if (!message.dropbox_oauth_receiver_href) { return; } if (_this.locationToken(message.dropbox_oauth_receiver_href) === token) { if (window.handle) { _this.closeWindow(window.handle); } _this.onMessage.removeListener(listener); return callback(); } }; return this.onMessage.addListener(listener); }; Chrome.prototype.storeCredentials = function(credentials, callback) { var items; items = {}; items[this.storageKey] = credentials; chrome.storage.local.set(items, callback); return this; }; Chrome.prototype.loadCredentials = function(callback) { var _this = this; chrome.storage.local.get(this.storageKey, function(items) { return callback(items[_this.storageKey] || null); }); return this; }; Chrome.prototype.forgetCredentials = function(callback) { chrome.storage.local.remove(this.storageKey, callback); return this; }; Chrome.oauthReceiver = function() { return window.addEventListener('load', function() { var driver; driver = new Dropbox.Drivers.Chrome(); driver.sendMessage({ dropbox_oauth_receiver_href: window.location.href }); if (window.close) { return window.close(); } }); }; return Chrome; })(Dropbox.Drivers.BrowserBase); Dropbox.Drivers.Cordova = (function(_super) { __extends(Cordova, _super); function Cordova(options) { this.rememberUser = (options != null ? options.rememberUser : void 0) || false; this.scope = (options != null ? options.scope : void 0) || 'default'; } Cordova.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { var authHost, browser, onEvent, promptPageLoaded; browser = window.open(authUrl, '_blank', 'location=yes'); promptPageLoaded = false; authHost = /^[^/]*\/\/[^/]*\//.exec(authUrl)[0]; onEvent = function(event) { if (event.url === authUrl && promptPageLoaded === false) { promptPageLoaded = true; return; } if (event.url && event.url.substring(0, authHost.length) !== authHost) { promptPageLoaded = false; return; } if (event.type === 'exit' || promptPageLoaded) { browser.removeEventListener('loadstop', onEvent); browser.removeEventListener('exit', onEvent); if (event.type !== 'exit') { browser.close(); } return callback(); } }; browser.addEventListener('loadstop', onEvent); return browser.addEventListener('exit', onEvent); }; Cordova.prototype.url = function() { return null; }; Cordova.prototype.onAuthStateChange = function(client, callback) { var superCall, _this = this; superCall = (function() { return function() { return Cordova.__super__.onAuthStateChange.call(_this, client, callback); }; })(); this.setStorageKey(client); if (client.authState === DropboxClient.RESET) { return this.loadCredentials(function(credentials) { if (credentials && credentials.authState) { return _this.forgetCredentials(superCall); } else { return superCall(); } }); } else { return superCall(); } }; return Cordova; })(Dropbox.Drivers.BrowserBase); Dropbox.Drivers.NodeServer = (function() { function NodeServer(options) { this.port = (options != null ? options.port : void 0) || 8912; this.faviconFile = (options != null ? options.favicon : void 0) || null; this.fs = require('fs'); this.http = require('http'); this.open = require('open'); this.callbacks = {}; this.nodeUrl = require('url'); this.createApp(); } NodeServer.prototype.url = function(token) { return ("http://localhost:" + this.port + "/oauth_callback?dboauth_token=") + encodeURIComponent(token); }; NodeServer.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { this.callbacks[token] = callback; return this.openBrowser(authUrl); }; NodeServer.prototype.openBrowser = function(url) { if (!url.match(/^https?:\/\//)) { throw new Error("Not a http/https URL: " + url); } if ('BROWSER' in process.env) { return this.open(url, process.env['BROWSER']); } else { return this.open(url); } }; NodeServer.prototype.createApp = function() { var _this = this; this.app = this.http.createServer(function(request, response) { return _this.doRequest(request, response); }); return this.app.listen(this.port); }; NodeServer.prototype.closeServer = function() { return this.app.close(); }; NodeServer.prototype.doRequest = function(request, response) { var data, rejected, token, url, _this = this; url = this.nodeUrl.parse(request.url, true); if (url.pathname === '/oauth_callback') { if (url.query.not_approved === 'true') { rejected = true; token = url.query.dboauth_token; } else { rejected = false; token = url.query.oauth_token; } if (this.callbacks[token]) { this.callbacks[token](rejected); delete this.callbacks[token]; } } data = ''; request.on('data', function(dataFragment) { return data += dataFragment; }); return request.on('end', function() { if (_this.faviconFile && (url.pathname === '/favicon.ico')) { return _this.sendFavicon(response); } else { return _this.closeBrowser(response); } }); }; NodeServer.prototype.closeBrowser = function(response) { var closeHtml; closeHtml = "\n\n

Please close this window.

"; response.writeHead(200, { 'Content-Length': closeHtml.length, 'Content-Type': 'text/html' }); response.write(closeHtml); return response.end(); }; NodeServer.prototype.sendFavicon = function(response) { return this.fs.readFile(this.faviconFile, function(error, data) { response.writeHead(200, { 'Content-Length': data.length, 'Content-Type': 'image/x-icon' }); response.write(data); return response.end(); }); }; return NodeServer; })(); base64HmacSha1 = function(string, key) { return arrayToBase64(hmacSha1(stringToArray(string), stringToArray(key), string.length, key.length)); }; base64Sha1 = function(string) { return arrayToBase64(sha1(stringToArray(string), string.length)); }; if (typeof require !== 'undefined') { try { crypto = require('crypto'); if (crypto.createHmac && crypto.createHash) { base64HmacSha1 = function(string, key) { var hmac; hmac = crypto.createHmac('sha1', key); hmac.update(string); return hmac.digest('base64'); }; base64Sha1 = function(string) { var hash; hash = crypto.createHash('sha1'); hash.update(string); return hash.digest('base64'); }; } } catch (_error) { requireError = _error; } } Dropbox.Util.hmac = base64HmacSha1; Dropbox.Util.sha1 = base64Sha1; hmacSha1 = function(string, key, length, keyLength) { var hash1, i, ipad, opad; if (key.length > 16) { key = sha1(key, keyLength); } ipad = (function() { var _i, _results; _results = []; for (i = _i = 0; _i < 16; i = ++_i) { _results.push(key[i] ^ 0x36363636); } return _results; })(); opad = (function() { var _i, _results; _results = []; for (i = _i = 0; _i < 16; i = ++_i) { _results.push(key[i] ^ 0x5C5C5C5C); } return _results; })(); hash1 = sha1(ipad.concat(string), 64 + length); return sha1(opad.concat(hash1), 64 + 20); }; sha1 = function(string, length) { var a, a0, b, b0, c, c0, d, d0, e, e0, ft, i, j, kt, limit, state, t, _i; string[length >> 2] |= 1 << (31 - ((length & 0x03) << 3)); string[(((length + 8) >> 6) << 4) + 15] = length << 3; state = Array(80); a = 1732584193; b = -271733879; c = -1732584194; d = 271733878; e = -1009589776; i = 0; limit = string.length; while (i < limit) { a0 = a; b0 = b; c0 = c; d0 = d; e0 = e; for (j = _i = 0; _i < 80; j = ++_i) { if (j < 16) { state[j] = string[i + j]; } else { state[j] = rotateLeft32(state[j - 3] ^ state[j - 8] ^ state[j - 14] ^ state[j - 16], 1); } if (j < 20) { ft = (b & c) | ((~b) & d); kt = 1518500249; } else if (j < 40) { ft = b ^ c ^ d; kt = 1859775393; } else if (j < 60) { ft = (b & c) | (b & d) | (c & d); kt = -1894007588; } else { ft = b ^ c ^ d; kt = -899497514; } t = add32(add32(rotateLeft32(a, 5), ft), add32(add32(e, state[j]), kt)); e = d; d = c; c = rotateLeft32(b, 30); b = a; a = t; } a = add32(a, a0); b = add32(b, b0); c = add32(c, c0); d = add32(d, d0); e = add32(e, e0); i += 16; } return [a, b, c, d, e]; }; /* # Uncomment the definition below for debugging. # # Returns the hexadecimal representation of a 32-bit number. xxx = (n) -> if n < 0 n = (1 << 30) * 4 + n n.toString 16 */ rotateLeft32 = function(value, count) { return (value << count) | (value >>> (32 - count)); }; add32 = function(a, b) { var high, low; low = (a & 0xFFFF) + (b & 0xFFFF); high = (a >> 16) + (b >> 16) + (low >> 16); return (high << 16) | (low & 0xFFFF); }; arrayToBase64 = function(array) { var i, i2, limit, string, trit; string = ""; i = 0; limit = array.length * 4; while (i < limit) { i2 = i; trit = ((array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF) << 16; i2 += 1; trit |= ((array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF) << 8; i2 += 1; trit |= (array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF; string += _base64Digits[(trit >> 18) & 0x3F]; string += _base64Digits[(trit >> 12) & 0x3F]; i += 1; if (i >= limit) { string += '='; } else { string += _base64Digits[(trit >> 6) & 0x3F]; } i += 1; if (i >= limit) { string += '='; } else { string += _base64Digits[trit & 0x3F]; } i += 1; } return string; }; _base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; stringToArray = function(string) { var array, i, mask, _i, _ref; array = []; mask = 0xFF; for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { array[i >> 2] |= (string.charCodeAt(i) & mask) << ((3 - (i & 3)) << 3); } return array; }; Dropbox.Oauth = (function() { function Oauth(options) { this.key = this.k = null; this.secret = this.s = null; this.token = null; this.tokenSecret = null; this._appHash = null; this.reset(options); } Oauth.prototype.reset = function(options) { var k, s, secret, _ref; if (options.secret) { this.k = this.key = options.key; this.s = this.secret = options.secret; this._appHash = null; } else if (options.key) { this.key = options.key; this.secret = null; secret = atob(dropboxEncodeKey(this.key).split('|', 2)[1]); _ref = secret.split('?', 2), k = _ref[0], s = _ref[1]; this.k = decodeURIComponent(k); this.s = decodeURIComponent(s); this._appHash = null; } else { if (!this.k) { throw new Error('No API key supplied'); } } if (options.token) { return this.setToken(options.token, options.tokenSecret); } else { return this.setToken(null, ''); } }; Oauth.prototype.setToken = function(token, tokenSecret) { if (token && (!tokenSecret)) { throw new Error('No secret supplied with the user token'); } this.token = token; this.tokenSecret = tokenSecret || ''; this.hmacKey = Dropbox.Xhr.urlEncodeValue(this.s) + '&' + Dropbox.Xhr.urlEncodeValue(tokenSecret); return null; }; Oauth.prototype.authHeader = function(method, url, params) { var header, oauth_params, param, value, _i, _len; this.addAuthParams(method, url, params); oauth_params = []; for (param in params) { value = params[param]; if (param.substring(0, 6) === 'oauth_') { oauth_params.push(param); } } oauth_params.sort(); header = []; for (_i = 0, _len = oauth_params.length; _i < _len; _i++) { param = oauth_params[_i]; header.push(Dropbox.Xhr.urlEncodeValue(param) + '="' + Dropbox.Xhr.urlEncodeValue(params[param]) + '"'); delete params[param]; } return 'OAuth ' + header.join(','); }; Oauth.prototype.addAuthParams = function(method, url, params) { this.boilerplateParams(params); params.oauth_signature = this.signature(method, url, params); return params; }; Oauth.prototype.boilerplateParams = function(params) { params.oauth_consumer_key = this.k; params.oauth_nonce = Dropbox.Oauth.nonce(); params.oauth_signature_method = 'HMAC-SHA1'; if (this.token) { params.oauth_token = this.token; } params.oauth_timestamp = Math.floor(Date.now() / 1000); params.oauth_version = '1.0'; return params; }; Oauth.nonce = function() { return Math.random().toString(36); }; Oauth.prototype.signature = function(method, url, params) { var string; string = method.toUpperCase() + '&' + Dropbox.Xhr.urlEncodeValue(url) + '&' + Dropbox.Xhr.urlEncodeValue(Dropbox.Xhr.urlEncode(params)); return base64HmacSha1(string, this.hmacKey); }; Oauth.prototype.appHash = function() { if (this._appHash) { return this._appHash; } return this._appHash = base64Sha1(this.k).replace(/\=/g, ''); }; return Oauth; })(); if (Date.now == null) { Date.now = function() { return (new Date()).getTime(); }; } dropboxEncodeKey = function(key, secret) { var i, k, result, s, x, y, z, _i, _j, _ref, _ref1, _results; if (secret) { secret = [encodeURIComponent(key), encodeURIComponent(secret)].join('?'); key = (function() { var _i, _ref, _results; _results = []; for (i = _i = 0, _ref = key.length / 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { _results.push(((key.charCodeAt(i * 2) & 15) * 16) + (key.charCodeAt(i * 2 + 1) & 15)); } return _results; })(); } else { _ref = key.split('|', 2), key = _ref[0], secret = _ref[1]; key = atob(key); key = (function() { var _i, _ref1, _results; _results = []; for (i = _i = 0, _ref1 = key.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) { _results.push(key.charCodeAt(i)); } return _results; })(); secret = atob(secret); } s = (function() { _results = []; for (_i = 0; _i < 256; _i++){ _results.push(_i); } return _results; }).apply(this); y = 0; for (x = _j = 0; _j < 256; x = ++_j) { y = (y + s[i] + key[x % key.length]) % 256; _ref1 = [s[y], s[x]], s[x] = _ref1[0], s[y] = _ref1[1]; } x = y = 0; result = (function() { var _k, _ref2, _ref3, _results1; _results1 = []; for (z = _k = 0, _ref2 = secret.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; z = 0 <= _ref2 ? ++_k : --_k) { x = (x + 1) % 256; y = (y + s[x]) % 256; _ref3 = [s[y], s[x]], s[x] = _ref3[0], s[y] = _ref3[1]; k = s[(s[x] + s[y]) % 256]; _results1.push(String.fromCharCode((k ^ secret.charCodeAt(z)) % 256)); } return _results1; })(); key = (function() { var _k, _ref2, _results1; _results1 = []; for (i = _k = 0, _ref2 = key.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; i = 0 <= _ref2 ? ++_k : --_k) { _results1.push(String.fromCharCode(key[i])); } return _results1; })(); return [btoa(key.join('')), btoa(result.join(''))].join('|'); }; Dropbox.Util.encodeKey = dropboxEncodeKey; Dropbox.PulledChanges = (function() { PulledChanges.parse = function(deltaInfo) { if (deltaInfo && typeof deltaInfo === 'object') { return new Dropbox.PulledChanges(deltaInfo); } else { return deltaInfo; } }; PulledChanges.prototype.blankSlate = void 0; PulledChanges.prototype.cursorTag = void 0; PulledChanges.prototype.changes = void 0; PulledChanges.prototype.shouldPullAgain = void 0; PulledChanges.prototype.shouldBackOff = void 0; PulledChanges.prototype.cursor = function() { return this.cursorTag; }; function PulledChanges(deltaInfo) { var entry; this.blankSlate = deltaInfo.reset || false; this.cursorTag = deltaInfo.cursor; this.shouldPullAgain = deltaInfo.has_more; this.shouldBackOff = !this.shouldPullAgain; if (deltaInfo.cursor && deltaInfo.cursor.length) { this.changes = (function() { var _i, _len, _ref, _results; _ref = deltaInfo.entries; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { entry = _ref[_i]; _results.push(Dropbox.PullChange.parse(entry)); } return _results; })(); } else { this.changes = []; } } return PulledChanges; })(); Dropbox.PullChange = (function() { PullChange.parse = function(entry) { if (entry && typeof entry === 'object') { return new Dropbox.PullChange(entry); } else { return entry; } }; PullChange.prototype.path = void 0; PullChange.prototype.wasRemoved = void 0; PullChange.prototype.stat = void 0; function PullChange(entry) { this.path = entry[0]; this.stat = Dropbox.Stat.parse(entry[1]); if (this.stat) { this.wasRemoved = false; } else { this.stat = null; this.wasRemoved = true; } } return PullChange; })(); Dropbox.RangeInfo = (function() { RangeInfo.parse = function(headerValue) { if (typeof headerValue === 'string') { return new Dropbox.RangeInfo(headerValue); } else { return headerValue; } }; RangeInfo.prototype.start = null; RangeInfo.prototype.size = null; RangeInfo.prototype.end = null; function RangeInfo(headerValue) { var match; if (match = /^bytes (\d*)-(\d*)\/(.*)$/.exec(headerValue)) { this.start = parseInt(match[1]); this.end = parseInt(match[2]); if (match[3] === '*') { this.size = null; } else { this.size = parseInt(match[3]); } } else { this.start = 0; this.end = 0; this.size = null; } } return RangeInfo; })(); Dropbox.PublicUrl = (function() { PublicUrl.parse = function(urlData, isDirect) { if (urlData && typeof urlData === 'object') { return new Dropbox.PublicUrl(urlData, isDirect); } else { return urlData; } }; PublicUrl.prototype.url = null; PublicUrl.prototype.expiresAt = null; PublicUrl.prototype.isDirect = null; PublicUrl.prototype.isPreview = null; PublicUrl.prototype.json = function() { return this._json || (this._json = { url: this.url, expires: this.expiresAt.toString(), direct: this.isDirect }); }; function PublicUrl(urlData, isDirect) { this.url = urlData.url; this.expiresAt = new Date(Date.parse(urlData.expires)); if (isDirect === true) { this.isDirect = true; } else if (isDirect === false) { this.isDirect = false; } else { if ('direct' in urlData) { this.isDirect = urlData.direct; } else { this.isDirect = Date.now() - this.expiresAt <= 86400000; } } this.isPreview = !this.isDirect; this._json = null; } return PublicUrl; })(); Dropbox.CopyReference = (function() { CopyReference.parse = function(refData) { if (refData && (typeof refData === 'object' || typeof refData === 'string')) { return new Dropbox.CopyReference(refData); } else { return refData; } }; CopyReference.prototype.tag = null; CopyReference.prototype.expiresAt = null; CopyReference.prototype.json = function() { return this._json || (this._json = { copy_ref: this.tag, expires: this.expiresAt.toString() }); }; function CopyReference(refData) { if (typeof refData === 'object') { this.tag = refData.copy_ref; this.expiresAt = new Date(Date.parse(refData.expires)); this._json = refData; } else { this.tag = refData; this.expiresAt = new Date(Math.ceil(Date.now() / 1000) * 1000); this._json = null; } } return CopyReference; })(); Dropbox.Stat = (function() { Stat.parse = function(metadata) { if (metadata && typeof metadata === 'object') { return new Dropbox.Stat(metadata); } else { return metadata; } }; Stat.prototype.path = null; Stat.prototype.name = null; Stat.prototype.inAppFolder = null; Stat.prototype.isFolder = null; Stat.prototype.isFile = null; Stat.prototype.isRemoved = null; Stat.prototype.typeIcon = null; Stat.prototype.versionTag = null; Stat.prototype.mimeType = null; Stat.prototype.size = null; Stat.prototype.humanSize = null; Stat.prototype.hasThumbnail = null; Stat.prototype.modifiedAt = null; Stat.prototype.clientModifiedAt = null; Stat.prototype.json = function() { return this._json; }; function Stat(metadata) { var lastIndex, nameSlash, _ref, _ref1; this._json = metadata; this.path = metadata.path; if (this.path.substring(0, 1) !== '/') { this.path = '/' + this.path; } lastIndex = this.path.length - 1; if (lastIndex >= 0 && this.path.substring(lastIndex) === '/') { this.path = this.path.substring(0, lastIndex); } nameSlash = this.path.lastIndexOf('/'); this.name = this.path.substring(nameSlash + 1); this.isFolder = metadata.is_dir || false; this.isFile = !this.isFolder; this.isRemoved = metadata.is_deleted || false; this.typeIcon = metadata.icon; if ((_ref = metadata.modified) != null ? _ref.length : void 0) { this.modifiedAt = new Date(Date.parse(metadata.modified)); } else { this.modifiedAt = null; } if ((_ref1 = metadata.client_mtime) != null ? _ref1.length : void 0) { this.clientModifiedAt = new Date(Date.parse(metadata.client_mtime)); } else { this.clientModifiedAt = null; } switch (metadata.root) { case 'dropbox': this.inAppFolder = false; break; case 'app_folder': this.inAppFolder = true; break; default: this.inAppFolder = null; } this.size = metadata.bytes || 0; this.humanSize = metadata.size || ''; this.hasThumbnail = metadata.thumb_exists || false; if (this.isFolder) { this.versionTag = metadata.hash; this.mimeType = metadata.mime_type || 'inode/directory'; } else { this.versionTag = metadata.rev; this.mimeType = metadata.mime_type || 'application/octet-stream'; } } return Stat; })(); Dropbox.UploadCursor = (function() { UploadCursor.parse = function(cursorData) { if (cursorData && (typeof cursorData === 'object' || typeof cursorData === 'string')) { return new Dropbox.UploadCursor(cursorData); } else { return cursorData; } }; UploadCursor.prototype.tag = null; UploadCursor.prototype.offset = null; UploadCursor.prototype.expiresAt = null; UploadCursor.prototype.json = function() { return this._json || (this._json = { upload_id: this.tag, offset: this.offset, expires: this.expiresAt.toString() }); }; function UploadCursor(cursorData) { this.replace(cursorData); } UploadCursor.prototype.replace = function(cursorData) { if (typeof cursorData === 'object') { this.tag = cursorData.upload_id || null; this.offset = cursorData.offset || 0; this.expiresAt = new Date(Date.parse(cursorData.expires) || Date.now()); this._json = cursorData; } else { this.tag = cursorData || null; this.offset = 0; this.expiresAt = new Date(Math.floor(Date.now() / 1000) * 1000); this._json = null; } return this; }; return UploadCursor; })(); Dropbox.UserInfo = (function() { UserInfo.parse = function(userInfo) { if (userInfo && typeof userInfo === 'object') { return new Dropbox.UserInfo(userInfo); } else { return userInfo; } }; UserInfo.prototype.name = null; UserInfo.prototype.email = null; UserInfo.prototype.countryCode = null; UserInfo.prototype.uid = null; UserInfo.prototype.referralUrl = null; UserInfo.prototype.publicAppUrl = null; UserInfo.prototype.quota = null; UserInfo.prototype.usedQuota = null; UserInfo.prototype.privateBytes = null; UserInfo.prototype.sharedBytes = null; UserInfo.prototype.json = function() { return this._json; }; function UserInfo(userInfo) { var lastIndex; this._json = userInfo; this.name = userInfo.display_name; this.email = userInfo.email; this.countryCode = userInfo.country || null; this.uid = userInfo.uid.toString(); if (userInfo.public_app_url) { this.publicAppUrl = userInfo.public_app_url; lastIndex = this.publicAppUrl.length - 1; if (lastIndex >= 0 && this.publicAppUrl.substring(lastIndex) === '/') { this.publicAppUrl = this.publicAppUrl.substring(0, lastIndex); } } else { this.publicAppUrl = null; } this.referralUrl = userInfo.referral_link; this.quota = userInfo.quota_info.quota; this.privateBytes = userInfo.quota_info.normal || 0; this.sharedBytes = userInfo.quota_info.shared || 0; this.usedQuota = this.privateBytes + this.sharedBytes; } return UserInfo; })(); if (typeof XMLHttpRequest !== 'undefined' && (typeof window !== 'undefined' || typeof self !== 'undefined') && typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string') { if (typeof XDomainRequest !== 'undefined' && !('withCredentials' in new XMLHttpRequest())) { DropboxXhrRequest = XDomainRequest; DropboxXhrIeMode = true; DropboxXhrCanSendForms = false; } else { DropboxXhrRequest = XMLHttpRequest; DropboxXhrIeMode = false; DropboxXhrCanSendForms = typeof FormData !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1; } DropboxXhrDoesPreflight = true; } else { DropboxXhrRequest = require('xhr2'); DropboxXhrIeMode = false; DropboxXhrCanSendForms = false; DropboxXhrDoesPreflight = false; } if (typeof Uint8Array === 'undefined') { DropboxXhrArrayBufferView = null; DropboxXhrWrapBlob = false; DropboxXhrSendArrayBufferView = false; } else { if (Object.getPrototypeOf) { DropboxXhrArrayBufferView = Object.getPrototypeOf(Object.getPrototypeOf(new Uint8Array(0))).constructor; } else if (Object.__proto__) { DropboxXhrArrayBufferView = (new Uint8Array(0)).__proto__.__proto__.constructor; } if (typeof Blob === 'undefined') { DropboxXhrWrapBlob = false; DropboxXhrSendArrayBufferView = true; } else { try { if ((new Blob([new Uint8Array(2)])).size === 2) { DropboxXhrWrapBlob = true; DropboxXhrSendArrayBufferView = true; } else { DropboxXhrSendArrayBufferView = false; DropboxXhrWrapBlob = (new Blob([new ArrayBuffer(2)])).size === 2; } } catch (_error) { blobError = _error; DropboxXhrSendArrayBufferView = false; DropboxXhrWrapBlob = false; if (typeof WebKitBlobBuilder !== 'undefined') { if (navigator.userAgent.indexOf('Android') !== -1) { DropboxXhrCanSendForms = false; } } } if (DropboxXhrArrayBufferView === Object) { DropboxXhrSendArrayBufferView = false; } } } Dropbox.Xhr = (function() { Xhr.Request = DropboxXhrRequest; Xhr.ieXdr = DropboxXhrIeMode; Xhr.canSendForms = DropboxXhrCanSendForms; Xhr.doesPreflight = DropboxXhrDoesPreflight; Xhr.ArrayBufferView = DropboxXhrArrayBufferView; Xhr.sendArrayBufferView = DropboxXhrSendArrayBufferView; Xhr.wrapBlob = DropboxXhrWrapBlob; function Xhr(method, baseUrl) { this.method = method; this.isGet = this.method === 'GET'; this.url = baseUrl; this.wantHeaders = false; this.headers = {}; this.params = null; this.body = null; this.preflight = !(this.isGet || (this.method === 'POST')); this.signed = false; this.completed = false; this.responseType = null; this.callback = null; this.xhr = null; this.onError = null; } Xhr.prototype.xhr = null; Xhr.prototype.onError = null; Xhr.prototype.setParams = function(params) { if (this.signed) { throw new Error('setParams called after addOauthParams or addOauthHeader'); } if (this.params) { throw new Error('setParams cannot be called twice'); } this.params = params; return this; }; Xhr.prototype.setCallback = function(callback) { this.callback = callback; return this; }; Xhr.prototype.signWithOauth = function(oauth, cacheFriendly) { if (Dropbox.Xhr.ieXdr) { return this.addOauthParams(oauth); } else if (this.preflight || !Dropbox.Xhr.doesPreflight) { return this.addOauthHeader(oauth); } else { if (this.isGet && cacheFriendly) { return this.addOauthHeader(oauth); } else { return this.addOauthParams(oauth); } } }; Xhr.prototype.addOauthParams = function(oauth) { if (this.signed) { throw new Error('Request already has an OAuth signature'); } this.params || (this.params = {}); oauth.addAuthParams(this.method, this.url, this.params); this.signed = true; return this; }; Xhr.prototype.addOauthHeader = function(oauth) { if (this.signed) { throw new Error('Request already has an OAuth signature'); } this.params || (this.params = {}); this.signed = true; return this.setHeader('Authorization', oauth.authHeader(this.method, this.url, this.params)); }; Xhr.prototype.setBody = function(body) { if (this.isGet) { throw new Error('setBody cannot be called on GET requests'); } if (this.body !== null) { throw new Error('Request already has a body'); } if (typeof body === 'string') { } else if ((typeof FormData !== 'undefined') && (body instanceof FormData)) { } else { this.headers['Content-Type'] = 'application/octet-stream'; this.preflight = true; } this.body = body; return this; }; Xhr.prototype.setResponseType = function(responseType) { this.responseType = responseType; return this; }; Xhr.prototype.setHeader = function(headerName, value) { var oldValue; if (this.headers[headerName]) { oldValue = this.headers[headerName]; throw new Error("HTTP header " + headerName + " already set to " + oldValue); } if (headerName === 'Content-Type') { throw new Error('Content-Type is automatically computed based on setBody'); } this.preflight = true; this.headers[headerName] = value; return this; }; Xhr.prototype.reportResponseHeaders = function() { return this.wantHeaders = true; }; Xhr.prototype.setFileField = function(fieldName, fileName, fileData, contentType) { var blob, boundary, builder, useFormData; if (this.body !== null) { throw new Error('Request already has a body'); } if (this.isGet) { throw new Error('setFileField cannot be called on GET requests'); } if (typeof fileData === 'object') { if (typeof ArrayBuffer !== 'undefined') { if (fileData instanceof ArrayBuffer) { if (Dropbox.Xhr.sendArrayBufferView) { fileData = new Uint8Array(fileData); } } else { if (!Dropbox.Xhr.sendArrayBufferView && fileData.byteOffset === 0 && fileData.buffer instanceof ArrayBuffer) { fileData = fileData.buffer; } } } contentType || (contentType = 'application/octet-stream'); try { fileData = new Blob([fileData], { type: contentType }); } catch (_error) { blobError = _error; if (window.WebKitBlobBuilder) { builder = new WebKitBlobBuilder; builder.append(fileData); if (blob = builder.getBlob(contentType)) { fileData = blob; } } } if (typeof File !== 'undefined' && fileData instanceof File) { fileData = new Blob([fileData], { type: fileData.type }); } useFormData = fileData instanceof Blob; } else { useFormData = false; } if (useFormData) { this.body = new FormData(); return this.body.append(fieldName, fileData, fileName); } else { contentType || (contentType = 'application/octet-stream'); boundary = this.multipartBoundary(); this.headers['Content-Type'] = "multipart/form-data; boundary=" + boundary; return this.body = ['--', boundary, "\r\n", 'Content-Disposition: form-data; name="', fieldName, '"; filename="', fileName, "\"\r\n", 'Content-Type: ', contentType, "\r\n", "Content-Transfer-Encoding: binary\r\n\r\n", fileData, "\r\n", '--', boundary, '--', "\r\n"].join(''); } }; Xhr.prototype.multipartBoundary = function() { return [Date.now().toString(36), Math.random().toString(36)].join('----'); }; Xhr.prototype.paramsToUrl = function() { var queryString; if (this.params) { queryString = Dropbox.Xhr.urlEncode(this.params); if (queryString.length !== 0) { this.url = [this.url, '?', queryString].join(''); } this.params = null; } return this; }; Xhr.prototype.paramsToBody = function() { if (this.params) { if (this.body !== null) { throw new Error('Request already has a body'); } if (this.isGet) { throw new Error('paramsToBody cannot be called on GET requests'); } this.headers['Content-Type'] = 'application/x-www-form-urlencoded'; this.body = Dropbox.Xhr.urlEncode(this.params); this.params = null; } return this; }; Xhr.prototype.prepare = function() { var header, ieXdr, value, _ref, _this = this; ieXdr = Dropbox.Xhr.ieXdr; if (this.isGet || this.body !== null || ieXdr) { this.paramsToUrl(); if (this.body !== null && typeof this.body === 'string') { this.headers['Content-Type'] = 'text/plain; charset=utf8'; } } else { this.paramsToBody(); } this.xhr = new Dropbox.Xhr.Request(); if (ieXdr) { this.xhr.onload = function() { return _this.onXdrLoad(); }; this.xhr.onerror = function() { return _this.onXdrError(); }; this.xhr.ontimeout = function() { return _this.onXdrError(); }; this.xhr.onprogress = function() {}; } else { this.xhr.onreadystatechange = function() { return _this.onReadyStateChange(); }; } this.xhr.open(this.method, this.url, true); if (!ieXdr) { _ref = this.headers; for (header in _ref) { if (!__hasProp.call(_ref, header)) continue; value = _ref[header]; this.xhr.setRequestHeader(header, value); } } if (this.responseType) { if (this.responseType === 'b') { if (this.xhr.overrideMimeType) { this.xhr.overrideMimeType('text/plain; charset=x-user-defined'); } } else { this.xhr.responseType = this.responseType; } } return this; }; Xhr.prototype.send = function(callback) { var body, xhrError; this.callback = callback || this.callback; if (this.body !== null) { body = this.body; if (Dropbox.Xhr.sendArrayBufferView) { if (body instanceof ArrayBuffer) { body = new Uint8Array(body); } } else { if (body.byteOffset === 0 && body.buffer instanceof ArrayBuffer) { body = body.buffer; } } try { this.xhr.send(body); } catch (_error) { xhrError = _error; if (!Dropbox.Xhr.sendArrayBufferView && Dropbox.Xhr.wrapBlob) { body = new Blob([body], { type: 'application/octet-stream' }); this.xhr.send(body); } else { throw xhrError; } } } else { this.xhr.send(); } return this; }; Xhr.urlEncode = function(object) { var chunks, key, value; chunks = []; for (key in object) { value = object[key]; chunks.push(this.urlEncodeValue(key) + '=' + this.urlEncodeValue(value)); } return chunks.sort().join('&'); }; Xhr.urlEncodeValue = function(object) { return encodeURIComponent(object.toString()).replace(/\!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); }; Xhr.urlDecode = function(string) { var kvp, result, token, _i, _len, _ref; result = {}; _ref = string.split('&'); for (_i = 0, _len = _ref.length; _i < _len; _i++) { token = _ref[_i]; kvp = token.split('='); result[decodeURIComponent(kvp[0])] = decodeURIComponent(kvp[1]); } return result; }; Xhr.prototype.onReadyStateChange = function() { var allHeaders, apiError, bytes, dirtyText, headers, i, jsonError, metadata, metadataJson, text, _i, _ref; if (this.xhr.readyState !== 4) { return true; } if (this.completed) { return true; } this.completed = true; if (this.xhr.status < 200 || this.xhr.status >= 300) { apiError = new Dropbox.ApiError(this.xhr, this.method, this.url); if (this.onError) { this.onError(apiError, this.callback); } else { this.callback(apiError); } return true; } if (this.wantHeaders) { allHeaders = this.xhr.getAllResponseHeaders(); if (allHeaders) { headers = Dropbox.Xhr.parseResponseHeaders(allHeaders); } else { headers = this.guessResponseHeaders(); } metadataJson = headers['x-dropbox-metadata']; } else { headers = void 0; metadataJson = this.xhr.getResponseHeader('x-dropbox-metadata'); } if (metadataJson != null ? metadataJson.length : void 0) { try { metadata = JSON.parse(metadataJson); } catch (_error) { jsonError = _error; metadata = void 0; } } else { metadata = void 0; } if (this.responseType) { if (this.responseType === 'b') { dirtyText = this.xhr.responseText != null ? this.xhr.responseText : this.xhr.response; bytes = []; for (i = _i = 0, _ref = dirtyText.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { bytes.push(String.fromCharCode(dirtyText.charCodeAt(i) & 0xFF)); } text = bytes.join(''); this.callback(null, text, metadata, headers); } else { this.callback(null, this.xhr.response, metadata, headers); } return true; } text = this.xhr.responseText != null ? this.xhr.responseText : this.xhr.response; switch (this.xhr.getResponseHeader('Content-Type')) { case 'application/x-www-form-urlencoded': this.callback(null, Dropbox.Xhr.urlDecode(text), metadata, headers); break; case 'application/json': case 'text/javascript': this.callback(null, JSON.parse(text), metadata, headers); break; default: this.callback(null, text, metadata, headers); } return true; }; Xhr.parseResponseHeaders = function(allHeaders) { var colonIndex, headerLines, headers, line, name, value, _i, _len; headers = {}; headerLines = allHeaders.split("\n"); for (_i = 0, _len = headerLines.length; _i < _len; _i++) { line = headerLines[_i]; colonIndex = line.indexOf(':'); name = line.substring(0, colonIndex).trim().toLowerCase(); value = line.substring(colonIndex + 1).trim(); headers[name] = value; } return headers; }; Xhr.prototype.guessResponseHeaders = function() { var headers, name, value, _i, _len, _ref; headers = {}; _ref = ['cache-control', 'content-language', 'content-range', 'content-type', 'expires', 'last-modified', 'pragma', 'x-dropbox-metadata']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; value = this.xhr.getResponseHeader(name); if (value) { headers[name] = value; } } return headers; }; Xhr.prototype.onXdrLoad = function() { var headers, metadata, text; if (this.completed) { return true; } this.completed = true; text = this.xhr.responseText; if (this.wantHeaders) { headers = { 'content-type': this.xhr.contentType }; } else { headers = void 0; } metadata = void 0; if (this.responseType) { this.callback(null, text, metadata, headers); return true; } switch (this.xhr.contentType) { case 'application/x-www-form-urlencoded': this.callback(null, Dropbox.Xhr.urlDecode(text), metadata, headers); break; case 'application/json': case 'text/javascript': this.callback(null, JSON.parse(text), metadata, headers); break; default: this.callback(null, text, metadata, headers); } return true; }; Xhr.prototype.onXdrError = function() { var apiError; if (this.completed) { return true; } this.completed = true; apiError = new Dropbox.ApiError(this.xhr, this.method, this.url); if (this.onError) { this.onError(apiError, this.callback); } else { this.callback(apiError); } return true; }; return Xhr; })(); if (typeof module !== 'undefined' && 'exports' in module) { module.exports = Dropbox; } else if (typeof window !== "undefined" && window !== null) { if (window.Dropbox) { for (name in Dropbox) { if (!__hasProp.call(Dropbox, name)) continue; value = Dropbox[name]; window.Dropbox[name] = value; } } else { window.Dropbox = Dropbox; } } else if (typeof self !== "undefined" && self !== null) { self.Dropbox = Dropbox; } else { throw new Error('This library only supports node.js and modern browsers.'); } }).call(this);