From 1672d0eb1da915335e820cffe8dc2dd552f05a38 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Wed, 30 Nov 2016 18:06:44 +0700 Subject: [PATCH] Release 0.14.0 --- bower.json | 4 +- package.json | 2 +- release/head/remotestorage-nocache.amd.js | 137 ++++++++- release/head/remotestorage-nocache.js | 137 ++++++++- release/head/remotestorage-nocache.min.js | 10 +- release/head/remotestorage.amd.js | 139 +++++++-- release/head/remotestorage.js | 139 +++++++-- release/head/remotestorage.min.js | 14 +- release/stable/remotestorage-nocache.amd.js | 296 +++++++++++++------ release/stable/remotestorage-nocache.js | 296 +++++++++++++------ release/stable/remotestorage-nocache.min.js | 14 +- release/stable/remotestorage.amd.js | 298 ++++++++++++++------ release/stable/remotestorage.js | 298 ++++++++++++++------ release/stable/remotestorage.min.js | 18 +- src/version.js | 6 +- 15 files changed, 1366 insertions(+), 442 deletions(-) diff --git a/bower.json b/bower.json index 17306c1f2..f9c4c4d9c 100644 --- a/bower.json +++ b/bower.json @@ -1,10 +1,10 @@ { "name": "remotestorage", - "version": "0.13.0", + "version": "0.14.0", "main": [ "./release/stable/remotestorage.js" ], "license": "MIT", "homepage": "https://github.com/remotestorage/remotestorage.js", - "keywords": ["localstorage", "indexeddb", "storage", "offline", "no-backend", "unhosted"] + "keywords": ["localstorage", "indexeddb", "storage", "offline", "no-backend", "unhosted", "offline-first"] } diff --git a/package.json b/package.json index a4785641d..cb8b32703 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "remotestoragejs", "description": "JavaScript library for integrating remoteStorage", - "version": "0.13.1-pre", + "version": "0.14.0", "private": false, "license": "MIT", "main": "./node-main.js", diff --git a/release/head/remotestorage-nocache.amd.js b/release/head/remotestorage-nocache.amd.js index d8c894fb2..4ec23e6ae 100644 --- a/release/head/remotestorage-nocache.amd.js +++ b/release/head/remotestorage-nocache.amd.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.1-pre, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ define([], function() { /** FILE: src/remotestorage.js **/ @@ -171,6 +171,18 @@ define([], function() { * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -180,8 +192,9 @@ define([], function() { RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -316,6 +329,20 @@ define([], function() { * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -1617,6 +1644,7 @@ define([], function() { * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -1628,7 +1656,8 @@ define([], function() { * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -1714,13 +1743,17 @@ define([], function() { body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -1756,11 +1789,16 @@ define([], function() { } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -6612,6 +6650,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -6977,15 +7017,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); + } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); } - return xhr; + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -7062,6 +7132,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -7630,15 +7702,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -7717,8 +7823,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -7866,7 +7972,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -7875,6 +7981,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -7885,7 +7992,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/head/remotestorage-nocache.js b/release/head/remotestorage-nocache.js index 695bbbcdc..1e52cf4ca 100644 --- a/release/head/remotestorage-nocache.js +++ b/release/head/remotestorage-nocache.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.1-pre, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ /** FILE: lib/bluebird.js **/ /** @@ -3441,6 +3441,18 @@ module.exports = ret; * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -3450,8 +3462,9 @@ module.exports = ret; RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -3586,6 +3599,20 @@ module.exports = ret; * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -4887,6 +4914,7 @@ module.exports = ret; * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -4898,7 +4926,8 @@ module.exports = ret; * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -4984,13 +5013,17 @@ module.exports = ret; body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -5026,11 +5059,16 @@ module.exports = ret; } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -9882,6 +9920,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -10247,15 +10287,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); + } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); } - return xhr; + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -10332,6 +10402,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -10900,15 +10972,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -10987,8 +11093,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -11136,7 +11242,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -11145,6 +11251,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -11155,7 +11262,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/head/remotestorage-nocache.min.js b/release/head/remotestorage-nocache.min.js index 98dc16e03..bc24de22b 100644 --- a/release/head/remotestorage-nocache.min.js +++ b/release/head/remotestorage-nocache.min.js @@ -1,8 +1,8 @@ -/** remotestorage.js 0.13.1-pre, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o0},Async.prototype.invokeLater=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn)),this._lateBuffer.push(fn,receiver,arg),this._queueTick()},Async.prototype.invoke=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn));var functionBuffer=this._functionBuffer;functionBuffer.push(fn,receiver,arg),this._length=functionBuffer.length(),this._queueTick()},Async.prototype._consumeFunctionBuffer=function(){for(var functionBuffer=this._functionBuffer;functionBuffer.length()>0;){var fn=functionBuffer.shift(),receiver=functionBuffer.shift(),arg=functionBuffer.shift();fn.call(receiver,arg)}this._reset(),this._consumeLateBuffer()},Async.prototype._consumeLateBuffer=function(){for(var buffer=this._lateBuffer;buffer.length()>0;){var fn=buffer.shift(),receiver=buffer.shift(),arg=buffer.shift(),res=tryCatch1(fn,receiver,arg);if(res===errorObj){if(this._queueTick(),null==fn.domain)throw res.e;fn.domain.emit("error",res.e)}}},Async.prototype._queueTick=function(){this._isTickUsed||(this._schedule(this.consumeFunctionBuffer),this._isTickUsed=!0)},Async.prototype._reset=function(){this._isTickUsed=!1,this._length=0},module.exports=new Async},{"./queue.js":15,"./schedule.js":16,"./util.js":19}],2:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise.js")();module.exports=Promise},{"./promise.js":12}],3:[function(_dereq_,module,exports){"use strict";module.exports=function(){function formatNonError(obj){var str;if("function"==typeof obj)str="[function "+(obj.name||"anonymous")+"]";else{str=obj.toString();var ruselessToString=/\[object [a-zA-Z0-9$_]+\]/;if(ruselessToString.test(str))try{var newStr=JSON.stringify(obj);str=newStr}catch(e){}0===str.length&&(str="(empty array)")}return"(<"+snip(str)+">, no stack trace)"}function snip(str){var maxChars=41;return str.length=0;--i){var line=prev[i];if(current[curLast]!==line)break;current.pop(),curLast--}current.push("From previous event:");for(var lines=current.concat(prev),ret=[],i=0,len=lines.length;len>i;++i)rignore.test(lines[i])&&rtraceline.test(lines[i])||i>0&&!rtraceline.test(lines[i])&&"From previous event:"!==lines[i]||ret.push(lines[i]);return ret},CapturedTrace.protectErrorMessageNewlines=function(stack){for(var i=0;i=i)){for(var errorMessageLines=[],j=0;i>j;++j)errorMessageLines.push(stack.shift());stack.unshift(errorMessageLines.join("\x00"))}},CapturedTrace.isSupported=function(){return"function"==typeof captureStackTrace};var captureStackTrace=function stackDetection(){if("number"==typeof Error.stackTraceLimit&&"function"==typeof Error.captureStackTrace){rtraceline=/^\s*at\s*/,formatStack=function(stack,error){return"string"==typeof stack?stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)};var captureStackTrace=Error.captureStackTrace;return function(receiver,ignoreUntil){captureStackTrace(receiver,ignoreUntil)}}var err=new Error;if("string"==typeof err.stack&&"function"==typeof"".startsWith&&err.stack.startsWith("stackDetection@")&&"stackDetection"===stackDetection.name){defineProperty(Error,"stackTraceLimit",{writable:!0,enumerable:!1,configurable:!1,value:25}),rtraceline=/@/;var rline=/[@\n]/;return formatStack=function(stack,error){return"string"==typeof stack?error.name+". "+error.message+"\n"+stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)},function(o){for(var stack=(new Error).stack,split=stack.split(rline),len=split.length,ret="",i=0;len>i;i+=2)ret+=split[i],ret+="@",ret+=split[i+1],ret+="\n";o.stack=ret}}return formatStack=function(stack,error){return"string"==typeof stack?stack:"object"!=typeof error&&"function"!=typeof error||void 0===error.name||void 0===error.message?formatNonError(error):error.name+". "+error.message},null}();return CapturedTrace}},{"./es5.js":8,"./util.js":19}],4:[function(_dereq_,module,exports){"use strict";module.exports=function(NEXT_FILTER){function CatchFilter(instances,callback,promise){this._instances=instances,this._callback=callback,this._promise=promise}function CatchFilter$_safePredicate(predicate,e){var safeObject={},retfilter=tryCatch1(predicate,safeObject,e);if(retfilter===errorObj)return retfilter;var safeKeys=keys(safeObject);return safeKeys.length?(errorObj.e=new TypeError("Catch filter must inherit from Error or be a simple predicate function"),errorObj):retfilter}var util=_dereq_("./util.js"),errors=_dereq_("./errors.js"),tryCatch1=util.tryCatch1,errorObj=util.errorObj,keys=_dereq_("./es5.js").keys,TypeError=errors.TypeError;return CatchFilter.prototype.doFilter=function(e){for(var cb=this._callback,promise=this._promise,boundTo=promise._boundTo,i=0,len=this._instances.length;len>i;++i){var item=this._instances[i],itemIsErrorType=item===Error||null!=item&&item.prototype instanceof Error;if(itemIsErrorType&&e instanceof item){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}if("function"==typeof item&&!itemIsErrorType){var shouldHandle=CatchFilter$_safePredicate(item,e);if(shouldHandle===errorObj){var trace=errors.canAttach(errorObj.e)?errorObj.e:new Error(errorObj.e+"");this._promise._attachExtraTrace(trace),e=errorObj.e;break}if(shouldHandle){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}}}return NEXT_FILTER.e=e,NEXT_FILTER},CatchFilter}},{"./errors.js":6,"./es5.js":8,"./util.js":19}],5:[function(_dereq_,module,exports){"use strict";var util=_dereq_("./util.js"),isPrimitive=util.isPrimitive,wrapsPrimitiveReceiver=util.wrapsPrimitiveReceiver;module.exports=function(Promise){var returner=function(){return this},thrower=function(){throw this},wrapper=function(value,action){return 1===action?function(){throw value}:2===action?function(){return value}:void 0};Promise.prototype["return"]=Promise.prototype.thenReturn=function(value){return wrapsPrimitiveReceiver&&isPrimitive(value)?this._then(wrapper(value,2),void 0,void 0,void 0,void 0):this._then(returner,void 0,void 0,value,void 0)},Promise.prototype["throw"]=Promise.prototype.thenThrow=function(reason){return wrapsPrimitiveReceiver&&isPrimitive(reason)?this._then(wrapper(reason,1),void 0,void 0,void 0,void 0):this._then(thrower,void 0,void 0,reason,void 0)}}},{"./util.js":19}],6:[function(_dereq_,module,exports){"use strict";function markAsOriginatingFromRejection(e){try{notEnumerableProp(e,"isOperational",!0)}catch(ignore){}}function originatesFromRejection(e){return null==e?!1:e instanceof OperationalError||e.isOperational===!0}function isError(obj){return obj instanceof Error}function canAttach(obj){return isError(obj)}function subError(nameProperty,defaultMessage){function SubError(message){return this instanceof SubError?(this.message="string"==typeof message?message:defaultMessage,this.name=nameProperty,void(Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor))):new SubError(message)}return inherits(SubError,Error),SubError}function OperationalError(message){this.name="OperationalError",this.message=message,this.cause=message,this.isOperational=!0,message instanceof Error?(this.message=message.message,this.stack=message.stack):Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}var _TypeError,_RangeError,Objectfreeze=_dereq_("./es5.js").freeze,util=_dereq_("./util.js"),inherits=util.inherits,notEnumerableProp=util.notEnumerableProp,CancellationError=subError("CancellationError","cancellation error"),TimeoutError=subError("TimeoutError","timeout error"),AggregateError=subError("AggregateError","aggregate error");try{_TypeError=TypeError,_RangeError=RangeError}catch(e){_TypeError=subError("TypeError","type error"),_RangeError=subError("RangeError","range error")}for(var methods="join pop push shift unshift slice filter forEach some every map indexOf lastIndexOf reduce reduceRight sort reverse".split(" "),i=0;i=i;++i)values.push("holder.p"+i);return new Function("holder"," \n 'use strict'; \n var callback = holder.fn; \n return callback(values); \n ".replace(/values/g,values.join(", ")))},thenCallbacks=[],callers=[void 0],i=1;5>=i;++i)thenCallbacks.push(thenCallback(i)),callers.push(caller(i));var Holder=function(total,fn){this.p1=this.p2=this.p3=this.p4=this.p5=null,this.fn=fn,this.total=total,this.now=0};Holder.prototype.callers=callers,Holder.prototype.checkFulfillment=function(promise){var now=this.now;now++;var total=this.total;if(now>=total){var handler=this.callers[total],ret=tryCatch1(handler,void 0,this);ret===errorObj?promise._rejectUnchecked(ret.e):promise._tryFollow(ret)||promise._fulfillUnchecked(ret)}else this.now=now}}Promise.join=function(){var fn,last=arguments.length-1;if(last>0&&"function"==typeof arguments[last]&&(fn=arguments[last],6>last&&canEvaluate)){var ret=new Promise(INTERNAL);ret._setTrace(void 0);for(var holder=new Holder(last,fn),reject=ret._reject,callbacks=thenCallbacks,i=0;last>i;++i){var maybePromise=cast(arguments[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._then(callbacks[i],reject,void 0,ret,holder):maybePromise.isFulfilled()?callbacks[i].call(ret,maybePromise._settledValue,holder):(ret._reject(maybePromise._settledValue),maybePromise._unsetRejectionIsUnhandled()):callbacks[i].call(ret,maybePromise,holder)}return ret}for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];var ret=new PromiseArray(args).promise();return void 0!==fn?ret.spread(fn):ret}}},{"./util.js":19}],11:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function thrower(r){throw r}function Promise$_spreadAdapter(val,receiver){if(!util.isArray(val))return Promise$_successAdapter(val,receiver);var ret=util.tryCatchApply(this,[null].concat(val),receiver);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_successAdapter(val,receiver){var nodeback=this,ret=void 0===val?tryCatch1(nodeback,receiver,null):tryCatch2(nodeback,receiver,null,val);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_errorAdapter(reason,receiver){var nodeback=this,ret=tryCatch1(nodeback,receiver,reason);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),tryCatch2=util.tryCatch2,tryCatch1=util.tryCatch1,errorObj=util.errorObj;Promise.prototype.nodeify=function(nodeback,options){if("function"==typeof nodeback){var adapter=Promise$_successAdapter;void 0!==options&&Object(options).spread&&(adapter=Promise$_spreadAdapter),this._then(adapter,Promise$_errorAdapter,void 0,nodeback,this._boundTo)}return this}}},{"./async.js":1,"./util.js":19}],12:[function(_dereq_,module,exports){"use strict";function noConflict(bluebird){try{Promise===bluebird&&(Promise=old)}catch(e){}return bluebird}var old;"undefined"!=typeof Promise&&(old=Promise),module.exports=function(){function Promise(resolver){if("function"!=typeof resolver)throw new TypeError("the promise constructor requires a resolver function");if(this.constructor!==Promise)throw new TypeError("the promise constructor cannot be invoked directly");this._bitField=0,this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0,this._settledValue=void 0,this._boundTo=void 0,resolver!==INTERNAL&&this._resolveFromResolver(resolver)}function returnFirstElement(elements){return elements[0]}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),errors=_dereq_("./errors.js"),INTERNAL=function(){},APPLY={},NEXT_FILTER={e:null},cast=_dereq_("./thenables.js")(Promise,INTERNAL),PromiseArray=_dereq_("./promise_array.js")(Promise,INTERNAL,cast),CapturedTrace=_dereq_("./captured_trace.js")(),CatchFilter=_dereq_("./catch_filter.js")(NEXT_FILTER),PromiseResolver=_dereq_("./promise_resolver.js"),isArray=util.isArray,errorObj=util.errorObj,tryCatch1=util.tryCatch1,tryCatch2=util.tryCatch2,tryCatchApply=util.tryCatchApply,RangeError=errors.RangeError,TypeError=errors.TypeError,CancellationError=errors.CancellationError,TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,originatesFromRejection=errors.originatesFromRejection,markAsOriginatingFromRejection=errors.markAsOriginatingFromRejection,canAttach=errors.canAttach,thrower=util.thrower,apiRejection=_dereq_("./errors_api_rejection")(Promise),makeSelfResolutionError=function(){return new TypeError("circular promise resolution chain")};Promise.prototype.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(maybePromise instanceof Promise){var binder=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)}),p=Promise.all([this,binder]).then(returnFirstElement);ret._follow(p)}else ret._follow(this),ret._setBoundTo(thisArg);return ret._propagateFrom(this,3),ret},Promise.prototype.toString=function(){return"[object Promise]"},Promise.prototype.caught=Promise.prototype["catch"]=function(fn){var len=arguments.length;if(len>1){var i,catchInstances=new Array(len-1),j=0;for(i=0;len-1>i;++i){var item=arguments[i];if("function"!=typeof item){var catchFilterTypeError=new TypeError("A catch filter must be an error constructor or a filter function");return this._attachExtraTrace(catchFilterTypeError),Promise.reject(catchFilterTypeError)}catchInstances[j++]=item}catchInstances.length=j,fn=arguments[i],this._resetTrace();var catchFilter=new CatchFilter(catchInstances,fn,this);return this._then(void 0,catchFilter.doFilter,void 0,catchFilter,void 0)}return this._then(void 0,fn,void 0,void 0,void 0)},Promise.prototype.then=function(didFulfill,didReject,didProgress){return this._then(didFulfill,didReject,didProgress,void 0,void 0)},Promise.prototype.done=function(didFulfill,didReject,didProgress){var promise=this._then(didFulfill,didReject,didProgress,void 0,void 0);promise._setIsFinal()},Promise.prototype.spread=function(didFulfill,didReject){return this._then(didFulfill,didReject,void 0,APPLY,void 0)},Promise.prototype.isCancellable=function(){return!this.isResolved()&&this._cancellable()},Promise.prototype.toJSON=function(){var ret={isFulfilled:!1,isRejected:!1,fulfillmentValue:void 0,rejectionReason:void 0};return this.isFulfilled()?(ret.fulfillmentValue=this._settledValue,ret.isFulfilled=!0):this.isRejected()&&(ret.rejectionReason=this._settledValue,ret.isRejected=!0),ret},Promise.prototype.all=function(){return new PromiseArray(this).promise()},Promise.is=function(val){return val instanceof Promise},Promise.all=function(promises){return new PromiseArray(promises).promise()},Promise.prototype.error=function(fn){return this.caught(originatesFromRejection,fn)},Promise.prototype._resolveFromSyncValue=function(value){if(value===errorObj)this._cleanValues(),this._setRejected(),this._settledValue=value.e,this._ensurePossibleRejectionHandled();else{var maybePromise=cast(value,void 0);maybePromise instanceof Promise?this._follow(maybePromise):(this._cleanValues(),this._setFulfilled(),this._settledValue=value)}},Promise.method=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");return function(){var value;switch(arguments.length){case 0:value=tryCatch1(fn,this,void 0);break;case 1:value=tryCatch1(fn,this,arguments[0]);break;case 2:value=tryCatch2(fn,this,arguments[0],arguments[1]);break;default:for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];value=tryCatchApply(fn,args,this)}var ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret}},Promise.attempt=Promise["try"]=function(fn,args,ctx){if("function"!=typeof fn)return apiRejection("fn must be a function");var value=isArray(args)?tryCatchApply(fn,args,ctx):tryCatch1(fn,ctx,args),ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret},Promise.defer=Promise.pending=function(){var promise=new Promise(INTERNAL);return promise._setTrace(void 0),new PromiseResolver(promise)},Promise.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(ret._setTrace(void 0),maybePromise instanceof Promise){var p=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)});ret._follow(p)}else ret._setBoundTo(thisArg),ret._setFulfilled();return ret},Promise.cast=function(obj){var ret=cast(obj,void 0);if(!(ret instanceof Promise)){var val=ret;ret=new Promise(INTERNAL),ret._setTrace(void 0),ret._setFulfilled(),ret._cleanValues(),ret._settledValue=val}return ret},Promise.resolve=Promise.fulfilled=Promise.cast,Promise.reject=Promise.rejected=function(reason){var ret=new Promise(INTERNAL);if(ret._setTrace(void 0),markAsOriginatingFromRejection(reason),ret._cleanValues(),ret._setRejected(),ret._settledValue=reason,!canAttach(reason)){var trace=new Error(reason+"");ret._setCarriedStackTrace(trace)}return ret._ensurePossibleRejectionHandled(),ret},Promise.onPossiblyUnhandledRejection=function(fn){CapturedTrace.possiblyUnhandledRejection="function"==typeof fn?fn:void 0};var unhandledRejectionHandled;Promise.onUnhandledRejectionHandled=function(fn){unhandledRejectionHandled="function"==typeof fn?fn:void 0};var debugging=!("undefined"==typeof process||"string"!=typeof process.execPath||"object"!=typeof process.env||!process.env.BLUEBIRD_DEBUG&&"development"!==process.env.NODE_ENV);Promise.longStackTraces=function(){if(async.haveItemsQueued()&&debugging===!1)throw new Error("cannot enable long stack traces after promises have been created");debugging=CapturedTrace.isSupported()},Promise.hasLongStackTraces=function(){return debugging&&CapturedTrace.isSupported()},Promise.prototype._then=function(didFulfill,didReject,didProgress,receiver,internalData){var haveInternalData=void 0!==internalData,ret=haveInternalData?internalData:new Promise(INTERNAL);if(!haveInternalData){if(debugging){var haveSameContext=this._peekContext()===this._traceParent;ret._traceParent=haveSameContext?this._traceParent:this}ret._propagateFrom(this,7)}var callbackIndex=this._addCallbacks(didFulfill,didReject,didProgress,ret,receiver);return this.isResolved()&&async.invoke(this._queueSettleAt,this,callbackIndex),ret},Promise.prototype._length=function(){return 262143&this._bitField},Promise.prototype._isFollowingOrFulfilledOrRejected=function(){return(939524096&this._bitField)>0},Promise.prototype._isFollowing=function(){return 536870912===(536870912&this._bitField)},Promise.prototype._setLength=function(len){this._bitField=-262144&this._bitField|262143&len},Promise.prototype._setFulfilled=function(){this._bitField=268435456|this._bitField},Promise.prototype._setRejected=function(){this._bitField=134217728|this._bitField},Promise.prototype._setFollowing=function(){this._bitField=536870912|this._bitField},Promise.prototype._setIsFinal=function(){this._bitField=33554432|this._bitField},Promise.prototype._isFinal=function(){return(33554432&this._bitField)>0},Promise.prototype._cancellable=function(){return(67108864&this._bitField)>0},Promise.prototype._setCancellable=function(){this._bitField=67108864|this._bitField},Promise.prototype._unsetCancellable=function(){this._bitField=-67108865&this._bitField},Promise.prototype._setRejectionIsUnhandled=function(){this._bitField=2097152|this._bitField},Promise.prototype._unsetRejectionIsUnhandled=function(){this._bitField=-2097153&this._bitField,this._isUnhandledRejectionNotified()&&(this._unsetUnhandledRejectionIsNotified(),this._notifyUnhandledRejectionIsHandled())},Promise.prototype._isRejectionUnhandled=function(){return(2097152&this._bitField)>0},Promise.prototype._setUnhandledRejectionIsNotified=function(){this._bitField=524288|this._bitField},Promise.prototype._unsetUnhandledRejectionIsNotified=function(){this._bitField=-524289&this._bitField},Promise.prototype._isUnhandledRejectionNotified=function(){return(524288&this._bitField)>0},Promise.prototype._setCarriedStackTrace=function(capturedTrace){this._bitField=1048576|this._bitField,this._fulfillmentHandler0=capturedTrace},Promise.prototype._unsetCarriedStackTrace=function(){this._bitField=-1048577&this._bitField,this._fulfillmentHandler0=void 0},Promise.prototype._isCarryingStackTrace=function(){return(1048576&this._bitField)>0},Promise.prototype._getCarriedStackTrace=function(){return this._isCarryingStackTrace()?this._fulfillmentHandler0:void 0},Promise.prototype._receiverAt=function(index){var ret=0===index?this._receiver0:this[(index<<2)+index-5+4];return this._isBound()&&void 0===ret?this._boundTo:ret},Promise.prototype._promiseAt=function(index){return 0===index?this._promise0:this[(index<<2)+index-5+3]},Promise.prototype._fulfillmentHandlerAt=function(index){return 0===index?this._fulfillmentHandler0:this[(index<<2)+index-5+0]},Promise.prototype._rejectionHandlerAt=function(index){return 0===index?this._rejectionHandler0:this[(index<<2)+index-5+1]},Promise.prototype._addCallbacks=function(fulfill,reject,progress,promise,receiver){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promise,void 0!==receiver&&(this._receiver0=receiver),"function"!=typeof fulfill||this._isCarryingStackTrace()||(this._fulfillmentHandler0=fulfill),"function"==typeof reject&&(this._rejectionHandler0=reject),"function"==typeof progress&&(this._progressHandler0=progress);else{var base=(index<<2)+index-5;this[base+3]=promise,this[base+4]=receiver,this[base+0]="function"==typeof fulfill?fulfill:void 0,this[base+1]="function"==typeof reject?reject:void 0,this[base+2]="function"==typeof progress?progress:void 0}return this._setLength(index+1),index},Promise.prototype._setProxyHandlers=function(receiver,promiseSlotValue){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promiseSlotValue,this._receiver0=receiver;else{var base=(index<<2)+index-5;this[base+3]=promiseSlotValue,this[base+4]=receiver,this[base+0]=this[base+1]=this[base+2]=void 0}this._setLength(index+1)},Promise.prototype._proxyPromiseArray=function(promiseArray,index){this._setProxyHandlers(promiseArray,index)},Promise.prototype._proxyPromise=function(promise){promise._setProxied(),this._setProxyHandlers(promise,-15)},Promise.prototype._setBoundTo=function(obj){void 0!==obj?(this._bitField=8388608|this._bitField,this._boundTo=obj):this._bitField=-8388609&this._bitField},Promise.prototype._isBound=function(){return 8388608===(8388608&this._bitField)},Promise.prototype._resolveFromResolver=function(resolver){function Promise$_resolver(val){promise._tryFollow(val)||promise._fulfill(val)}function Promise$_rejecter(val){var trace=canAttach(val)?val:new Error(val+"");promise._attachExtraTrace(trace),markAsOriginatingFromRejection(val),promise._reject(val,trace===val?void 0:trace)}var promise=this;this._setTrace(void 0),this._pushContext();var r=tryCatch2(resolver,void 0,Promise$_resolver,Promise$_rejecter);if(this._popContext(),void 0!==r&&r===errorObj){var e=r.e,trace=canAttach(e)?e:new Error(e+"");promise._reject(e,trace)}},Promise.prototype._spreadSlowCase=function(targetFn,promise,values,boundTo){var promiseForAll=new PromiseArray(values).promise(),promise2=promiseForAll._then(function(){return targetFn.apply(boundTo,arguments)},void 0,void 0,APPLY,void 0);promise._follow(promise2)},Promise.prototype._callSpread=function(handler,promise,value){var boundTo=this._boundTo;if(isArray(value))for(var i=0,len=value.length;len>i;++i)if(cast(value[i],void 0)instanceof Promise)return void this._spreadSlowCase(handler,promise,value,boundTo);return promise._pushContext(),tryCatchApply(handler,value,boundTo)},Promise.prototype._callHandler=function(handler,receiver,promise,value){var x;return receiver!==APPLY||this.isRejected()?(promise._pushContext(),x=tryCatch1(handler,receiver,value)):x=this._callSpread(handler,promise,value),promise._popContext(),x},Promise.prototype._settlePromiseFromHandler=function(handler,receiver,value,promise){if(!(promise instanceof Promise))return void handler.call(receiver,value,promise);var x=this._callHandler(handler,receiver,promise,value);if(!promise._isFollowing())if(x===errorObj||x===promise||x===NEXT_FILTER){var err=x===promise?makeSelfResolutionError():x.e,trace=canAttach(err)?err:new Error(err+""); -x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string"); -RemoteStorage.config.cordovaRedirectUri=uri},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.connected=!1,RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),self.online=!0,isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]?!0:!1}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(url,errorHandler,sucessHandler){function __processState(){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"resource not found",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}function __makeRequest(){xhr.onreadystatechange=function(){4===xhr.readyState&&__processState()},xhr.onload=function(a,b){__processState()},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this,xhr=new XMLHttpRequest;return __makeRequest()},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(URL,JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error,request:URL}):generateErrorObject({message:"unknown response from server",request:URL}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){var uri="";return address.split("://")[1]||(uri="acct:"),protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource="+uri+address}function __fallbackChecks(err){if(self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1)return uri_index+=1,__call();if(!self.config.tls_only&&"https"===protocol)return uri_index=0,protocol="http",__call();if(!self.config.webfist_fallback||"webfist.org"===host)return cb(err);uri_index=0,protocol="http",host="webfist.org";var URL=__buildURL();self.__fetchJRD(URL,cb,function(data){self.__processJRD(URL,data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(URL,JRD,cb,function(result){return cb(null,cb)})})})})}function __call(){var URL=__buildURL();self.__fetchJRD(URL,__fallbackChecks,function(JRD){self.__processJRD(URL,JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,host="";host=address.indexOf("://")>-1?address.replace(/ /g,"").split("://")[1]:address.replace(/ /g,"").split("@")[1];var uri_index=0,protocol="https";return self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0)},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId),!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){ -redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href,storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' +x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string"); +RemoteStorage.config.cordovaRedirectUri=uri},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.rs=rs,this.connected=!1,RS.eventHandling(this,"change","connected","not-connected","wire-busy","wire-done"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]?!0:!1}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(url,errorHandler,sucessHandler){function __processState(){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"resource not found",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}function __makeRequest(){xhr.onreadystatechange=function(){4===xhr.readyState&&__processState()},xhr.onload=function(a,b){__processState()},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this,xhr=new XMLHttpRequest;return __makeRequest()},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(URL,JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error,request:URL}):generateErrorObject({message:"unknown response from server",request:URL}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){var uri="";return address.split("://")[1]||(uri="acct:"),protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource="+uri+address}function __fallbackChecks(err){if(self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1)return uri_index+=1,__call();if(!self.config.tls_only&&"https"===protocol)return uri_index=0,protocol="http",__call();if(!self.config.webfist_fallback||"webfist.org"===host)return cb(err);uri_index=0,protocol="http",host="webfist.org";var URL=__buildURL();self.__fetchJRD(URL,cb,function(data){self.__processJRD(URL,data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(URL,JRD,cb,function(result){return cb(null,cb)})})})})}function __call(){var URL=__buildURL();self.__fetchJRD(URL,__fallbackChecks,function(JRD){self.__processJRD(URL,JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,host="";host=address.indexOf("://")>-1?address.replace(/ /g,"").split("://")[1]:address.replace(/ /g,"").split("@")[1];var uri_index=0,protocol="https";return self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0)},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId), +!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href,storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' },function(window){function stateSetter(widget,state,message){return RemoteStorage.log("[Widget] Producing stateSetter for",state),function(){RemoteStorage.log("[Widget] Setting state",state,message),hasLocalStorage&&(localStorage[LS_STATE_KEY]=state),widget.view?(widget.rs.remote&&widget.view.setUserAddress(widget.rs.remote.userAddress),widget.view.setState(state,message)):widget._rememberedState=state}}function errorsHandler(widget){return function(error){var s;error instanceof RemoteStorage.DiscoveryError?(console.error("Discovery failed",error,'"'+error.message+'"'),s=stateSetter(widget,"initial",error.message)):error instanceof RemoteStorage.SyncError?s=stateSetter(widget,"offline"):error instanceof RemoteStorage.Unauthorized?s=stateSetter(widget,"unauthorized"):(RemoteStorage.log("[Widget] Unknown error"),s=stateSetter(widget,"error",[error])),s.apply()}}function flashFor(evt){return"GET"===evt.method&&evt.isFolder?!1:!0}var hasLocalStorage,LS_STATE_KEY="remotestorage:widget:state",VALID_ENTRY_STATES={initial:!0,connected:!0,offline:!0};RemoteStorage.Widget=function(remoteStorage){var self=this,requestsToFlashFor=0;if(this.rs=remoteStorage,this.rs.remote.on("connected",stateSetter(this,"connected")),this.rs.on("disconnected",stateSetter(this,"initial")),this.rs.on("connecting",stateSetter(this,"authing")),this.rs.on("authing",stateSetter(this,"authing")),this.rs.on("error",errorsHandler(this)),this.rs.remote&&(this.rs.remote.on("wire-busy",function(evt){flashFor(evt)&&(requestsToFlashFor++,stateSetter(self,"busy")())}),this.rs.remote.on("wire-done",function(evt){flashFor(evt)&&requestsToFlashFor--,0>=requestsToFlashFor&&evt.success&&stateSetter(self,"connected")()})),hasLocalStorage){var state=localStorage[LS_STATE_KEY];state&&VALID_ENTRY_STATES[state]&&(this._rememberedState=state)}},RemoteStorage.Widget.prototype={display:function(options){return"string"==typeof options?options={domID:options}:"undefined"==typeof options&&(options={}),this.view||this.setView(new RemoteStorage.Widget.View(this.rs)),this.view.display(options),this},linkWidgetToSync:function(){"object"==typeof this.rs.sync&&"function"==typeof this.rs.sync.sync?this.view.on("sync",this.rs.sync.sync.bind(this.rs.sync)):(RemoteStorage.log("[Widget] typeof this.rs.sync check fail",this.rs.sync),setTimeout(this.linkWidgetToSync.bind(this),1e3))},setView:function(view){this.view=view,this.view.on("connect",function(options){"string"==typeof options?this.rs.connect(options):options.special&&this.rs[options.special].connect(options)}.bind(this)),this.view.on("secret-entered",function(secretKey){this.view.setUserSecretKey(secretKey),stateSetter(this,"ciphered")()}.bind(this)),this.view.on("secret-cancelled",function(){stateSetter(this,"notciphered")()}.bind(this)),this.view.on("disconnect",this.rs.disconnect.bind(this.rs)),this.linkWidgetToSync();try{this.view.on("reset",function(){var location=RemoteStorage.Authorize.getLocation();this.rs.on("disconnected",location.reload.bind(location)),this.rs.disconnect()}.bind(this))}catch(e){if(!e.message||!e.message.match(/Unknown event/))throw e}this._rememberedState&&(setTimeout(stateSetter(this,this._rememberedState),0),delete this._rememberedState)}},RemoteStorage.prototype.displayWidget=function(options){return this.widget.display(options)},RemoteStorage.Widget._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.widget||(remoteStorage.widget=new RemoteStorage.Widget(remoteStorage))},RemoteStorage.Widget._rs_supported=function(remoteStorage){return"undefined"!=typeof document}}("undefined"!=typeof window?window:global),function(window){function removeClass(el,className){return el.classList.remove(className)}function addClass(el,className){return el.classList.add(className)}function stopPropagation(event){"function"==typeof event.stopPropagation?event.stopPropagation():event.cancelBubble=!0}function setupButton(parent,className,iconName,eventListener){var element=parent.querySelector("."+className);if("undefined"!=typeof iconName){var img=element.querySelector("img");(img||element).src=RemoteStorage.Assets[iconName]}return element.addEventListener("click",eventListener),element}function handleButtonState(event){event.target.value?event.target.nextElementSibling.removeAttribute("disabled"):event.target.nextElementSibling.setAttribute("disabled","disabled")}var t=RemoteStorage.I18n.translate;RemoteStorage.Widget.View=function(remoteStorage){if(this.rs=remoteStorage,"undefined"==typeof document)throw"Widget not supported";RemoteStorage.eventHandling(this,"connect","secret-entered","secret-cancelled","disconnect","sync","display","reset");for(var event in this.events)this.events[event]=this.events[event].bind(this);this.hideBubbleOnBodyClick=function(event){for(var p=event.target;p!==document.body;p=p.parentElement)if("remotestorage-widget"===p.id)return;this.hideBubble()}.bind(this)},RemoteStorage.Widget.View.prototype={connectGdrive:function(){this._emit("connect",{special:"googledrive"})},connectDropbox:function(){this._emit("connect",{special:"dropbox"})},setState:function(state,message){RemoteStorage.log("[View] widget.view.setState(",state,",",message,");");var s=this.states[state];if("undefined"==typeof s)throw new Error("Bad State assigned to view: "+state);s.apply(this,[message])},setUserAddress:function(addr){this.userAddress=addr||"";var el;this.div&&(el=this.div.querySelector("form.remotestorage-initial").userAddress)&&(el.value=this.userAddress)},setUserSecretKey:function(secretKey){this.userSecretKey=secretKey},toggleBubble:function(event){this.bubble.className.search("rs-hidden")<0?this.hideBubble(event):this.showBubble(event)},hideBubble:function(){addClass(this.bubble,"rs-hidden"),document.body.removeEventListener("click",this.hideBubbleOnBodyClick)},showBubble:function(event){removeClass(this.bubble,"rs-hidden"),"undefined"!=typeof event&&stopPropagation(event),document.body.addEventListener("click",this.hideBubbleOnBodyClick),this.div.querySelector(".remotestorage-connected").classList.contains("remotestorage-cipher")&&!this.userSecretKey?this.bubble.querySelector("form.remotestorage-cipher-form").userSecretKey.focus():this.bubble.querySelector("form.remotestorage-initial").userAddress.focus()},display:function(options){if("undefined"!=typeof this.div)return this.div;var element=document.createElement("div"),style=document.createElement("style");if(style.innerHTML=RemoteStorage.Assets.widgetCss,element.id="remotestorage-widget",element.innerHTML=RemoteStorage.Assets.widget,element.appendChild(style),options.domID){var parent=document.getElementById(options.domID);if(!parent)throw'Failed to find target DOM element with id="'+options.domID+'"';parent.appendChild(element)}else document.body.appendChild(element);setupButton(element,"rs-sync","syncIcon",this.events.sync),setupButton(element,"rs-disconnect","disconnectIcon",this.events.disconnect),setupButton(element,"remotestorage-reset",void 0,this.events.reset);setupButton(element,"connect","connectIcon",this.events.connect);this.form=element.querySelector("form.remotestorage-initial");var el=this.form.userAddress;if(el.addEventListener("load",handleButtonState),el.addEventListener("keyup",handleButtonState),this.userAddress&&(el.value=this.userAddress),options.encryption){this.cipher=!0;var secretKeyInput=element.querySelector("form.remotestorage-cipher-form").userSecretKey;secretKeyInput.type="password";setupButton(element,"rs-cipher","cipherIcon",this.events["secret-entered"]);secretKeyInput.addEventListener("load",handleButtonState),secretKeyInput.addEventListener("keyup",handleButtonState),setupButton(element,"rs-nocipher","nocipherIcon",this.events["secret-cancelled"])}this.cube=setupButton(element,"rs-cube","remoteStorageIcon",this.toggleBubble.bind(this)),setupButton(element,"rs-dropbox","dropbox",this.connectDropbox.bind(this)),setupButton(element,"rs-googledrive","googledrive",this.connectGdrive.bind(this));var bubbleDontCatch={INPUT:!0,BUTTON:!0,IMG:!0},eventListener=function(event){bubbleDontCatch[event.target.tagName]||this.div.classList.contains("remotestorage-state-unauthorized")||this.showBubble(event)}.bind(this);return this.bubble=setupButton(element,"rs-bubble",void 0,eventListener),this.hideBubble(),this.div=element,this.states.initial.call(this),this.events.display.call(this),this.div},states:{initial:function(message){var cube=this.cube,info=message||t("view_info");cube.src=RemoteStorage.Assets.remoteStorageIcon,this._renderTranslatedInitialContent(),message?(cube.src=RemoteStorage.Assets.remoteStorageIconError,removeClass(this.cube,"remotestorage-loading"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},2e3)):this.hideBubble(),this.div.className="remotestorage-state-initial",this.userSecretKey&&delete this.userSecretKey;var backends=1;this._activateBackend("dropbox")&&(backends+=1),this._activateBackend("googledrive")&&(backends+=1),this.div.querySelector(".rs-bubble-text").style.paddingRight=32*backends+8+"px";var cb=this.div.querySelector(".connect");this.form.userAddress.value&&cb.removeAttribute("disabled");var infoEl=this.div.querySelector(".rs-info-msg");infoEl.innerHTML=info,message?infoEl.classList.add("remotestorage-error-info"):infoEl.classList.remove("remotestorage-error-info")},authing:function(){this.div.removeEventListener("click",this.events.connect),this.div.className="remotestorage-state-authing",this.div.querySelector(".rs-status-text").innerHTML=t("view_connecting",this.userAddress),addClass(this.cube,"remotestorage-loading")},connected:function(){var cube=this.cube;this.div.className="remotestorage-state-connected",this.div.querySelector(".userAddress").innerHTML=this.userAddress,cube.src=RemoteStorage.Assets.remoteStorageIcon,removeClass(cube,"remotestorage-loading"),this.cipher&&(this.userSecretKey?this.userSecretKeyError?(cube.src=RemoteStorage.Assets.remoteStorageIconError,addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),addClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},5e3)):(removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),cube.src=RemoteStorage.Assets.remoteStorageIconCiphered):(addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.showBubble()));var icons={googledrive:this.div.querySelector(".rs-googledrive"),dropbox:this.div.querySelector(".rs-dropbox")};icons.googledrive.style.display=icons.dropbox.style.display="none",icons[this.rs.backend]?(icons[this.rs.backend].style.display="inline-block",this.div.querySelector(".rs-bubble-text").style.paddingRight="72px"):this.div.querySelector(".rs-bubble-text").style.paddingRight="40px"},ciphered:function(){this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value="",removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.cube.src=RemoteStorage.Assets.remoteStorageIconCiphered,this.hideBubble()},notciphered:function(){this.cipher=!1,removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.hideBubble()},busy:function(){this.div.className="remotestorage-state-busy",addClass(this.cube,"remotestorage-loading")},offline:function(){this.div.className="remotestorage-state-offline",this.cube.src=RemoteStorage.Assets.remoteStorageIconOffline,this.div.querySelector(".rs-status-text").innerHTML=t("view_offline")},error:function(err){var errorMsg=err;this.div.className="remotestorage-state-error",this.div.querySelector(".rs-bubble-text").innerHTML=""+t("view_error_occured")+"",err instanceof Error&&(errorMsg=err.message+"\n\n"+err.stack),this.div.querySelector(".rs-error-msg").textContent=errorMsg,this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble()},unauthorized:function(){this.div.className="remotestorage-state-unauthorized",this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble(),this.div.addEventListener("click",this.events.connect)}},events:{connect:function(event){stopPropagation(event),event.preventDefault(),this._emit("connect",this.div.querySelector("form.remotestorage-initial").userAddress.value)},"secret-entered":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-entered",this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value)},"secret-cancelled":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-cancelled")},sync:function(event){stopPropagation(event),event.preventDefault(),this._emit("sync")},disconnect:function(event){stopPropagation(event),event.preventDefault(),this._emit("disconnect")},reset:function(event){event.preventDefault();var result=window.confirm(t("view_confirm_reset"));result&&this._emit("reset")},display:function(event){event&&event.preventDefault(),this._emit("display")}},_renderTranslatedInitialContent:function(){this.div.querySelector(".rs-status-text").innerHTML=t("view_connect"),this.div.querySelector(".remotestorage-reset").innerHTML=t("view_get_me_out"),this.div.querySelector(".rs-error-plz-report").innerHTML=t("view_error_plz_report"),this.div.querySelector(".remotestorage-unauthorized").innerHTML=t("view_unauthorized"),this.div.querySelector(".remotestorage-invalid-key").innerHTML=t("view_invalid_key")},_activateBackend:function(backendName){var className="rs-"+backendName;return this.rs.apiKeys[backendName]?(this.div.querySelector("."+className).style.display="inline-block",!0):(this.div.querySelector("."+className).style.display="none",!1)}}}("undefined"!=typeof window?window:global),function(global,factory){"function"==typeof define&&define.amd?define([],factory):"undefined"!=typeof module&&module.exports?module.exports=factory():global.tv4=factory()}(this,function(){function notReallyPercentEncode(string){return encodeURI(string).replace(/%25[0-9][0-9]/g,function(doubleEncoded){return"%"+doubleEncoded.substring(3)})}function uriTemplateSubstitution(spec){var modifier="";uriTemplateGlobalModifiers[spec.charAt(0)]&&(modifier=spec.charAt(0),spec=spec.substring(1));var separator="",prefix="",shouldEscape=!0,showVariables=!1,trimEmptyString=!1;"+"===modifier?shouldEscape=!1:"."===modifier?(prefix=".",separator="."):"/"===modifier?(prefix="/",separator="/"):"#"===modifier?(prefix="#",shouldEscape=!1):";"===modifier?(prefix=";",separator=";",showVariables=!0,trimEmptyString=!0):"?"===modifier?(prefix="?",separator="&",showVariables=!0):"&"===modifier&&(prefix="&",separator="&",showVariables=!0);for(var varNames=[],varList=spec.split(","),varSpecs=[],varSpecMap={},i=0;i0&&(result+=varSpec.suffices["*"]?separator||",":",",varSpec.suffices["*"]&&showVariables&&(result+=varSpec.name+"=")),result+=shouldEscape?encodeURIComponent(value[j]).replace(/!/g,"%21"):notReallyPercentEncode(value[j])}else if("object"==typeof value){showVariables&&!varSpec.suffices["*"]&&(result+=varSpec.name+"=");var first=!0;for(var key in value)first||(result+=varSpec.suffices["*"]?separator||",":","),first=!1,result+=shouldEscape?encodeURIComponent(key).replace(/!/g,"%21"):notReallyPercentEncode(key),result+=varSpec.suffices["*"]?"=":",",result+=shouldEscape?encodeURIComponent(value[key]).replace(/!/g,"%21"):notReallyPercentEncode(value[key])}else showVariables&&(result+=varSpec.name,trimEmptyString&&""===value||(result+="=")),null!=varSpec.truncate&&(value=value.substring(0,varSpec.truncate)),result+=shouldEscape?encodeURIComponent(value).replace(/!/g,"%21"):notReallyPercentEncode(value)}return result};return subFunction.varNames=varNames,{prefix:prefix,substitution:subFunction}}function UriTemplate(template){if(!(this instanceof UriTemplate))return new UriTemplate(template);for(var parts=template.split("{"),textParts=[parts.shift()],prefixes=[],substitutions=[],varNames=[];parts.length>0;){var part=parts.shift(),spec=part.split("}")[0],remainder=part.substring(spec.length+1),funcs=uriTemplateSubstitution(spec);substitutions.push(funcs.substitution),prefixes.push(funcs.prefix),textParts.push(remainder),varNames=varNames.concat(funcs.substitution.varNames)}this.fill=function(valueFunction){for(var result=textParts[0],i=0;i0&&"/"===testUrl.charAt(baseUrl.length-1)||"#"===remainder.charAt(0)||"?"===remainder.charAt(0))return!0}return!1}function createApi(language){var currentLanguage,customErrorReporter,globalContext=new ValidatorContext,api={setErrorReporter:function(reporter){return"string"==typeof reporter?this.language(reporter):(customErrorReporter=reporter,!0)},addFormat:function(){globalContext.addFormat.apply(globalContext,arguments)},language:function(code){return code?(languages[code]||(code=code.split("-")[0]),languages[code]?(currentLanguage=code,code):!1):currentLanguage},addLanguage:function(code,messageMap){var key;for(key in ErrorCodes)messageMap[key]&&!messageMap[ErrorCodes[key]]&&(messageMap[ErrorCodes[key]]=messageMap[key]);var rootCode=code.split("-")[0];if(languages[rootCode]){languages[code]=Object.create(languages[rootCode]);for(key in messageMap)"undefined"==typeof languages[rootCode][key]&&(languages[rootCode][key]=messageMap[key]),languages[code][key]=messageMap[key]}else languages[code]=messageMap,languages[rootCode]=messageMap;return this},freshApi:function(language){var result=createApi();return language&&result.language(language),result},validate:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!1,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema);var error=context.validateAll(data,schema,null,null,"");return!error&&banUnknownProperties&&(error=context.banUnknownProperties(data,schema)),this.error=error,this.missing=context.missing,this.valid=null===error,this.valid},validateResult:function(){var result={};return this.validate.apply(result,arguments),result},validateMultiple:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!0,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema),context.validateAll(data,schema,null,null,""),banUnknownProperties&&context.banUnknownProperties(data,schema);var result={};return result.errors=context.errors,result.missing=context.missing,result.valid=0===result.errors.length,result},addSchema:function(){return globalContext.addSchema.apply(globalContext,arguments)},getSchema:function(){return globalContext.getSchema.apply(globalContext,arguments)},getSchemaMap:function(){return globalContext.getSchemaMap.apply(globalContext,arguments)},getSchemaUris:function(){return globalContext.getSchemaUris.apply(globalContext,arguments)},getMissingUris:function(){return globalContext.getMissingUris.apply(globalContext,arguments)},dropSchemas:function(){globalContext.dropSchemas.apply(globalContext,arguments)},defineKeyword:function(){globalContext.defineKeyword.apply(globalContext,arguments)},defineError:function(codeName,codeNumber,defaultMessage){if("string"!=typeof codeName||!/^[A-Z]+(_[A-Z]+)*$/.test(codeName))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof codeNumber||codeNumber%1!==0||1e4>codeNumber)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof ErrorCodes[codeName])throw new Error("Error already defined: "+codeName+" as "+ErrorCodes[codeName]);if("undefined"!=typeof ErrorCodeLookup[codeNumber])throw new Error("Error code already used: "+ErrorCodeLookup[codeNumber]+" as "+codeNumber);ErrorCodes[codeName]=codeNumber,ErrorCodeLookup[codeNumber]=codeName,ErrorMessagesDefault[codeName]=ErrorMessagesDefault[codeNumber]=defaultMessage;for(var langCode in languages){var language=languages[langCode];language[codeName]&&(language[codeNumber]=language[codeNumber]||language[codeName])}},reset:function(){globalContext.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:normSchema,resolveUrl:resolveUrl,getDocumentUri:getDocumentUri,errorCodes:ErrorCodes};return api.language(language||"en"),api}Object.keys||(Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if("object"!=typeof obj&&"function"!=typeof obj||null===obj)throw new TypeError("Object.keys called on non-object");var result=[];for(var prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(var i=0;dontEnumsLength>i;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result}}()),Object.create||(Object.create=function(){function F(){}return function(o){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Array.isArray||(Array.isArray=function(vArg){return"[object Array]"===Object.prototype.toString.call(vArg)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(searchElement){if(null===this)throw new TypeError;var t=Object(this),len=t.length>>>0;if(0===len)return-1;var n=0;if(arguments.length>1&&(n=Number(arguments[1]),n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=len)return-1;for(var k=n>=0?n:Math.max(len-Math.abs(n),0);len>k;k++)if(k in t&&t[k]===searchElement)return k;return-1}),Object.isFrozen||(Object.isFrozen=function(obj){for(var key="tv4_test_frozen_key";obj.hasOwnProperty(key);)key+=Math.random();try{return obj[key]=!0,delete obj[key],!1}catch(e){return!0}});var uriTemplateGlobalModifiers={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},uriTemplateSuffices={"*":!0};UriTemplate.prototype={toString:function(){return this.template},fillFromObject:function(obj){return this.fill(function(varName){return obj[varName]})}};var ValidatorContext=function(parent,collectMultiple,errorReporter,checkRecursive,trackUnknownProperties){if(this.missing=[],this.missingMap={},this.formatValidators=parent?Object.create(parent.formatValidators):{},this.schemas=parent?Object.create(parent.schemas):{},this.collectMultiple=collectMultiple,this.errors=[],this.handleError=collectMultiple?this.collectError:this.returnError,checkRecursive&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),trackUnknownProperties&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=errorReporter||defaultErrorReporter("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},parent)for(var key in parent.definedKeywords)this.definedKeywords[key]=parent.definedKeywords[key].slice(0)};ValidatorContext.prototype.defineKeyword=function(keyword,keywordFunction){this.definedKeywords[keyword]=this.definedKeywords[keyword]||[],this.definedKeywords[keyword].push(keywordFunction)},ValidatorContext.prototype.createError=function(code,messageParams,dataPath,schemaPath,subErrors,data,schema){var error=new ValidationError(code,messageParams,dataPath,schemaPath,subErrors);return error.message=this.errorReporter(error,data,schema),error},ValidatorContext.prototype.returnError=function(error){return error},ValidatorContext.prototype.collectError=function(error){return error&&this.errors.push(error),null},ValidatorContext.prototype.prefixErrors=function(startIndex,dataPath,schemaPath){for(var i=startIndex;i=CLOSE_ENOUGH_LOW&&CLOSE_ENOUGH_HIGH>remainder)return this.createError(ErrorCodes.NUMBER_MULTIPLE_OF,{value:data,multipleOf:multipleOf},"","",null,data,schema)}return null},ValidatorContext.prototype.validateMinMax=function(data,schema){if("number"!=typeof data)return null;if(void 0!==schema.minimum){if(dataschema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM,{value:data,maximum:schema.maximum},"","/maximum",null,data,schema);if(schema.exclusiveMaximum&&data===schema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM_EXCLUSIVE,{value:data,maximum:schema.maximum},"","/exclusiveMaximum",null,data,schema)}return null},ValidatorContext.prototype.validateNaN=function(data,schema){return"number"!=typeof data?null:isNaN(data)===!0||data===1/0||data===-(1/0)?this.createError(ErrorCodes.NUMBER_NOT_A_NUMBER,{value:data},"","/type",null,data,schema):null},ValidatorContext.prototype.validateString=function(data,schema,dataPointerPath){return this.validateStringLength(data,schema,dataPointerPath)||this.validateStringPattern(data,schema,dataPointerPath)||null},ValidatorContext.prototype.validateStringLength=function(data,schema){return"string"!=typeof data?null:void 0!==schema.minLength&&data.lengthschema.maxLength?this.createError(ErrorCodes.STRING_LENGTH_LONG,{length:data.length,maximum:schema.maxLength},"","/maxLength",null,data,schema):null},ValidatorContext.prototype.validateStringPattern=function(data,schema){if("string"!=typeof data||"string"!=typeof schema.pattern&&!(schema.pattern instanceof RegExp))return null;var regexp;if(schema.pattern instanceof RegExp)regexp=schema.pattern;else{var body,flags="",literal=schema.pattern.match(/^\/(.+)\/([img]*)$/);literal?(body=literal[1],flags=literal[2]):body=schema.pattern,regexp=new RegExp(body,flags)}return regexp.test(data)?null:this.createError(ErrorCodes.STRING_PATTERN,{pattern:schema.pattern},"","/pattern",null,data,schema)},ValidatorContext.prototype.validateArray=function(data,schema,dataPointerPath){return Array.isArray(data)?this.validateArrayLength(data,schema,dataPointerPath)||this.validateArrayUniqueItems(data,schema,dataPointerPath)||this.validateArrayItems(data,schema,dataPointerPath)||null:null},ValidatorContext.prototype.validateArrayLength=function(data,schema){var error;return void 0!==schema.minItems&&data.lengthschema.maxItems&&(error=this.createError(ErrorCodes.ARRAY_LENGTH_LONG,{length:data.length,maximum:schema.maxItems},"","/maxItems",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateArrayUniqueItems=function(data,schema){if(schema.uniqueItems)for(var i=0;ischema.maxProperties&&(error=this.createError(ErrorCodes.OBJECT_PROPERTIES_MAXIMUM,{propertyCount:keys.length,maximum:schema.maxProperties},"","/maxProperties",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateObjectRequiredProperties=function(data,schema){if(void 0!==schema.required)for(var i=0;ii;i++)uuid[i]=chars[0|Math.random()*radix];else{var r;for(uuid[8]=uuid[13]=uuid[18]=uuid[23]="-",uuid[14]="4",i=0;36>i;i++)uuid[i]||(r=0|16*Math.random(),uuid[i]=chars[19==i?3&r|8:r])}return uuid.join("")},function(global){function deprecate(thing,replacement){console.log("WARNING: "+thing+" is deprecated. Use "+replacement+" instead.")}var RS=RemoteStorage;RS.BaseClient=function(storage,base){if("/"!==base[base.length-1])throw"Not a folder: "+base;"/"===base&&(this.makePath=function(path){return("/"===path[0]?"":"/")+path}),this.storage=storage,this.base=base;var parts=this.base.split("/");parts.length>2?this.moduleName=parts[1]:this.moduleName="root",RS.eventHandling(this,"change"),this.on=this.on.bind(this),storage.onChange(this.base,this._fireChange.bind(this))},RS.BaseClient.prototype={extend:function(object){for(var key in object)this[key]=object[key];return this},scope:function(path){return new RS.BaseClient(this.storage,this.makePath(path))},getListing:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){return 404===r.statusCode?{}:r.body})},getAll:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){if(404===r.statusCode)return{};if("object"==typeof r.body){var keys=Object.keys(r.body);if(0===keys.length)return{};var calls=keys.map(function(key){return this.storage.get(this.makePath(path+key),maxAge).then(function(o){if("string"==typeof o.body)try{o.body=JSON.parse(o.body)}catch(e){}"object"==typeof o.body&&(r.body[key]=o.body)})}.bind(this));return Promise.all(calls).then(function(){return r.body})}}.bind(this))},getFile:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getFile must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){return{data:r.body,contentType:r.contentType,revision:r.revision}})},storeFile:function(mimeType,path,body){return"string"!=typeof mimeType?Promise.reject("Argument 'mimeType' of baseClient.storeFile must be a string"):"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.storeFile must be a string"):"string"!=typeof body&&"object"!=typeof body?Promise.reject("Argument 'body' of baseClient.storeFile must be a string, ArrayBuffer, or ArrayBufferView"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Editing a document to which only read access ('r') was claimed"),this.storage.put(this.makePath(path),body,mimeType).then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this)))},getObject:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getObject must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){if("object"==typeof r.body)return r.body;if("string"==typeof r.body)try{return JSON.parse(r.body)}catch(e){throw"Not valid JSON: "+this.makePath(path)}else if("undefined"!=typeof r.body&&200===r.statusCode)return Promise.reject("Not an object: "+this.makePath(path))}.bind(this))},storeObject:function(typeAlias,path,object){if("string"!=typeof typeAlias)return Promise.reject("Argument 'typeAlias' of baseClient.storeObject must be a string");if("string"!=typeof path)return Promise.reject("Argument 'path' of baseClient.storeObject must be a string");if("object"!=typeof object)return Promise.reject("Argument 'object' of baseClient.storeObject must be an object");this._attachType(object,typeAlias);try{var validationResult=this.validate(object);if(!validationResult.valid)return Promise.reject(validationResult)}catch(exc){return Promise.reject(exc)}return this.storage.put(this.makePath(path),JSON.stringify(object),"application/json; charset=UTF-8").then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this))},remove:function(path){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.remove must be a string"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Removing a document to which only read access ('r') was claimed"),this.storage["delete"](this.makePath(path)))},cache:function(path,strategy){if("string"!=typeof path)throw"Argument 'path' of baseClient.cache must be a string";if(strategy===!1?(deprecate("caching strategy ",'<"FLUSH">'),strategy="FLUSH"):void 0===strategy?strategy="ALL":"string"!=typeof strategy&&(deprecate("that caching strategy",'<"ALL">'),strategy="ALL"),"FLUSH"!==strategy&&"SEEN"!==strategy&&"ALL"!==strategy)throw'Argument \'strategy\' of baseclient.cache must be one of ["FLUSH", "SEEN", "ALL"]';return this.storage.caching.set(this.makePath(path),strategy),this},flush:function(path){return this.storage.local.flush(path)},makePath:function(path){return this.base+(path||"")},_fireChange:function(event){RemoteStorage.config.changeEvents[event.origin]&&(["new","old","lastCommon"].forEach(function(fieldNamePrefix){if((!event[fieldNamePrefix+"ContentType"]||/^application\/(.*)json(.*)/.exec(event[fieldNamePrefix+"ContentType"]))&&"string"==typeof event[fieldNamePrefix+"Value"])try{event[fieldNamePrefix+"Value"]=JSON.parse(event[fieldNamePrefix+"Value"])}catch(e){}}),this._emit("change",event))},_cleanPath:RemoteStorage.util.cleanPath,getItemURL:function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.getItemURL must be a string";return this.storage.connected?(path=this._cleanPath(this.makePath(path)),this.storage.remote.href+path):void 0},uuid:function(){return Math.uuid()}},RS.BaseClient._rs_init=function(){RS.prototype.scope=function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.scope must be a string";if(!this.access.checkPathPermission(path,"r")){var escapedPath=path.replace(/(['\\])/g,"\\$1");console.warn("WARNING: please call remoteStorage.access.claim('"+escapedPath+"', 'r') (read only) or remoteStorage.access.claim('"+escapedPath+"', 'rw') (read/write) first")}return new RS.BaseClient(this,path)}}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.BaseClient.Types={uris:{},schemas:{},aliases:{},declare:function(moduleName,alias,uri,schema){var fullAlias=moduleName+"/"+alias;if(schema["extends"]){var extendedAlias,parts=schema["extends"].split("/");extendedAlias=1===parts.length?moduleName+"/"+parts.shift():parts.join("/");var extendedUri=this.uris[extendedAlias];if(!extendedUri)throw"Type '"+fullAlias+"' tries to extend unknown schema '"+extendedAlias+"'";schema["extends"]=this.schemas[extendedUri]}this.uris[fullAlias]=uri,this.aliases[uri]=fullAlias,this.schemas[uri]=schema},resolveAlias:function(alias){return this.uris[alias]},getSchema:function(uri){return this.schemas[uri]},inScope:function(moduleName){var ml=moduleName.length,schemas={};for(var alias in this.uris)if(alias.substr(0,ml+1)===moduleName+"/"){var uri=this.uris[alias];schemas[uri]=this.schemas[uri]}return schemas}};var SchemaNotFound=function(uri){var error=new Error("Schema not found: "+uri);return error.name="SchemaNotFound",error};SchemaNotFound.prototype=Error.prototype,RemoteStorage.BaseClient.Types.SchemaNotFound=SchemaNotFound,RemoteStorage.BaseClient.prototype.extend({declareType:function(alias,uri,schema){schema||(schema=uri,uri=this._defaultTypeURI(alias)),RemoteStorage.BaseClient.Types.declare(this.moduleName,alias,uri,schema)},validate:function(object){var schema=RemoteStorage.BaseClient.Types.getSchema(object["@context"]);if(schema)return tv4.validateResult(object,schema);throw new SchemaNotFound(object["@context"])},_defaultTypeURI:function(alias){return"http://remotestorage.io/spec/modules/"+encodeURIComponent(this.moduleName)+"/"+encodeURIComponent(alias)},_attachType:function(object,alias){object["@context"]=RemoteStorage.BaseClient.Types.resolveAlias(this.moduleName+"/"+alias)||this._defaultTypeURI(alias)}}),Object.defineProperty(RemoteStorage.BaseClient.prototype,"schemas",{configurable:!0,get:function(){return RemoteStorage.BaseClient.Types.inScope(this.moduleName)}})}("undefined"!=typeof window?window:global),function(){RemoteStorage.MODULES={},RemoteStorage.defineModule=function(moduleName,builder){if(RemoteStorage.MODULES[moduleName]=builder, -Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,RS.WireClient.request(method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():xhr})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){rs._emit("error",new RemoteStorage.SyncError(err))})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?global.setTimeout(self._request(method,url,options),3210):Promise.resolve(xhr)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return;rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),promise.reject(err)}).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response)}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):((200===resp.status||404===resp.status)&&(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file +Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",isFolder=RemoteStorage.util.isFolder,Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){return rs._emit("error",new RemoteStorage.SyncError(err)),Promise.reject(err)})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",isFolder=RemoteStorage.util.isFolder,getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?(self.online&&(self.online=!1,self.rs._emit("network-offline")),global.setTimeout(self._request(method,url,options),3210)):(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return;rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){return this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),Promise.resolve(args)}.bind(this)).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response)}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):((200===resp.status||404===resp.status)&&(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file diff --git a/release/head/remotestorage.amd.js b/release/head/remotestorage.amd.js index db2bfe119..22bef1ae8 100644 --- a/release/head/remotestorage.amd.js +++ b/release/head/remotestorage.amd.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.1-pre, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ define([], function() { /** FILE: src/remotestorage.js **/ @@ -171,6 +171,18 @@ define([], function() { * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -180,8 +192,9 @@ define([], function() { RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -316,6 +329,20 @@ define([], function() { * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -1617,6 +1644,7 @@ define([], function() { * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -1628,7 +1656,8 @@ define([], function() { * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -1714,13 +1743,17 @@ define([], function() { body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -1756,11 +1789,16 @@ define([], function() { } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -7378,7 +7416,6 @@ Math.uuid = function (len, radix) { error = new RemoteStorage.Unauthorized(); } else if (status.networkProblems) { error = new RemoteStorage.SyncError('Network request failed.'); - this.remote.online = false; } else { error = new Error('HTTP response code ' + status.statusCode + ' received.'); } @@ -7409,7 +7446,6 @@ Math.uuid = function (len, radix) { .then(function (completed) { delete self._timeStarted[task.path]; delete self._running[task.path]; - self.remote.online = true; if (completed) { if (self._tasks[task.path]) { @@ -8994,6 +9030,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -9359,15 +9397,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); } - return xhr; + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -9444,6 +9512,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -10012,15 +10082,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -10099,8 +10203,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -10248,7 +10352,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -10257,6 +10361,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -10267,7 +10372,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/head/remotestorage.js b/release/head/remotestorage.js index 6c868b9a5..b5ebcaa9d 100644 --- a/release/head/remotestorage.js +++ b/release/head/remotestorage.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.1-pre, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ /** FILE: lib/bluebird.js **/ /** @@ -3441,6 +3441,18 @@ module.exports = ret; * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -3450,8 +3462,9 @@ module.exports = ret; RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -3586,6 +3599,20 @@ module.exports = ret; * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -4887,6 +4914,7 @@ module.exports = ret; * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -4898,7 +4926,8 @@ module.exports = ret; * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -4984,13 +5013,17 @@ module.exports = ret; body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -5026,11 +5059,16 @@ module.exports = ret; } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -10648,7 +10686,6 @@ Math.uuid = function (len, radix) { error = new RemoteStorage.Unauthorized(); } else if (status.networkProblems) { error = new RemoteStorage.SyncError('Network request failed.'); - this.remote.online = false; } else { error = new Error('HTTP response code ' + status.statusCode + ' received.'); } @@ -10679,7 +10716,6 @@ Math.uuid = function (len, radix) { .then(function (completed) { delete self._timeStarted[task.path]; delete self._running[task.path]; - self.remote.online = true; if (completed) { if (self._tasks[task.path]) { @@ -12264,6 +12300,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -12629,15 +12667,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); } - return xhr; + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -12714,6 +12782,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -13282,15 +13352,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -13369,8 +13473,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -13518,7 +13622,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -13527,6 +13631,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -13537,7 +13642,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/head/remotestorage.min.js b/release/head/remotestorage.min.js index e415ed35c..2cbe3751e 100644 --- a/release/head/remotestorage.min.js +++ b/release/head/remotestorage.min.js @@ -1,10 +1,10 @@ -/** remotestorage.js 0.13.1-pre, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o0},Async.prototype.invokeLater=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn)),this._lateBuffer.push(fn,receiver,arg),this._queueTick()},Async.prototype.invoke=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn));var functionBuffer=this._functionBuffer;functionBuffer.push(fn,receiver,arg),this._length=functionBuffer.length(),this._queueTick()},Async.prototype._consumeFunctionBuffer=function(){for(var functionBuffer=this._functionBuffer;functionBuffer.length()>0;){var fn=functionBuffer.shift(),receiver=functionBuffer.shift(),arg=functionBuffer.shift();fn.call(receiver,arg)}this._reset(),this._consumeLateBuffer()},Async.prototype._consumeLateBuffer=function(){for(var buffer=this._lateBuffer;buffer.length()>0;){var fn=buffer.shift(),receiver=buffer.shift(),arg=buffer.shift(),res=tryCatch1(fn,receiver,arg);if(res===errorObj){if(this._queueTick(),null==fn.domain)throw res.e;fn.domain.emit("error",res.e)}}},Async.prototype._queueTick=function(){this._isTickUsed||(this._schedule(this.consumeFunctionBuffer),this._isTickUsed=!0)},Async.prototype._reset=function(){this._isTickUsed=!1,this._length=0},module.exports=new Async},{"./queue.js":15,"./schedule.js":16,"./util.js":19}],2:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise.js")();module.exports=Promise},{"./promise.js":12}],3:[function(_dereq_,module,exports){"use strict";module.exports=function(){function formatNonError(obj){var str;if("function"==typeof obj)str="[function "+(obj.name||"anonymous")+"]";else{str=obj.toString();var ruselessToString=/\[object [a-zA-Z0-9$_]+\]/;if(ruselessToString.test(str))try{var newStr=JSON.stringify(obj);str=newStr}catch(e){}0===str.length&&(str="(empty array)")}return"(<"+snip(str)+">, no stack trace)"}function snip(str){var maxChars=41;return str.length=0;--i){var line=prev[i];if(current[curLast]!==line)break;current.pop(),curLast--}current.push("From previous event:");for(var lines=current.concat(prev),ret=[],i=0,len=lines.length;len>i;++i)rignore.test(lines[i])&&rtraceline.test(lines[i])||i>0&&!rtraceline.test(lines[i])&&"From previous event:"!==lines[i]||ret.push(lines[i]);return ret},CapturedTrace.protectErrorMessageNewlines=function(stack){for(var i=0;i=i)){for(var errorMessageLines=[],j=0;i>j;++j)errorMessageLines.push(stack.shift());stack.unshift(errorMessageLines.join("\x00"))}},CapturedTrace.isSupported=function(){return"function"==typeof captureStackTrace};var captureStackTrace=function stackDetection(){if("number"==typeof Error.stackTraceLimit&&"function"==typeof Error.captureStackTrace){rtraceline=/^\s*at\s*/,formatStack=function(stack,error){return"string"==typeof stack?stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)};var captureStackTrace=Error.captureStackTrace;return function(receiver,ignoreUntil){captureStackTrace(receiver,ignoreUntil)}}var err=new Error;if("string"==typeof err.stack&&"function"==typeof"".startsWith&&err.stack.startsWith("stackDetection@")&&"stackDetection"===stackDetection.name){defineProperty(Error,"stackTraceLimit",{writable:!0,enumerable:!1,configurable:!1,value:25}),rtraceline=/@/;var rline=/[@\n]/;return formatStack=function(stack,error){return"string"==typeof stack?error.name+". "+error.message+"\n"+stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)},function(o){for(var stack=(new Error).stack,split=stack.split(rline),len=split.length,ret="",i=0;len>i;i+=2)ret+=split[i],ret+="@",ret+=split[i+1],ret+="\n";o.stack=ret}}return formatStack=function(stack,error){return"string"==typeof stack?stack:"object"!=typeof error&&"function"!=typeof error||void 0===error.name||void 0===error.message?formatNonError(error):error.name+". "+error.message},null}();return CapturedTrace}},{"./es5.js":8,"./util.js":19}],4:[function(_dereq_,module,exports){"use strict";module.exports=function(NEXT_FILTER){function CatchFilter(instances,callback,promise){this._instances=instances,this._callback=callback,this._promise=promise}function CatchFilter$_safePredicate(predicate,e){var safeObject={},retfilter=tryCatch1(predicate,safeObject,e);if(retfilter===errorObj)return retfilter;var safeKeys=keys(safeObject);return safeKeys.length?(errorObj.e=new TypeError("Catch filter must inherit from Error or be a simple predicate function"),errorObj):retfilter}var util=_dereq_("./util.js"),errors=_dereq_("./errors.js"),tryCatch1=util.tryCatch1,errorObj=util.errorObj,keys=_dereq_("./es5.js").keys,TypeError=errors.TypeError;return CatchFilter.prototype.doFilter=function(e){for(var cb=this._callback,promise=this._promise,boundTo=promise._boundTo,i=0,len=this._instances.length;len>i;++i){var item=this._instances[i],itemIsErrorType=item===Error||null!=item&&item.prototype instanceof Error;if(itemIsErrorType&&e instanceof item){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}if("function"==typeof item&&!itemIsErrorType){var shouldHandle=CatchFilter$_safePredicate(item,e);if(shouldHandle===errorObj){var trace=errors.canAttach(errorObj.e)?errorObj.e:new Error(errorObj.e+"");this._promise._attachExtraTrace(trace),e=errorObj.e;break}if(shouldHandle){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}}}return NEXT_FILTER.e=e,NEXT_FILTER},CatchFilter}},{"./errors.js":6,"./es5.js":8,"./util.js":19}],5:[function(_dereq_,module,exports){"use strict";var util=_dereq_("./util.js"),isPrimitive=util.isPrimitive,wrapsPrimitiveReceiver=util.wrapsPrimitiveReceiver;module.exports=function(Promise){var returner=function(){return this},thrower=function(){throw this},wrapper=function(value,action){return 1===action?function(){throw value}:2===action?function(){return value}:void 0};Promise.prototype["return"]=Promise.prototype.thenReturn=function(value){return wrapsPrimitiveReceiver&&isPrimitive(value)?this._then(wrapper(value,2),void 0,void 0,void 0,void 0):this._then(returner,void 0,void 0,value,void 0)},Promise.prototype["throw"]=Promise.prototype.thenThrow=function(reason){return wrapsPrimitiveReceiver&&isPrimitive(reason)?this._then(wrapper(reason,1),void 0,void 0,void 0,void 0):this._then(thrower,void 0,void 0,reason,void 0)}}},{"./util.js":19}],6:[function(_dereq_,module,exports){"use strict";function markAsOriginatingFromRejection(e){try{notEnumerableProp(e,"isOperational",!0)}catch(ignore){}}function originatesFromRejection(e){return null==e?!1:e instanceof OperationalError||e.isOperational===!0}function isError(obj){return obj instanceof Error}function canAttach(obj){return isError(obj)}function subError(nameProperty,defaultMessage){function SubError(message){return this instanceof SubError?(this.message="string"==typeof message?message:defaultMessage,this.name=nameProperty,void(Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor))):new SubError(message)}return inherits(SubError,Error),SubError}function OperationalError(message){this.name="OperationalError",this.message=message,this.cause=message,this.isOperational=!0,message instanceof Error?(this.message=message.message,this.stack=message.stack):Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}var _TypeError,_RangeError,Objectfreeze=_dereq_("./es5.js").freeze,util=_dereq_("./util.js"),inherits=util.inherits,notEnumerableProp=util.notEnumerableProp,CancellationError=subError("CancellationError","cancellation error"),TimeoutError=subError("TimeoutError","timeout error"),AggregateError=subError("AggregateError","aggregate error");try{_TypeError=TypeError,_RangeError=RangeError}catch(e){_TypeError=subError("TypeError","type error"),_RangeError=subError("RangeError","range error")}for(var methods="join pop push shift unshift slice filter forEach some every map indexOf lastIndexOf reduce reduceRight sort reverse".split(" "),i=0;i=i;++i)values.push("holder.p"+i);return new Function("holder"," \n 'use strict'; \n var callback = holder.fn; \n return callback(values); \n ".replace(/values/g,values.join(", ")))},thenCallbacks=[],callers=[void 0],i=1;5>=i;++i)thenCallbacks.push(thenCallback(i)),callers.push(caller(i));var Holder=function(total,fn){this.p1=this.p2=this.p3=this.p4=this.p5=null,this.fn=fn,this.total=total,this.now=0};Holder.prototype.callers=callers,Holder.prototype.checkFulfillment=function(promise){var now=this.now;now++;var total=this.total;if(now>=total){var handler=this.callers[total],ret=tryCatch1(handler,void 0,this);ret===errorObj?promise._rejectUnchecked(ret.e):promise._tryFollow(ret)||promise._fulfillUnchecked(ret)}else this.now=now}}Promise.join=function(){var fn,last=arguments.length-1;if(last>0&&"function"==typeof arguments[last]&&(fn=arguments[last],6>last&&canEvaluate)){var ret=new Promise(INTERNAL);ret._setTrace(void 0);for(var holder=new Holder(last,fn),reject=ret._reject,callbacks=thenCallbacks,i=0;last>i;++i){var maybePromise=cast(arguments[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._then(callbacks[i],reject,void 0,ret,holder):maybePromise.isFulfilled()?callbacks[i].call(ret,maybePromise._settledValue,holder):(ret._reject(maybePromise._settledValue),maybePromise._unsetRejectionIsUnhandled()):callbacks[i].call(ret,maybePromise,holder)}return ret}for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];var ret=new PromiseArray(args).promise();return void 0!==fn?ret.spread(fn):ret}}},{"./util.js":19}],11:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function thrower(r){throw r}function Promise$_spreadAdapter(val,receiver){if(!util.isArray(val))return Promise$_successAdapter(val,receiver);var ret=util.tryCatchApply(this,[null].concat(val),receiver);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_successAdapter(val,receiver){var nodeback=this,ret=void 0===val?tryCatch1(nodeback,receiver,null):tryCatch2(nodeback,receiver,null,val);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_errorAdapter(reason,receiver){var nodeback=this,ret=tryCatch1(nodeback,receiver,reason);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),tryCatch2=util.tryCatch2,tryCatch1=util.tryCatch1,errorObj=util.errorObj;Promise.prototype.nodeify=function(nodeback,options){if("function"==typeof nodeback){var adapter=Promise$_successAdapter;void 0!==options&&Object(options).spread&&(adapter=Promise$_spreadAdapter),this._then(adapter,Promise$_errorAdapter,void 0,nodeback,this._boundTo)}return this}}},{"./async.js":1,"./util.js":19}],12:[function(_dereq_,module,exports){"use strict";function noConflict(bluebird){try{Promise===bluebird&&(Promise=old)}catch(e){}return bluebird}var old;"undefined"!=typeof Promise&&(old=Promise),module.exports=function(){function Promise(resolver){if("function"!=typeof resolver)throw new TypeError("the promise constructor requires a resolver function");if(this.constructor!==Promise)throw new TypeError("the promise constructor cannot be invoked directly");this._bitField=0,this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0,this._settledValue=void 0,this._boundTo=void 0,resolver!==INTERNAL&&this._resolveFromResolver(resolver)}function returnFirstElement(elements){return elements[0]}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),errors=_dereq_("./errors.js"),INTERNAL=function(){},APPLY={},NEXT_FILTER={e:null},cast=_dereq_("./thenables.js")(Promise,INTERNAL),PromiseArray=_dereq_("./promise_array.js")(Promise,INTERNAL,cast),CapturedTrace=_dereq_("./captured_trace.js")(),CatchFilter=_dereq_("./catch_filter.js")(NEXT_FILTER),PromiseResolver=_dereq_("./promise_resolver.js"),isArray=util.isArray,errorObj=util.errorObj,tryCatch1=util.tryCatch1,tryCatch2=util.tryCatch2,tryCatchApply=util.tryCatchApply,RangeError=errors.RangeError,TypeError=errors.TypeError,CancellationError=errors.CancellationError,TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,originatesFromRejection=errors.originatesFromRejection,markAsOriginatingFromRejection=errors.markAsOriginatingFromRejection,canAttach=errors.canAttach,thrower=util.thrower,apiRejection=_dereq_("./errors_api_rejection")(Promise),makeSelfResolutionError=function(){return new TypeError("circular promise resolution chain")};Promise.prototype.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(maybePromise instanceof Promise){var binder=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)}),p=Promise.all([this,binder]).then(returnFirstElement);ret._follow(p)}else ret._follow(this),ret._setBoundTo(thisArg);return ret._propagateFrom(this,3),ret},Promise.prototype.toString=function(){return"[object Promise]"},Promise.prototype.caught=Promise.prototype["catch"]=function(fn){var len=arguments.length;if(len>1){var i,catchInstances=new Array(len-1),j=0;for(i=0;len-1>i;++i){var item=arguments[i];if("function"!=typeof item){var catchFilterTypeError=new TypeError("A catch filter must be an error constructor or a filter function");return this._attachExtraTrace(catchFilterTypeError),Promise.reject(catchFilterTypeError)}catchInstances[j++]=item}catchInstances.length=j,fn=arguments[i],this._resetTrace();var catchFilter=new CatchFilter(catchInstances,fn,this);return this._then(void 0,catchFilter.doFilter,void 0,catchFilter,void 0)}return this._then(void 0,fn,void 0,void 0,void 0)},Promise.prototype.then=function(didFulfill,didReject,didProgress){return this._then(didFulfill,didReject,didProgress,void 0,void 0)},Promise.prototype.done=function(didFulfill,didReject,didProgress){var promise=this._then(didFulfill,didReject,didProgress,void 0,void 0);promise._setIsFinal()},Promise.prototype.spread=function(didFulfill,didReject){return this._then(didFulfill,didReject,void 0,APPLY,void 0)},Promise.prototype.isCancellable=function(){return!this.isResolved()&&this._cancellable()},Promise.prototype.toJSON=function(){var ret={isFulfilled:!1,isRejected:!1,fulfillmentValue:void 0,rejectionReason:void 0};return this.isFulfilled()?(ret.fulfillmentValue=this._settledValue,ret.isFulfilled=!0):this.isRejected()&&(ret.rejectionReason=this._settledValue,ret.isRejected=!0),ret},Promise.prototype.all=function(){return new PromiseArray(this).promise()},Promise.is=function(val){return val instanceof Promise},Promise.all=function(promises){return new PromiseArray(promises).promise()},Promise.prototype.error=function(fn){return this.caught(originatesFromRejection,fn)},Promise.prototype._resolveFromSyncValue=function(value){if(value===errorObj)this._cleanValues(),this._setRejected(),this._settledValue=value.e,this._ensurePossibleRejectionHandled();else{var maybePromise=cast(value,void 0);maybePromise instanceof Promise?this._follow(maybePromise):(this._cleanValues(),this._setFulfilled(),this._settledValue=value)}},Promise.method=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");return function(){var value;switch(arguments.length){case 0:value=tryCatch1(fn,this,void 0);break;case 1:value=tryCatch1(fn,this,arguments[0]);break;case 2:value=tryCatch2(fn,this,arguments[0],arguments[1]);break;default:for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];value=tryCatchApply(fn,args,this)}var ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret}},Promise.attempt=Promise["try"]=function(fn,args,ctx){if("function"!=typeof fn)return apiRejection("fn must be a function");var value=isArray(args)?tryCatchApply(fn,args,ctx):tryCatch1(fn,ctx,args),ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret},Promise.defer=Promise.pending=function(){var promise=new Promise(INTERNAL);return promise._setTrace(void 0),new PromiseResolver(promise)},Promise.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(ret._setTrace(void 0),maybePromise instanceof Promise){var p=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)});ret._follow(p)}else ret._setBoundTo(thisArg),ret._setFulfilled();return ret},Promise.cast=function(obj){var ret=cast(obj,void 0);if(!(ret instanceof Promise)){var val=ret;ret=new Promise(INTERNAL),ret._setTrace(void 0),ret._setFulfilled(),ret._cleanValues(),ret._settledValue=val}return ret},Promise.resolve=Promise.fulfilled=Promise.cast,Promise.reject=Promise.rejected=function(reason){var ret=new Promise(INTERNAL);if(ret._setTrace(void 0),markAsOriginatingFromRejection(reason),ret._cleanValues(),ret._setRejected(),ret._settledValue=reason,!canAttach(reason)){var trace=new Error(reason+"");ret._setCarriedStackTrace(trace)}return ret._ensurePossibleRejectionHandled(),ret},Promise.onPossiblyUnhandledRejection=function(fn){CapturedTrace.possiblyUnhandledRejection="function"==typeof fn?fn:void 0};var unhandledRejectionHandled;Promise.onUnhandledRejectionHandled=function(fn){unhandledRejectionHandled="function"==typeof fn?fn:void 0};var debugging=!("undefined"==typeof process||"string"!=typeof process.execPath||"object"!=typeof process.env||!process.env.BLUEBIRD_DEBUG&&"development"!==process.env.NODE_ENV);Promise.longStackTraces=function(){if(async.haveItemsQueued()&&debugging===!1)throw new Error("cannot enable long stack traces after promises have been created");debugging=CapturedTrace.isSupported()},Promise.hasLongStackTraces=function(){return debugging&&CapturedTrace.isSupported()},Promise.prototype._then=function(didFulfill,didReject,didProgress,receiver,internalData){var haveInternalData=void 0!==internalData,ret=haveInternalData?internalData:new Promise(INTERNAL);if(!haveInternalData){if(debugging){var haveSameContext=this._peekContext()===this._traceParent;ret._traceParent=haveSameContext?this._traceParent:this}ret._propagateFrom(this,7)}var callbackIndex=this._addCallbacks(didFulfill,didReject,didProgress,ret,receiver);return this.isResolved()&&async.invoke(this._queueSettleAt,this,callbackIndex),ret},Promise.prototype._length=function(){return 262143&this._bitField},Promise.prototype._isFollowingOrFulfilledOrRejected=function(){return(939524096&this._bitField)>0},Promise.prototype._isFollowing=function(){return 536870912===(536870912&this._bitField)},Promise.prototype._setLength=function(len){this._bitField=-262144&this._bitField|262143&len},Promise.prototype._setFulfilled=function(){this._bitField=268435456|this._bitField},Promise.prototype._setRejected=function(){this._bitField=134217728|this._bitField},Promise.prototype._setFollowing=function(){this._bitField=536870912|this._bitField},Promise.prototype._setIsFinal=function(){this._bitField=33554432|this._bitField},Promise.prototype._isFinal=function(){return(33554432&this._bitField)>0},Promise.prototype._cancellable=function(){return(67108864&this._bitField)>0},Promise.prototype._setCancellable=function(){this._bitField=67108864|this._bitField},Promise.prototype._unsetCancellable=function(){this._bitField=-67108865&this._bitField},Promise.prototype._setRejectionIsUnhandled=function(){this._bitField=2097152|this._bitField},Promise.prototype._unsetRejectionIsUnhandled=function(){this._bitField=-2097153&this._bitField,this._isUnhandledRejectionNotified()&&(this._unsetUnhandledRejectionIsNotified(),this._notifyUnhandledRejectionIsHandled())},Promise.prototype._isRejectionUnhandled=function(){return(2097152&this._bitField)>0},Promise.prototype._setUnhandledRejectionIsNotified=function(){this._bitField=524288|this._bitField},Promise.prototype._unsetUnhandledRejectionIsNotified=function(){this._bitField=-524289&this._bitField},Promise.prototype._isUnhandledRejectionNotified=function(){return(524288&this._bitField)>0},Promise.prototype._setCarriedStackTrace=function(capturedTrace){this._bitField=1048576|this._bitField,this._fulfillmentHandler0=capturedTrace},Promise.prototype._unsetCarriedStackTrace=function(){this._bitField=-1048577&this._bitField,this._fulfillmentHandler0=void 0},Promise.prototype._isCarryingStackTrace=function(){return(1048576&this._bitField)>0},Promise.prototype._getCarriedStackTrace=function(){return this._isCarryingStackTrace()?this._fulfillmentHandler0:void 0},Promise.prototype._receiverAt=function(index){var ret=0===index?this._receiver0:this[(index<<2)+index-5+4];return this._isBound()&&void 0===ret?this._boundTo:ret},Promise.prototype._promiseAt=function(index){return 0===index?this._promise0:this[(index<<2)+index-5+3]},Promise.prototype._fulfillmentHandlerAt=function(index){return 0===index?this._fulfillmentHandler0:this[(index<<2)+index-5+0]},Promise.prototype._rejectionHandlerAt=function(index){return 0===index?this._rejectionHandler0:this[(index<<2)+index-5+1]},Promise.prototype._addCallbacks=function(fulfill,reject,progress,promise,receiver){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promise,void 0!==receiver&&(this._receiver0=receiver),"function"!=typeof fulfill||this._isCarryingStackTrace()||(this._fulfillmentHandler0=fulfill),"function"==typeof reject&&(this._rejectionHandler0=reject),"function"==typeof progress&&(this._progressHandler0=progress);else{var base=(index<<2)+index-5;this[base+3]=promise,this[base+4]=receiver,this[base+0]="function"==typeof fulfill?fulfill:void 0,this[base+1]="function"==typeof reject?reject:void 0,this[base+2]="function"==typeof progress?progress:void 0}return this._setLength(index+1),index},Promise.prototype._setProxyHandlers=function(receiver,promiseSlotValue){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promiseSlotValue,this._receiver0=receiver;else{var base=(index<<2)+index-5;this[base+3]=promiseSlotValue,this[base+4]=receiver,this[base+0]=this[base+1]=this[base+2]=void 0}this._setLength(index+1)},Promise.prototype._proxyPromiseArray=function(promiseArray,index){this._setProxyHandlers(promiseArray,index)},Promise.prototype._proxyPromise=function(promise){promise._setProxied(),this._setProxyHandlers(promise,-15)},Promise.prototype._setBoundTo=function(obj){void 0!==obj?(this._bitField=8388608|this._bitField,this._boundTo=obj):this._bitField=-8388609&this._bitField},Promise.prototype._isBound=function(){return 8388608===(8388608&this._bitField)},Promise.prototype._resolveFromResolver=function(resolver){function Promise$_resolver(val){promise._tryFollow(val)||promise._fulfill(val)}function Promise$_rejecter(val){var trace=canAttach(val)?val:new Error(val+"");promise._attachExtraTrace(trace),markAsOriginatingFromRejection(val),promise._reject(val,trace===val?void 0:trace)}var promise=this;this._setTrace(void 0),this._pushContext();var r=tryCatch2(resolver,void 0,Promise$_resolver,Promise$_rejecter);if(this._popContext(),void 0!==r&&r===errorObj){var e=r.e,trace=canAttach(e)?e:new Error(e+"");promise._reject(e,trace)}},Promise.prototype._spreadSlowCase=function(targetFn,promise,values,boundTo){var promiseForAll=new PromiseArray(values).promise(),promise2=promiseForAll._then(function(){return targetFn.apply(boundTo,arguments)},void 0,void 0,APPLY,void 0);promise._follow(promise2)},Promise.prototype._callSpread=function(handler,promise,value){var boundTo=this._boundTo;if(isArray(value))for(var i=0,len=value.length;len>i;++i)if(cast(value[i],void 0)instanceof Promise)return void this._spreadSlowCase(handler,promise,value,boundTo);return promise._pushContext(),tryCatchApply(handler,value,boundTo)},Promise.prototype._callHandler=function(handler,receiver,promise,value){var x;return receiver!==APPLY||this.isRejected()?(promise._pushContext(),x=tryCatch1(handler,receiver,value)):x=this._callSpread(handler,promise,value),promise._popContext(),x},Promise.prototype._settlePromiseFromHandler=function(handler,receiver,value,promise){if(!(promise instanceof Promise))return void handler.call(receiver,value,promise);var x=this._callHandler(handler,receiver,promise,value);if(!promise._isFollowing())if(x===errorObj||x===promise||x===NEXT_FILTER){var err=x===promise?makeSelfResolutionError():x.e,trace=canAttach(err)?err:new Error(err+""); -x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string"); -RemoteStorage.config.cordovaRedirectUri=uri},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.connected=!1,RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),self.online=!0,isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]?!0:!1}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(url,errorHandler,sucessHandler){function __processState(){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"resource not found",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}function __makeRequest(){xhr.onreadystatechange=function(){4===xhr.readyState&&__processState()},xhr.onload=function(a,b){__processState()},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this,xhr=new XMLHttpRequest;return __makeRequest()},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(URL,JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error,request:URL}):generateErrorObject({message:"unknown response from server",request:URL}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){var uri="";return address.split("://")[1]||(uri="acct:"),protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource="+uri+address}function __fallbackChecks(err){if(self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1)return uri_index+=1,__call();if(!self.config.tls_only&&"https"===protocol)return uri_index=0,protocol="http",__call();if(!self.config.webfist_fallback||"webfist.org"===host)return cb(err);uri_index=0,protocol="http",host="webfist.org";var URL=__buildURL();self.__fetchJRD(URL,cb,function(data){self.__processJRD(URL,data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(URL,JRD,cb,function(result){return cb(null,cb)})})})})}function __call(){var URL=__buildURL();self.__fetchJRD(URL,__fallbackChecks,function(JRD){self.__processJRD(URL,JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,host="";host=address.indexOf("://")>-1?address.replace(/ /g,"").split("://")[1]:address.replace(/ /g,"").split("@")[1];var uri_index=0,protocol="https";return self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0)},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId),!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){ -redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href,storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' +x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string"); +RemoteStorage.config.cordovaRedirectUri=uri},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.rs=rs,this.connected=!1,RS.eventHandling(this,"change","connected","not-connected","wire-busy","wire-done"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]?!0:!1}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(url,errorHandler,sucessHandler){function __processState(){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"resource not found",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}function __makeRequest(){xhr.onreadystatechange=function(){4===xhr.readyState&&__processState()},xhr.onload=function(a,b){__processState()},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this,xhr=new XMLHttpRequest;return __makeRequest()},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(URL,JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error,request:URL}):generateErrorObject({message:"unknown response from server",request:URL}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){var uri="";return address.split("://")[1]||(uri="acct:"),protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource="+uri+address}function __fallbackChecks(err){if(self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1)return uri_index+=1,__call();if(!self.config.tls_only&&"https"===protocol)return uri_index=0,protocol="http",__call();if(!self.config.webfist_fallback||"webfist.org"===host)return cb(err);uri_index=0,protocol="http",host="webfist.org";var URL=__buildURL();self.__fetchJRD(URL,cb,function(data){self.__processJRD(URL,data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(URL,JRD,cb,function(result){return cb(null,cb)})})})})}function __call(){var URL=__buildURL();self.__fetchJRD(URL,__fallbackChecks,function(JRD){self.__processJRD(URL,JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,host="";host=address.indexOf("://")>-1?address.replace(/ /g,"").split("://")[1]:address.replace(/ /g,"").split("@")[1];var uri_index=0,protocol="https";return self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0)},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId), +!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href,storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' },function(window){function stateSetter(widget,state,message){return RemoteStorage.log("[Widget] Producing stateSetter for",state),function(){RemoteStorage.log("[Widget] Setting state",state,message),hasLocalStorage&&(localStorage[LS_STATE_KEY]=state),widget.view?(widget.rs.remote&&widget.view.setUserAddress(widget.rs.remote.userAddress),widget.view.setState(state,message)):widget._rememberedState=state}}function errorsHandler(widget){return function(error){var s;error instanceof RemoteStorage.DiscoveryError?(console.error("Discovery failed",error,'"'+error.message+'"'),s=stateSetter(widget,"initial",error.message)):error instanceof RemoteStorage.SyncError?s=stateSetter(widget,"offline"):error instanceof RemoteStorage.Unauthorized?s=stateSetter(widget,"unauthorized"):(RemoteStorage.log("[Widget] Unknown error"),s=stateSetter(widget,"error",[error])),s.apply()}}function flashFor(evt){return"GET"===evt.method&&evt.isFolder?!1:!0}var hasLocalStorage,LS_STATE_KEY="remotestorage:widget:state",VALID_ENTRY_STATES={initial:!0,connected:!0,offline:!0};RemoteStorage.Widget=function(remoteStorage){var self=this,requestsToFlashFor=0;if(this.rs=remoteStorage,this.rs.remote.on("connected",stateSetter(this,"connected")),this.rs.on("disconnected",stateSetter(this,"initial")),this.rs.on("connecting",stateSetter(this,"authing")),this.rs.on("authing",stateSetter(this,"authing")),this.rs.on("error",errorsHandler(this)),this.rs.remote&&(this.rs.remote.on("wire-busy",function(evt){flashFor(evt)&&(requestsToFlashFor++,stateSetter(self,"busy")())}),this.rs.remote.on("wire-done",function(evt){flashFor(evt)&&requestsToFlashFor--,0>=requestsToFlashFor&&evt.success&&stateSetter(self,"connected")()})),hasLocalStorage){var state=localStorage[LS_STATE_KEY];state&&VALID_ENTRY_STATES[state]&&(this._rememberedState=state)}},RemoteStorage.Widget.prototype={display:function(options){return"string"==typeof options?options={domID:options}:"undefined"==typeof options&&(options={}),this.view||this.setView(new RemoteStorage.Widget.View(this.rs)),this.view.display(options),this},linkWidgetToSync:function(){"object"==typeof this.rs.sync&&"function"==typeof this.rs.sync.sync?this.view.on("sync",this.rs.sync.sync.bind(this.rs.sync)):(RemoteStorage.log("[Widget] typeof this.rs.sync check fail",this.rs.sync),setTimeout(this.linkWidgetToSync.bind(this),1e3))},setView:function(view){this.view=view,this.view.on("connect",function(options){"string"==typeof options?this.rs.connect(options):options.special&&this.rs[options.special].connect(options)}.bind(this)),this.view.on("secret-entered",function(secretKey){this.view.setUserSecretKey(secretKey),stateSetter(this,"ciphered")()}.bind(this)),this.view.on("secret-cancelled",function(){stateSetter(this,"notciphered")()}.bind(this)),this.view.on("disconnect",this.rs.disconnect.bind(this.rs)),this.linkWidgetToSync();try{this.view.on("reset",function(){var location=RemoteStorage.Authorize.getLocation();this.rs.on("disconnected",location.reload.bind(location)),this.rs.disconnect()}.bind(this))}catch(e){if(!e.message||!e.message.match(/Unknown event/))throw e}this._rememberedState&&(setTimeout(stateSetter(this,this._rememberedState),0),delete this._rememberedState)}},RemoteStorage.prototype.displayWidget=function(options){return this.widget.display(options)},RemoteStorage.Widget._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.widget||(remoteStorage.widget=new RemoteStorage.Widget(remoteStorage))},RemoteStorage.Widget._rs_supported=function(remoteStorage){return"undefined"!=typeof document}}("undefined"!=typeof window?window:global),function(window){function removeClass(el,className){return el.classList.remove(className)}function addClass(el,className){return el.classList.add(className)}function stopPropagation(event){"function"==typeof event.stopPropagation?event.stopPropagation():event.cancelBubble=!0}function setupButton(parent,className,iconName,eventListener){var element=parent.querySelector("."+className);if("undefined"!=typeof iconName){var img=element.querySelector("img");(img||element).src=RemoteStorage.Assets[iconName]}return element.addEventListener("click",eventListener),element}function handleButtonState(event){event.target.value?event.target.nextElementSibling.removeAttribute("disabled"):event.target.nextElementSibling.setAttribute("disabled","disabled")}var t=RemoteStorage.I18n.translate;RemoteStorage.Widget.View=function(remoteStorage){if(this.rs=remoteStorage,"undefined"==typeof document)throw"Widget not supported";RemoteStorage.eventHandling(this,"connect","secret-entered","secret-cancelled","disconnect","sync","display","reset");for(var event in this.events)this.events[event]=this.events[event].bind(this);this.hideBubbleOnBodyClick=function(event){for(var p=event.target;p!==document.body;p=p.parentElement)if("remotestorage-widget"===p.id)return;this.hideBubble()}.bind(this)},RemoteStorage.Widget.View.prototype={connectGdrive:function(){this._emit("connect",{special:"googledrive"})},connectDropbox:function(){this._emit("connect",{special:"dropbox"})},setState:function(state,message){RemoteStorage.log("[View] widget.view.setState(",state,",",message,");");var s=this.states[state];if("undefined"==typeof s)throw new Error("Bad State assigned to view: "+state);s.apply(this,[message])},setUserAddress:function(addr){this.userAddress=addr||"";var el;this.div&&(el=this.div.querySelector("form.remotestorage-initial").userAddress)&&(el.value=this.userAddress)},setUserSecretKey:function(secretKey){this.userSecretKey=secretKey},toggleBubble:function(event){this.bubble.className.search("rs-hidden")<0?this.hideBubble(event):this.showBubble(event)},hideBubble:function(){addClass(this.bubble,"rs-hidden"),document.body.removeEventListener("click",this.hideBubbleOnBodyClick)},showBubble:function(event){removeClass(this.bubble,"rs-hidden"),"undefined"!=typeof event&&stopPropagation(event),document.body.addEventListener("click",this.hideBubbleOnBodyClick),this.div.querySelector(".remotestorage-connected").classList.contains("remotestorage-cipher")&&!this.userSecretKey?this.bubble.querySelector("form.remotestorage-cipher-form").userSecretKey.focus():this.bubble.querySelector("form.remotestorage-initial").userAddress.focus()},display:function(options){if("undefined"!=typeof this.div)return this.div;var element=document.createElement("div"),style=document.createElement("style");if(style.innerHTML=RemoteStorage.Assets.widgetCss,element.id="remotestorage-widget",element.innerHTML=RemoteStorage.Assets.widget,element.appendChild(style),options.domID){var parent=document.getElementById(options.domID);if(!parent)throw'Failed to find target DOM element with id="'+options.domID+'"';parent.appendChild(element)}else document.body.appendChild(element);setupButton(element,"rs-sync","syncIcon",this.events.sync),setupButton(element,"rs-disconnect","disconnectIcon",this.events.disconnect),setupButton(element,"remotestorage-reset",void 0,this.events.reset);setupButton(element,"connect","connectIcon",this.events.connect);this.form=element.querySelector("form.remotestorage-initial");var el=this.form.userAddress;if(el.addEventListener("load",handleButtonState),el.addEventListener("keyup",handleButtonState),this.userAddress&&(el.value=this.userAddress),options.encryption){this.cipher=!0;var secretKeyInput=element.querySelector("form.remotestorage-cipher-form").userSecretKey;secretKeyInput.type="password";setupButton(element,"rs-cipher","cipherIcon",this.events["secret-entered"]);secretKeyInput.addEventListener("load",handleButtonState),secretKeyInput.addEventListener("keyup",handleButtonState),setupButton(element,"rs-nocipher","nocipherIcon",this.events["secret-cancelled"])}this.cube=setupButton(element,"rs-cube","remoteStorageIcon",this.toggleBubble.bind(this)),setupButton(element,"rs-dropbox","dropbox",this.connectDropbox.bind(this)),setupButton(element,"rs-googledrive","googledrive",this.connectGdrive.bind(this));var bubbleDontCatch={INPUT:!0,BUTTON:!0,IMG:!0},eventListener=function(event){bubbleDontCatch[event.target.tagName]||this.div.classList.contains("remotestorage-state-unauthorized")||this.showBubble(event)}.bind(this);return this.bubble=setupButton(element,"rs-bubble",void 0,eventListener),this.hideBubble(),this.div=element,this.states.initial.call(this),this.events.display.call(this),this.div},states:{initial:function(message){var cube=this.cube,info=message||t("view_info");cube.src=RemoteStorage.Assets.remoteStorageIcon,this._renderTranslatedInitialContent(),message?(cube.src=RemoteStorage.Assets.remoteStorageIconError,removeClass(this.cube,"remotestorage-loading"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},2e3)):this.hideBubble(),this.div.className="remotestorage-state-initial",this.userSecretKey&&delete this.userSecretKey;var backends=1;this._activateBackend("dropbox")&&(backends+=1),this._activateBackend("googledrive")&&(backends+=1),this.div.querySelector(".rs-bubble-text").style.paddingRight=32*backends+8+"px";var cb=this.div.querySelector(".connect");this.form.userAddress.value&&cb.removeAttribute("disabled");var infoEl=this.div.querySelector(".rs-info-msg");infoEl.innerHTML=info,message?infoEl.classList.add("remotestorage-error-info"):infoEl.classList.remove("remotestorage-error-info")},authing:function(){this.div.removeEventListener("click",this.events.connect),this.div.className="remotestorage-state-authing",this.div.querySelector(".rs-status-text").innerHTML=t("view_connecting",this.userAddress),addClass(this.cube,"remotestorage-loading")},connected:function(){var cube=this.cube;this.div.className="remotestorage-state-connected",this.div.querySelector(".userAddress").innerHTML=this.userAddress,cube.src=RemoteStorage.Assets.remoteStorageIcon,removeClass(cube,"remotestorage-loading"),this.cipher&&(this.userSecretKey?this.userSecretKeyError?(cube.src=RemoteStorage.Assets.remoteStorageIconError,addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),addClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},5e3)):(removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),cube.src=RemoteStorage.Assets.remoteStorageIconCiphered):(addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.showBubble()));var icons={googledrive:this.div.querySelector(".rs-googledrive"),dropbox:this.div.querySelector(".rs-dropbox")};icons.googledrive.style.display=icons.dropbox.style.display="none",icons[this.rs.backend]?(icons[this.rs.backend].style.display="inline-block",this.div.querySelector(".rs-bubble-text").style.paddingRight="72px"):this.div.querySelector(".rs-bubble-text").style.paddingRight="40px"},ciphered:function(){this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value="",removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.cube.src=RemoteStorage.Assets.remoteStorageIconCiphered,this.hideBubble()},notciphered:function(){this.cipher=!1,removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.hideBubble()},busy:function(){this.div.className="remotestorage-state-busy",addClass(this.cube,"remotestorage-loading")},offline:function(){this.div.className="remotestorage-state-offline",this.cube.src=RemoteStorage.Assets.remoteStorageIconOffline,this.div.querySelector(".rs-status-text").innerHTML=t("view_offline")},error:function(err){var errorMsg=err;this.div.className="remotestorage-state-error",this.div.querySelector(".rs-bubble-text").innerHTML=""+t("view_error_occured")+"",err instanceof Error&&(errorMsg=err.message+"\n\n"+err.stack),this.div.querySelector(".rs-error-msg").textContent=errorMsg,this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble()},unauthorized:function(){this.div.className="remotestorage-state-unauthorized",this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble(),this.div.addEventListener("click",this.events.connect)}},events:{connect:function(event){stopPropagation(event),event.preventDefault(),this._emit("connect",this.div.querySelector("form.remotestorage-initial").userAddress.value)},"secret-entered":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-entered",this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value)},"secret-cancelled":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-cancelled")},sync:function(event){stopPropagation(event),event.preventDefault(),this._emit("sync")},disconnect:function(event){stopPropagation(event),event.preventDefault(),this._emit("disconnect")},reset:function(event){event.preventDefault();var result=window.confirm(t("view_confirm_reset"));result&&this._emit("reset")},display:function(event){event&&event.preventDefault(),this._emit("display")}},_renderTranslatedInitialContent:function(){this.div.querySelector(".rs-status-text").innerHTML=t("view_connect"),this.div.querySelector(".remotestorage-reset").innerHTML=t("view_get_me_out"),this.div.querySelector(".rs-error-plz-report").innerHTML=t("view_error_plz_report"),this.div.querySelector(".remotestorage-unauthorized").innerHTML=t("view_unauthorized"),this.div.querySelector(".remotestorage-invalid-key").innerHTML=t("view_invalid_key")},_activateBackend:function(backendName){var className="rs-"+backendName;return this.rs.apiKeys[backendName]?(this.div.querySelector("."+className).style.display="inline-block",!0):(this.div.querySelector("."+className).style.display="none",!1)}}}("undefined"!=typeof window?window:global),function(global,factory){"function"==typeof define&&define.amd?define([],factory):"undefined"!=typeof module&&module.exports?module.exports=factory():global.tv4=factory()}(this,function(){function notReallyPercentEncode(string){return encodeURI(string).replace(/%25[0-9][0-9]/g,function(doubleEncoded){return"%"+doubleEncoded.substring(3)})}function uriTemplateSubstitution(spec){var modifier="";uriTemplateGlobalModifiers[spec.charAt(0)]&&(modifier=spec.charAt(0),spec=spec.substring(1));var separator="",prefix="",shouldEscape=!0,showVariables=!1,trimEmptyString=!1;"+"===modifier?shouldEscape=!1:"."===modifier?(prefix=".",separator="."):"/"===modifier?(prefix="/",separator="/"):"#"===modifier?(prefix="#",shouldEscape=!1):";"===modifier?(prefix=";",separator=";",showVariables=!0,trimEmptyString=!0):"?"===modifier?(prefix="?",separator="&",showVariables=!0):"&"===modifier&&(prefix="&",separator="&",showVariables=!0);for(var varNames=[],varList=spec.split(","),varSpecs=[],varSpecMap={},i=0;i0&&(result+=varSpec.suffices["*"]?separator||",":",",varSpec.suffices["*"]&&showVariables&&(result+=varSpec.name+"=")),result+=shouldEscape?encodeURIComponent(value[j]).replace(/!/g,"%21"):notReallyPercentEncode(value[j])}else if("object"==typeof value){showVariables&&!varSpec.suffices["*"]&&(result+=varSpec.name+"=");var first=!0;for(var key in value)first||(result+=varSpec.suffices["*"]?separator||",":","),first=!1,result+=shouldEscape?encodeURIComponent(key).replace(/!/g,"%21"):notReallyPercentEncode(key),result+=varSpec.suffices["*"]?"=":",",result+=shouldEscape?encodeURIComponent(value[key]).replace(/!/g,"%21"):notReallyPercentEncode(value[key])}else showVariables&&(result+=varSpec.name,trimEmptyString&&""===value||(result+="=")),null!=varSpec.truncate&&(value=value.substring(0,varSpec.truncate)),result+=shouldEscape?encodeURIComponent(value).replace(/!/g,"%21"):notReallyPercentEncode(value)}return result};return subFunction.varNames=varNames,{prefix:prefix,substitution:subFunction}}function UriTemplate(template){if(!(this instanceof UriTemplate))return new UriTemplate(template);for(var parts=template.split("{"),textParts=[parts.shift()],prefixes=[],substitutions=[],varNames=[];parts.length>0;){var part=parts.shift(),spec=part.split("}")[0],remainder=part.substring(spec.length+1),funcs=uriTemplateSubstitution(spec);substitutions.push(funcs.substitution),prefixes.push(funcs.prefix),textParts.push(remainder),varNames=varNames.concat(funcs.substitution.varNames)}this.fill=function(valueFunction){for(var result=textParts[0],i=0;i0&&"/"===testUrl.charAt(baseUrl.length-1)||"#"===remainder.charAt(0)||"?"===remainder.charAt(0))return!0}return!1}function createApi(language){var currentLanguage,customErrorReporter,globalContext=new ValidatorContext,api={setErrorReporter:function(reporter){return"string"==typeof reporter?this.language(reporter):(customErrorReporter=reporter,!0)},addFormat:function(){globalContext.addFormat.apply(globalContext,arguments)},language:function(code){return code?(languages[code]||(code=code.split("-")[0]),languages[code]?(currentLanguage=code,code):!1):currentLanguage},addLanguage:function(code,messageMap){var key;for(key in ErrorCodes)messageMap[key]&&!messageMap[ErrorCodes[key]]&&(messageMap[ErrorCodes[key]]=messageMap[key]);var rootCode=code.split("-")[0];if(languages[rootCode]){languages[code]=Object.create(languages[rootCode]);for(key in messageMap)"undefined"==typeof languages[rootCode][key]&&(languages[rootCode][key]=messageMap[key]),languages[code][key]=messageMap[key]}else languages[code]=messageMap,languages[rootCode]=messageMap;return this},freshApi:function(language){var result=createApi();return language&&result.language(language),result},validate:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!1,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema);var error=context.validateAll(data,schema,null,null,"");return!error&&banUnknownProperties&&(error=context.banUnknownProperties(data,schema)),this.error=error,this.missing=context.missing,this.valid=null===error,this.valid},validateResult:function(){var result={};return this.validate.apply(result,arguments),result},validateMultiple:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!0,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema),context.validateAll(data,schema,null,null,""),banUnknownProperties&&context.banUnknownProperties(data,schema);var result={};return result.errors=context.errors,result.missing=context.missing,result.valid=0===result.errors.length,result},addSchema:function(){return globalContext.addSchema.apply(globalContext,arguments)},getSchema:function(){return globalContext.getSchema.apply(globalContext,arguments)},getSchemaMap:function(){return globalContext.getSchemaMap.apply(globalContext,arguments)},getSchemaUris:function(){return globalContext.getSchemaUris.apply(globalContext,arguments)},getMissingUris:function(){return globalContext.getMissingUris.apply(globalContext,arguments)},dropSchemas:function(){globalContext.dropSchemas.apply(globalContext,arguments)},defineKeyword:function(){globalContext.defineKeyword.apply(globalContext,arguments)},defineError:function(codeName,codeNumber,defaultMessage){if("string"!=typeof codeName||!/^[A-Z]+(_[A-Z]+)*$/.test(codeName))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof codeNumber||codeNumber%1!==0||1e4>codeNumber)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof ErrorCodes[codeName])throw new Error("Error already defined: "+codeName+" as "+ErrorCodes[codeName]);if("undefined"!=typeof ErrorCodeLookup[codeNumber])throw new Error("Error code already used: "+ErrorCodeLookup[codeNumber]+" as "+codeNumber);ErrorCodes[codeName]=codeNumber,ErrorCodeLookup[codeNumber]=codeName,ErrorMessagesDefault[codeName]=ErrorMessagesDefault[codeNumber]=defaultMessage;for(var langCode in languages){var language=languages[langCode];language[codeName]&&(language[codeNumber]=language[codeNumber]||language[codeName])}},reset:function(){globalContext.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:normSchema,resolveUrl:resolveUrl,getDocumentUri:getDocumentUri,errorCodes:ErrorCodes};return api.language(language||"en"),api}Object.keys||(Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if("object"!=typeof obj&&"function"!=typeof obj||null===obj)throw new TypeError("Object.keys called on non-object");var result=[];for(var prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(var i=0;dontEnumsLength>i;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result}}()),Object.create||(Object.create=function(){function F(){}return function(o){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Array.isArray||(Array.isArray=function(vArg){return"[object Array]"===Object.prototype.toString.call(vArg)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(searchElement){if(null===this)throw new TypeError;var t=Object(this),len=t.length>>>0;if(0===len)return-1;var n=0;if(arguments.length>1&&(n=Number(arguments[1]),n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=len)return-1;for(var k=n>=0?n:Math.max(len-Math.abs(n),0);len>k;k++)if(k in t&&t[k]===searchElement)return k;return-1}),Object.isFrozen||(Object.isFrozen=function(obj){for(var key="tv4_test_frozen_key";obj.hasOwnProperty(key);)key+=Math.random();try{return obj[key]=!0,delete obj[key],!1}catch(e){return!0}});var uriTemplateGlobalModifiers={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},uriTemplateSuffices={"*":!0};UriTemplate.prototype={toString:function(){return this.template},fillFromObject:function(obj){return this.fill(function(varName){return obj[varName]})}};var ValidatorContext=function(parent,collectMultiple,errorReporter,checkRecursive,trackUnknownProperties){if(this.missing=[],this.missingMap={},this.formatValidators=parent?Object.create(parent.formatValidators):{},this.schemas=parent?Object.create(parent.schemas):{},this.collectMultiple=collectMultiple,this.errors=[],this.handleError=collectMultiple?this.collectError:this.returnError,checkRecursive&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),trackUnknownProperties&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=errorReporter||defaultErrorReporter("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},parent)for(var key in parent.definedKeywords)this.definedKeywords[key]=parent.definedKeywords[key].slice(0)};ValidatorContext.prototype.defineKeyword=function(keyword,keywordFunction){this.definedKeywords[keyword]=this.definedKeywords[keyword]||[],this.definedKeywords[keyword].push(keywordFunction)},ValidatorContext.prototype.createError=function(code,messageParams,dataPath,schemaPath,subErrors,data,schema){var error=new ValidationError(code,messageParams,dataPath,schemaPath,subErrors);return error.message=this.errorReporter(error,data,schema),error},ValidatorContext.prototype.returnError=function(error){return error},ValidatorContext.prototype.collectError=function(error){return error&&this.errors.push(error),null},ValidatorContext.prototype.prefixErrors=function(startIndex,dataPath,schemaPath){for(var i=startIndex;i=CLOSE_ENOUGH_LOW&&CLOSE_ENOUGH_HIGH>remainder)return this.createError(ErrorCodes.NUMBER_MULTIPLE_OF,{value:data,multipleOf:multipleOf},"","",null,data,schema)}return null},ValidatorContext.prototype.validateMinMax=function(data,schema){if("number"!=typeof data)return null;if(void 0!==schema.minimum){if(dataschema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM,{value:data,maximum:schema.maximum},"","/maximum",null,data,schema);if(schema.exclusiveMaximum&&data===schema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM_EXCLUSIVE,{value:data,maximum:schema.maximum},"","/exclusiveMaximum",null,data,schema)}return null},ValidatorContext.prototype.validateNaN=function(data,schema){return"number"!=typeof data?null:isNaN(data)===!0||data===1/0||data===-(1/0)?this.createError(ErrorCodes.NUMBER_NOT_A_NUMBER,{value:data},"","/type",null,data,schema):null},ValidatorContext.prototype.validateString=function(data,schema,dataPointerPath){return this.validateStringLength(data,schema,dataPointerPath)||this.validateStringPattern(data,schema,dataPointerPath)||null},ValidatorContext.prototype.validateStringLength=function(data,schema){return"string"!=typeof data?null:void 0!==schema.minLength&&data.lengthschema.maxLength?this.createError(ErrorCodes.STRING_LENGTH_LONG,{length:data.length,maximum:schema.maxLength},"","/maxLength",null,data,schema):null},ValidatorContext.prototype.validateStringPattern=function(data,schema){if("string"!=typeof data||"string"!=typeof schema.pattern&&!(schema.pattern instanceof RegExp))return null;var regexp;if(schema.pattern instanceof RegExp)regexp=schema.pattern;else{var body,flags="",literal=schema.pattern.match(/^\/(.+)\/([img]*)$/);literal?(body=literal[1],flags=literal[2]):body=schema.pattern,regexp=new RegExp(body,flags)}return regexp.test(data)?null:this.createError(ErrorCodes.STRING_PATTERN,{pattern:schema.pattern},"","/pattern",null,data,schema)},ValidatorContext.prototype.validateArray=function(data,schema,dataPointerPath){return Array.isArray(data)?this.validateArrayLength(data,schema,dataPointerPath)||this.validateArrayUniqueItems(data,schema,dataPointerPath)||this.validateArrayItems(data,schema,dataPointerPath)||null:null},ValidatorContext.prototype.validateArrayLength=function(data,schema){var error;return void 0!==schema.minItems&&data.lengthschema.maxItems&&(error=this.createError(ErrorCodes.ARRAY_LENGTH_LONG,{length:data.length,maximum:schema.maxItems},"","/maxItems",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateArrayUniqueItems=function(data,schema){if(schema.uniqueItems)for(var i=0;ischema.maxProperties&&(error=this.createError(ErrorCodes.OBJECT_PROPERTIES_MAXIMUM,{propertyCount:keys.length,maximum:schema.maxProperties},"","/maxProperties",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateObjectRequiredProperties=function(data,schema){if(void 0!==schema.required)for(var i=0;ii;i++)uuid[i]=chars[0|Math.random()*radix];else{var r;for(uuid[8]=uuid[13]=uuid[18]=uuid[23]="-",uuid[14]="4",i=0;36>i;i++)uuid[i]||(r=0|16*Math.random(),uuid[i]=chars[19==i?3&r|8:r])}return uuid.join("")},function(global){function deprecate(thing,replacement){console.log("WARNING: "+thing+" is deprecated. Use "+replacement+" instead.")}var RS=RemoteStorage;RS.BaseClient=function(storage,base){if("/"!==base[base.length-1])throw"Not a folder: "+base;"/"===base&&(this.makePath=function(path){return("/"===path[0]?"":"/")+path}),this.storage=storage,this.base=base;var parts=this.base.split("/");parts.length>2?this.moduleName=parts[1]:this.moduleName="root",RS.eventHandling(this,"change"),this.on=this.on.bind(this),storage.onChange(this.base,this._fireChange.bind(this))},RS.BaseClient.prototype={extend:function(object){for(var key in object)this[key]=object[key];return this},scope:function(path){return new RS.BaseClient(this.storage,this.makePath(path))},getListing:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){return 404===r.statusCode?{}:r.body})},getAll:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){if(404===r.statusCode)return{};if("object"==typeof r.body){var keys=Object.keys(r.body);if(0===keys.length)return{};var calls=keys.map(function(key){return this.storage.get(this.makePath(path+key),maxAge).then(function(o){if("string"==typeof o.body)try{o.body=JSON.parse(o.body)}catch(e){}"object"==typeof o.body&&(r.body[key]=o.body)})}.bind(this));return Promise.all(calls).then(function(){return r.body})}}.bind(this))},getFile:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getFile must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){return{data:r.body,contentType:r.contentType,revision:r.revision}})},storeFile:function(mimeType,path,body){return"string"!=typeof mimeType?Promise.reject("Argument 'mimeType' of baseClient.storeFile must be a string"):"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.storeFile must be a string"):"string"!=typeof body&&"object"!=typeof body?Promise.reject("Argument 'body' of baseClient.storeFile must be a string, ArrayBuffer, or ArrayBufferView"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Editing a document to which only read access ('r') was claimed"),this.storage.put(this.makePath(path),body,mimeType).then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this)))},getObject:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getObject must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){if("object"==typeof r.body)return r.body;if("string"==typeof r.body)try{return JSON.parse(r.body)}catch(e){throw"Not valid JSON: "+this.makePath(path)}else if("undefined"!=typeof r.body&&200===r.statusCode)return Promise.reject("Not an object: "+this.makePath(path))}.bind(this))},storeObject:function(typeAlias,path,object){if("string"!=typeof typeAlias)return Promise.reject("Argument 'typeAlias' of baseClient.storeObject must be a string");if("string"!=typeof path)return Promise.reject("Argument 'path' of baseClient.storeObject must be a string");if("object"!=typeof object)return Promise.reject("Argument 'object' of baseClient.storeObject must be an object");this._attachType(object,typeAlias);try{var validationResult=this.validate(object);if(!validationResult.valid)return Promise.reject(validationResult)}catch(exc){return Promise.reject(exc)}return this.storage.put(this.makePath(path),JSON.stringify(object),"application/json; charset=UTF-8").then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this))},remove:function(path){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.remove must be a string"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Removing a document to which only read access ('r') was claimed"),this.storage["delete"](this.makePath(path)))},cache:function(path,strategy){if("string"!=typeof path)throw"Argument 'path' of baseClient.cache must be a string";if(strategy===!1?(deprecate("caching strategy ",'<"FLUSH">'),strategy="FLUSH"):void 0===strategy?strategy="ALL":"string"!=typeof strategy&&(deprecate("that caching strategy",'<"ALL">'),strategy="ALL"),"FLUSH"!==strategy&&"SEEN"!==strategy&&"ALL"!==strategy)throw'Argument \'strategy\' of baseclient.cache must be one of ["FLUSH", "SEEN", "ALL"]';return this.storage.caching.set(this.makePath(path),strategy),this},flush:function(path){return this.storage.local.flush(path)},makePath:function(path){return this.base+(path||"")},_fireChange:function(event){RemoteStorage.config.changeEvents[event.origin]&&(["new","old","lastCommon"].forEach(function(fieldNamePrefix){if((!event[fieldNamePrefix+"ContentType"]||/^application\/(.*)json(.*)/.exec(event[fieldNamePrefix+"ContentType"]))&&"string"==typeof event[fieldNamePrefix+"Value"])try{event[fieldNamePrefix+"Value"]=JSON.parse(event[fieldNamePrefix+"Value"])}catch(e){}}),this._emit("change",event))},_cleanPath:RemoteStorage.util.cleanPath,getItemURL:function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.getItemURL must be a string";return this.storage.connected?(path=this._cleanPath(this.makePath(path)),this.storage.remote.href+path):void 0},uuid:function(){return Math.uuid()}},RS.BaseClient._rs_init=function(){RS.prototype.scope=function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.scope must be a string";if(!this.access.checkPathPermission(path,"r")){var escapedPath=path.replace(/(['\\])/g,"\\$1");console.warn("WARNING: please call remoteStorage.access.claim('"+escapedPath+"', 'r') (read only) or remoteStorage.access.claim('"+escapedPath+"', 'rw') (read/write) first")}return new RS.BaseClient(this,path)}}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.BaseClient.Types={uris:{},schemas:{},aliases:{},declare:function(moduleName,alias,uri,schema){var fullAlias=moduleName+"/"+alias;if(schema["extends"]){var extendedAlias,parts=schema["extends"].split("/");extendedAlias=1===parts.length?moduleName+"/"+parts.shift():parts.join("/");var extendedUri=this.uris[extendedAlias];if(!extendedUri)throw"Type '"+fullAlias+"' tries to extend unknown schema '"+extendedAlias+"'";schema["extends"]=this.schemas[extendedUri]}this.uris[fullAlias]=uri,this.aliases[uri]=fullAlias,this.schemas[uri]=schema},resolveAlias:function(alias){return this.uris[alias]},getSchema:function(uri){return this.schemas[uri]},inScope:function(moduleName){var ml=moduleName.length,schemas={};for(var alias in this.uris)if(alias.substr(0,ml+1)===moduleName+"/"){var uri=this.uris[alias];schemas[uri]=this.schemas[uri]}return schemas}};var SchemaNotFound=function(uri){var error=new Error("Schema not found: "+uri);return error.name="SchemaNotFound",error};SchemaNotFound.prototype=Error.prototype,RemoteStorage.BaseClient.Types.SchemaNotFound=SchemaNotFound,RemoteStorage.BaseClient.prototype.extend({declareType:function(alias,uri,schema){schema||(schema=uri,uri=this._defaultTypeURI(alias)),RemoteStorage.BaseClient.Types.declare(this.moduleName,alias,uri,schema)},validate:function(object){var schema=RemoteStorage.BaseClient.Types.getSchema(object["@context"]);if(schema)return tv4.validateResult(object,schema);throw new SchemaNotFound(object["@context"])},_defaultTypeURI:function(alias){return"http://remotestorage.io/spec/modules/"+encodeURIComponent(this.moduleName)+"/"+encodeURIComponent(alias)},_attachType:function(object,alias){object["@context"]=RemoteStorage.BaseClient.Types.resolveAlias(this.moduleName+"/"+alias)||this._defaultTypeURI(alias)}}),Object.defineProperty(RemoteStorage.BaseClient.prototype,"schemas",{configurable:!0,get:function(){return RemoteStorage.BaseClient.Types.inScope(this.moduleName)}})}("undefined"!=typeof window?window:global),function(global){var containingFolder=RemoteStorage.util.containingFolder;RemoteStorage.Caching=function(){this.reset(); -},RemoteStorage.Caching.prototype={pendingActivations:[],set:function(path,strategy){if("string"!=typeof path)throw new Error("path should be a string");if(!RemoteStorage.util.isFolder(path))throw new Error("path should be a folder");if(this._remoteStorage&&this._remoteStorage.access&&!this._remoteStorage.access.checkPathPermission(path,"r"))throw new Error('No access to path "'+path+'". You have to claim access to it first.');if(!strategy.match(/^(FLUSH|SEEN|ALL)$/))throw new Error("strategy should be 'FLUSH', 'SEEN', or 'ALL'");this._rootPaths[path]=strategy,"ALL"===strategy&&(this.activateHandler?this.activateHandler(path):this.pendingActivations.push(path))},enable:function(path){this.set(path,"ALL")},disable:function(path){this.set(path,"FLUSH")},onActivate:function(cb){var i;for(RemoteStorage.log("[Caching] Setting activate handler",cb,this.pendingActivations),this.activateHandler=cb,i=0;i1e3&&36e5>interval}var syncInterval=1e4,backgroundSyncInterval=6e4,isBackground=!1,isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,equal=RemoteStorage.util.equal,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=RemoteStorage.util.pathsFromRoot;RemoteStorage.Sync=function(setLocal,setRemote,setAccess,setCaching){this.local=setLocal,this.local.onDiff(function(path){this.addTask(path),this.doTasks()}.bind(this)),this.remote=setRemote,this.access=setAccess,this.caching=setCaching,this._tasks={},this._running={},this._timeStarted={},RemoteStorage.eventHandling(this,"done","req-done"),this.caching.onActivate(function(path){this.addTask(path),this.doTasks()}.bind(this))},RemoteStorage.Sync.prototype={now:function(){return(new Date).getTime()},queueGetRequest:function(path){var pending=Promise.defer();return this.remote.connected?this.remote.online?(this.addTask(path,function(){this.local.get(path).then(function(r){return pending.resolve(r)})}.bind(this)),this.doTasks()):pending.reject("cannot fulfill maxAge requirement - remote is not online"):pending.reject("cannot fulfill maxAge requirement - remote is not connected"),pending.promise},corruptServerItemsMap:function(itemsMap,force02){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap){var item=itemsMap[itemName];if("object"!=typeof item)return!0;if("string"!=typeof item.ETag)return!0;if(isFolder(itemName)){if(-1!==itemName.substring(0,itemName.length-1).indexOf("/"))return!0}else{if(-1!==itemName.indexOf("/"))return!0;if(force02){if("string"!=typeof item["Content-Type"])return!0;if("number"!=typeof item["Content-Length"])return!0}}}return!1},corruptItemsMap:function(itemsMap){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap)if("boolean"!=typeof itemsMap[itemName])return!0;return!1},corruptRevision:function(rev){return"object"!=typeof rev||Array.isArray(rev)||rev.revision&&"string"!=typeof rev.revision||rev.body&&"string"!=typeof rev.body&&"object"!=typeof rev.body||rev.contentType&&"string"!=typeof rev.contentType||rev.contentLength&&"number"!=typeof rev.contentLength||rev.timestamp&&"number"!=typeof rev.timestamp||rev.itemsMap&&this.corruptItemsMap(rev.itemsMap)},isCorrupt:function(node){return"object"!=typeof node||Array.isArray(node)||"string"!=typeof node.path||this.corruptRevision(node.common)||node.local&&this.corruptRevision(node.local)||node.remote&&this.corruptRevision(node.remote)||node.push&&this.corruptRevision(node.push)},hasTasks:function(){return Object.getOwnPropertyNames(this._tasks).length>0},collectDiffTasks:function(){var num=0;return this.local.forAllNodes(function(node){num>100||(this.isCorrupt(node)?(RemoteStorage.log("[Sync] WARNING: corrupt node in local cache",node),"object"==typeof node&&node.path&&(this.addTask(node.path),num++)):this.needsFetch(node)&&this.access.checkPathPermission(node.path,"r")?(this.addTask(node.path),num++):isDocument(node.path)&&this.needsPush(node)&&this.access.checkPathPermission(node.path,"rw")&&(this.addTask(node.path),num++))}.bind(this)).then(function(){return num},function(err){throw err})},inConflict:function(node){return node.local&&node.remote&&(void 0!==node.remote.body||node.remote.itemsMap)},needsRefresh:function(node){return node.common?node.common.timestamp?this.now()-node.common.timestamp>syncInterval:!0:!1},needsFetch:function(node){return this.inConflict(node)?!0:node.common&&void 0===node.common.itemsMap&&void 0===node.common.body?!0:node.remote&&void 0===node.remote.itemsMap&&void 0===node.remote.body?!0:!1},needsPush:function(node){return this.inConflict(node)?!1:node.local&&!node.push?!0:void 0},needsRemotePut:function(node){return node.local&&node.local.body},needsRemoteDelete:function(node){return node.local&&node.local.body===!1},getParentPath:function(path){var parts=path.match(/^(.*\/)([^\/]+\/?)$/);if(parts)return parts[1];throw new Error('Not a valid path: "'+path+'"')},deleteChildPathsFromTasks:function(){for(var path in this._tasks)for(var paths=pathsFromRoot(path),i=1;i=numToAdd)return!0;for(path in this._tasks)if(!this._running[path]&&(this._timeStarted[path]=this.now(),this._running[path]=this.doTask(path),this._running[path].then(this.finishTask.bind(this)),numAdded++,numAdded>=numToAdd))return!0;return numAdded>=numToAdd},collectTasks:function(alsoCheckRefresh){return this.hasTasks()||this.stopped?Promise.resolve():this.collectDiffTasks().then(function(numDiffs){return numDiffs||alsoCheckRefresh===!1?Promise.resolve():this.collectRefreshTasks()}.bind(this),function(err){throw err})},addTask:function(path,cb){this._tasks[path]||(this._tasks[path]=[]),"function"==typeof cb&&this._tasks[path].push(cb)},sync:function(){return this.done=!1,this.doTasks()?Promise.resolve():this.collectTasks().then(function(){try{this.doTasks()}catch(e){console.error("[Sync] doTasks error",e)}}.bind(this),function(e){throw console.error("[Sync] Sync error",e),new Error("Local cache unavailable")})}},RemoteStorage.prototype.getSyncInterval=function(){return syncInterval},RemoteStorage.prototype.setSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=syncInterval;syncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getBackgroundSyncInterval=function(){return backgroundSyncInterval},RemoteStorage.prototype.setBackgroundSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=backgroundSyncInterval;backgroundSyncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getCurrentSyncInterval=function(){return isBackground?backgroundSyncInterval:syncInterval};var SyncError=function(originalError){var msg="Sync failed: ";msg+="object"==typeof originalError&&"message"in originalError?originalError.message:originalError,this.originalError=originalError,this.message=msg};SyncError.prototype=new Error,SyncError.prototype.constructor=SyncError,RemoteStorage.SyncError=SyncError,RemoteStorage.prototype.syncCycle=function(){this.sync.stopped||(this.sync.on("done",function(){RemoteStorage.log("[Sync] Sync done. Setting timer to",this.getCurrentSyncInterval()),this.sync.stopped||(this._syncTimer&&clearTimeout(this._syncTimer),this._syncTimer=setTimeout(this.sync.sync.bind(this.sync),this.getCurrentSyncInterval()))}.bind(this)),this.sync.sync())},RemoteStorage.prototype.stopSync=function(){this.sync?(RemoteStorage.log("[Sync] Stopping sync"),this.sync.stopped=!0):(RemoteStorage.log("[Sync] Will instantiate sync stopped"),this.syncStopped=!0)},RemoteStorage.prototype.startSync=function(){this.sync.stopped=!1,this.syncStopped=!1,this.sync.sync()};var syncCycleCb;RemoteStorage.Sync._rs_init=function(remoteStorage){syncCycleCb=function(){RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),RemoteStorage.Env.isBrowser()&&handleVisibility.bind(remoteStorage)(),remoteStorage.sync||(remoteStorage.sync=new RemoteStorage.Sync(remoteStorage.local,remoteStorage.remote,remoteStorage.access,remoteStorage.caching),remoteStorage.syncStopped&&(RemoteStorage.log("[Sync] Instantiating sync stopped"),remoteStorage.sync.stopped=!0,delete remoteStorage.syncStopped)),RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),remoteStorage.syncCycle()},syncOnConnect=function(){remoteStorage.removeEventListener("connected",syncOnConnect),remoteStorage.startSync()},remoteStorage.on("ready",syncCycleCb),remoteStorage.on("connected",syncOnConnect)},RemoteStorage.Sync._rs_cleanup=function(remoteStorage){remoteStorage.stopSync(),remoteStorage.removeEventListener("ready",syncCycleCb),remoteStorage.removeEventListener("connected",syncOnConnect),delete remoteStorage.sync}}("undefined"!=typeof window?window:global),function(){function getLatest(node){if("object"==typeof node&&"string"==typeof node.path)if(isFolder(node.path)){if(node.local&&node.local.itemsMap)return node.local;if(node.common&&node.common.itemsMap)return node.common}else{if(node.local&&node.local.body&&node.local.contentType)return node.local;if(node.common&&node.common.body&&node.common.contentType)return node.common;if(node.body&&node.contentType)return{body:node.body,contentType:node.contentType}}}function isOutdated(nodes,maxAge){var path;for(path in nodes){if(nodes[path]&&nodes[path].remote)return!0;var nodeVersion=getLatest(nodes[path]);if(nodeVersion&&nodeVersion.timestamp&&(new Date).getTime()-nodeVersion.timestamp<=maxAge)return!1;if(!nodeVersion)return!0}return!0}function makeNode(path){var node={path:path,common:{}};return isFolder(path)&&(node.common.itemsMap={}),node}function updateFolderNodeWithItemName(node,itemName){return node.common||(node.common={itemsMap:{}}),node.common.itemsMap||(node.common.itemsMap={}),node.local||(node.local=deepClone(node.common)),node.local.itemsMap||(node.local.itemsMap=node.common.itemsMap),node.local.itemsMap[itemName]=!0,node}var isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=(RemoteStorage.util.equal,RemoteStorage.util.pathsFromRoot),methods={get:function(path,maxAge,queueGetRequest){var self=this;return"number"==typeof maxAge?self.getNodes(pathsFromRoot(path)).then(function(objs){var node=getLatest(objs[path]);return isOutdated(objs,maxAge)?queueGetRequest(path):node?{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}:{statusCode:404}}):self.getNodes([path]).then(function(objs){var node=getLatest(objs[path]);if(node){if(isFolder(path))for(var i in node.itemsMap)node.itemsMap.hasOwnProperty(i)&&node.itemsMap[i]===!1&&delete node.itemsMap[i];return{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}}return{statusCode:404}})},put:function(path,body,contentType){function _processNodes(paths,nodes){try{for(var i=0,len=paths.length;len>i;i++){var previous,path=paths[i],node=nodes[path];if(node||(nodes[path]=node=makeNode(path)),0===i)previous=getLatest(node),node.local={body:body,contentType:contentType,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{var itemName=paths[i-1].substring(path.length);node=updateFolderNodeWithItemName(node,itemName)}}return nodes}catch(e){throw RemoteStorage.log("[Cachinglayer] Error during PUT",nodes,i,e),e}}var paths=pathsFromRoot(path);return this._updateNodes(paths,_processNodes)},"delete":function(path){var paths=pathsFromRoot(path);return this._updateNodes(paths,function(paths,nodes){for(var i=0,len=paths.length;len>i;i++){var path=paths[i],node=nodes[path];if(!node)throw new Error("Cannot delete non-existing node "+path);if(0===i)previous=getLatest(node),node.local={body:!1,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{node.local||(node.local=deepClone(node.common));var itemName=paths[i-1].substring(path.length);if(delete node.local.itemsMap[itemName],Object.getOwnPropertyNames(node.local.itemsMap).length>0)break}}return nodes})},flush:function(path){var self=this;return self._getAllDescendentPaths(path).then(function(paths){return self.getNodes(paths)}).then(function(nodes){for(var path in nodes){var node=nodes[path];node&&node.common&&node.local&&self._emitChange({path:node.path,origin:"local",oldValue:node.local.body===!1?void 0:node.local.body,newValue:node.common.body===!1?void 0:node.common.body}),nodes[path]=void 0}return self.setNodes(nodes)})},_emitChange:function(obj){RemoteStorage.config.changeEvents[obj.origin]&&this._emit("change",obj)},fireInitial:function(){if(RemoteStorage.config.changeEvents.local){var self=this;self.forAllNodes(function(node){var latest;isDocument(node.path)&&(latest=getLatest(node),latest&&self._emitChange({path:node.path,origin:"local",oldValue:void 0,oldContentType:void 0,newValue:latest.body,newContentType:latest.contentType}))}).then(function(){self._emit("local-events-done")})}},onDiff:function(diffHandler){this.diffHandler=diffHandler},migrate:function(node){return"object"!=typeof node||node.common||(node.common={},"string"==typeof node.path?"/"===node.path.substr(-1)&&"object"==typeof node.body&&(node.common.itemsMap=node.body):(node.local||(node.local={}),node.local.body=node.body,node.local.contentType=node.contentType)),node},_updateNodesRunning:!1,_updateNodesQueued:[],_updateNodes:function(paths,_processNodes){var pending=Promise.defer();return this._doUpdateNodes(paths,_processNodes,pending),pending.promise},_doUpdateNodes:function(paths,_processNodes,promise){var self=this;return self._updateNodesRunning?void self._updateNodesQueued.push({paths:paths,cb:_processNodes,promise:promise}):(self._updateNodesRunning=!0,void self.getNodes(paths).then(function(nodes){var node,existingNodes=deepClone(nodes),changeEvents=[],equal=RemoteStorage.util.equal;nodes=_processNodes(paths,nodes);for(var path in nodes)node=nodes[path],equal(node,existingNodes[path])?delete nodes[path]:isDocument(path)&&(equal(node.local.body,node.local.previousBody)&&node.local.contentType===node.local.previousContentType||changeEvents.push({path:path,origin:"window",oldValue:node.local.previousBody,newValue:node.local.body===!1?void 0:node.local.body,oldContentType:node.local.previousContentType,newContentType:node.local.contentType}),delete node.local.previousBody,delete node.local.previousContentType);self.setNodes(nodes).then(function(){self._emitChangeEvents(changeEvents),promise.resolve({statusCode:200})})}).then(function(){return Promise.resolve()},function(err){promise.reject(err)}).then(function(){self._updateNodesRunning=!1;var nextJob=self._updateNodesQueued.shift();nextJob&&self._doUpdateNodes(nextJob.paths,nextJob.cb,nextJob.promise)}))},_emitChangeEvents:function(events){for(var i=0,len=events.length;len>i;i++)this._emitChange(events[i]),this.diffHandler&&this.diffHandler(events[i].path)},_getAllDescendentPaths:function(path){var self=this;return isFolder(path)?self.getNodes([path]).then(function(nodes){var allPaths=[path],latest=getLatest(nodes[path]),itemNames=Object.keys(latest.itemsMap),calls=itemNames.map(function(itemName){return self._getAllDescendentPaths(path+itemName).then(function(paths){for(var i=0,len=paths.length;len>i;i++)allPaths.push(paths[i])})});return Promise.all(calls).then(function(){return allPaths})}):Promise.resolve([path])},_getInternals:function(){return{getLatest:getLatest,makeNode:makeNode,isOutdated:isOutdated}}};RemoteStorage.cachingLayer=function(object){for(var key in methods)object[key]=methods[key]}}(),function(global){var DEFAULT_DB,RS=RemoteStorage,DB_VERSION=2,DEFAULT_DB_NAME="remotestorage";RS.IndexedDB=function(database){return this.db=database||DEFAULT_DB,this.db?(RS.cachingLayer(this),RS.eventHandling(this,"change","local-events-done"),this.getsRunning=0,this.putsRunning=0,this.changesQueued={},void(this.changesRunning={})):void RemoteStorage.log("[IndexedDB] Failed to open DB")},RS.IndexedDB.prototype={getNodes:function(paths){for(var misses=[],fromCache={},i=0,len=paths.length;len>i;i++)void 0!==this.changesQueued[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesQueued[paths[i]]||void 0):void 0!==this.changesRunning[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesRunning[paths[i]]||void 0):misses.push(paths[i]);return misses.length>0?this.getNodesFromDb(misses).then(function(nodes){for(var i in fromCache)nodes[i]=fromCache[i];return nodes}):Promise.resolve(fromCache)},setNodes:function(nodes){for(var i in nodes)this.changesQueued[i]=nodes[i]||!1;return this.maybeFlush(),Promise.resolve()},maybeFlush:function(){0===this.putsRunning?this.flushChangesQueued():this.commitSlownessWarning||(this.commitSlownessWarning=setInterval(function(){console.log("WARNING: waited more than 10 seconds for previous commit to finish")},1e4))},flushChangesQueued:function(){this.commitSlownessWarning&&(clearInterval(this.commitSlownessWarning),this.commitSlownessWarning=null),Object.keys(this.changesQueued).length>0&&(this.changesRunning=this.changesQueued,this.changesQueued={},this.setNodesInDb(this.changesRunning).then(this.flushChangesQueued.bind(this)))},getNodesFromDb:function(paths){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),nodes=transaction.objectStore("nodes"),retrievedNodes={};(new Date).getTime();return this.getsRunning++,paths.map(function(path,i){nodes.get(path).onsuccess=function(evt){retrievedNodes[path]=evt.target.result}}),transaction.oncomplete=function(){pending.resolve(retrievedNodes),this.getsRunning--}.bind(this),transaction.onerror=transaction.onabort=function(){pending.reject("get transaction error/abort"),this.getsRunning--}.bind(this),pending.promise},setNodesInDb:function(nodes){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readwrite"),nodesStore=transaction.objectStore("nodes"),startTime=(new Date).getTime(); -this.putsRunning++,RemoteStorage.log("[IndexedDB] Starting put",nodes,this.putsRunning);for(var path in nodes){var node=nodes[path];if("object"==typeof node)try{nodesStore.put(node)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while putting",node,e),e}else try{nodesStore["delete"](path)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while removing",nodesStore,node,e),e}}return transaction.oncomplete=function(){this.putsRunning--,RemoteStorage.log("[IndexedDB] Finished put",nodes,this.putsRunning,(new Date).getTime()-startTime+"ms"),pending.resolve()}.bind(this),transaction.onerror=function(){this.putsRunning--,pending.reject("transaction error")}.bind(this),transaction.onabort=function(){pending.reject("transaction abort"),this.putsRunning--}.bind(this),pending.promise},reset:function(callback){var dbName=this.db.name,self=this;this.db.close(),RS.IndexedDB.clean(this.db.name,function(){RS.IndexedDB.open(dbName,function(err,other){err?RemoteStorage.log("[IndexedDB] Error while resetting local storage",err):self.db=other,"function"==typeof callback&&callback(self)})})},forAllNodes:function(cb){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),cursorReq=transaction.objectStore("nodes").openCursor();return cursorReq.onsuccess=function(evt){var cursor=evt.target.result;cursor?(cb(this.migrate(cursor.value)),cursor["continue"]()):pending.resolve()}.bind(this),pending.promise},closeDB:function(){this.db.close()}},RS.IndexedDB.open=function(name,callback){var timer=setTimeout(function(){callback("timeout trying to open db")},1e4);try{var req=indexedDB.open(name,DB_VERSION);req.onerror=function(){RemoteStorage.log("[IndexedDB] Opening DB failed",req),clearTimeout(timer),callback(req.error)},req.onupgradeneeded=function(event){var db=req.result;RemoteStorage.log("[IndexedDB] Upgrade: from ",event.oldVersion," to ",event.newVersion),1!==event.oldVersion&&(RemoteStorage.log("[IndexedDB] Creating object store: nodes"),db.createObjectStore("nodes",{keyPath:"path"})),RemoteStorage.log("[IndexedDB] Creating object store: changes"),db.createObjectStore("changes",{keyPath:"path"})},req.onsuccess=function(){clearTimeout(timer);var db=req.result;return db.objectStoreNames.contains("nodes")&&db.objectStoreNames.contains("changes")?void callback(null,req.result):(RemoteStorage.log("[IndexedDB] Missing object store. Resetting the database."),void RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)}))}}catch(error){RemoteStorage.log("[IndexedDB] Failed to open database: "+error),RemoteStorage.log("[IndexedDB] Resetting database and trying again."),clearTimeout(timer),RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)})}},RS.IndexedDB.clean=function(databaseName,callback){var req=indexedDB.deleteDatabase(databaseName);req.onsuccess=function(){RemoteStorage.log("[IndexedDB] Done removing DB"),callback()},req.onerror=req.onabort=function(evt){console.error('Failed to remove database "'+databaseName+'"',evt)}},RS.IndexedDB._rs_init=function(remoteStorage){var pending=Promise.defer();return RS.IndexedDB.open(DEFAULT_DB_NAME,function(err,db){err?pending.reject(err):(DEFAULT_DB=db,db.onerror=function(){remoteStorage._emit("error",err)},pending.resolve())}),pending.promise},RS.IndexedDB._rs_supported=function(){var pending=Promise.defer();global.indexedDB=global.indexedDB||global.webkitIndexedDB||global.mozIndexedDB||global.oIndexedDB||global.msIndexedDB;var poorIndexedDbSupport=!1;if("undefined"!=typeof global.navigator&&global.navigator.userAgent.match(/Android (2|3|4\.[0-3])/)&&(navigator.userAgent.match(/Chrome|Firefox/)||(poorIndexedDbSupport=!0)),"indexedDB"in global&&!poorIndexedDbSupport)try{var check=indexedDB.open("rs-check");check.onerror=function(event){pending.reject()},check.onsuccess=function(event){check.result.close(),indexedDB.deleteDatabase("rs-check"),pending.resolve()}}catch(e){pending.reject()}else pending.reject();return pending.promise},RS.IndexedDB._rs_cleanup=function(remoteStorage){var pending=Promise.defer();return remoteStorage.local&&remoteStorage.local.closeDB(),RS.IndexedDB.clean(DEFAULT_DB_NAME,function(){pending.resolve()}),pending.promise}}("undefined"!=typeof window?window:global),function(global){function isRemoteStorageKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX||key.substr(0,CHANGES_PREFIX.length)===CHANGES_PREFIX}function isNodeKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX}var NODES_PREFIX="remotestorage:cache:nodes:",CHANGES_PREFIX="remotestorage:cache:changes:";RemoteStorage.LocalStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[LocalStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done")},RemoteStorage.LocalStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)try{nodes[paths[i]]=JSON.parse(localStorage[NODES_PREFIX+paths[i]])}catch(e){nodes[paths[i]]=void 0}return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)localStorage[NODES_PREFIX+path]=JSON.stringify(nodes[path]);return Promise.resolve()},forAllNodes:function(cb){for(var node,i=0,len=localStorage.length;len>i;i++)if(isNodeKey(localStorage.key(i))){try{node=this.migrate(JSON.parse(localStorage[localStorage.key(i)]))}catch(e){node=void 0}node&&cb(node)}return Promise.resolve()}},RemoteStorage.LocalStorage._rs_init=function(){},RemoteStorage.LocalStorage._rs_supported=function(){return RemoteStorage.util.localStorageAvailable()},RemoteStorage.LocalStorage._rs_cleanup=function(){for(var keys=[],i=0,len=localStorage.length;len>i;i++){var key=localStorage.key(i);isRemoteStorageKey(key)&&keys.push(key)}keys.forEach(function(key){RemoteStorage.log("[LocalStorage] Removing",key),delete localStorage[key]})}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.InMemoryStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[InMemoryStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done"),this._storage={}},RemoteStorage.InMemoryStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)nodes[paths[i]]=this._storage[paths[i]];return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)void 0===nodes[path]?delete this._storage[path]:this._storage[path]=nodes[path];return Promise.resolve()},forAllNodes:function(cb){for(var path in this._storage)cb(this.migrate(this._storage[path]));return Promise.resolve()}},RemoteStorage.InMemoryStorage._rs_init=function(){},RemoteStorage.InMemoryStorage._rs_supported=function(){return!0},RemoteStorage.InMemoryStorage._rs_cleanup=function(){}}("undefined"!=typeof window?window:global),function(){RemoteStorage.MODULES={},RemoteStorage.defineModule=function(moduleName,builder){if(RemoteStorage.MODULES[moduleName]=builder,Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,RS.WireClient.request(method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():xhr})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){rs._emit("error",new RemoteStorage.SyncError(err))})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?global.setTimeout(self._request(method,url,options),3210):Promise.resolve(xhr)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return;rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),promise.reject(err)}).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response); -}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):((200===resp.status||404===resp.status)&&(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file +},RemoteStorage.Caching.prototype={pendingActivations:[],set:function(path,strategy){if("string"!=typeof path)throw new Error("path should be a string");if(!RemoteStorage.util.isFolder(path))throw new Error("path should be a folder");if(this._remoteStorage&&this._remoteStorage.access&&!this._remoteStorage.access.checkPathPermission(path,"r"))throw new Error('No access to path "'+path+'". You have to claim access to it first.');if(!strategy.match(/^(FLUSH|SEEN|ALL)$/))throw new Error("strategy should be 'FLUSH', 'SEEN', or 'ALL'");this._rootPaths[path]=strategy,"ALL"===strategy&&(this.activateHandler?this.activateHandler(path):this.pendingActivations.push(path))},enable:function(path){this.set(path,"ALL")},disable:function(path){this.set(path,"FLUSH")},onActivate:function(cb){var i;for(RemoteStorage.log("[Caching] Setting activate handler",cb,this.pendingActivations),this.activateHandler=cb,i=0;i1e3&&36e5>interval}var syncInterval=1e4,backgroundSyncInterval=6e4,isBackground=!1,isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,equal=RemoteStorage.util.equal,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=RemoteStorage.util.pathsFromRoot;RemoteStorage.Sync=function(setLocal,setRemote,setAccess,setCaching){this.local=setLocal,this.local.onDiff(function(path){this.addTask(path),this.doTasks()}.bind(this)),this.remote=setRemote,this.access=setAccess,this.caching=setCaching,this._tasks={},this._running={},this._timeStarted={},RemoteStorage.eventHandling(this,"done","req-done"),this.caching.onActivate(function(path){this.addTask(path),this.doTasks()}.bind(this))},RemoteStorage.Sync.prototype={now:function(){return(new Date).getTime()},queueGetRequest:function(path){var pending=Promise.defer();return this.remote.connected?this.remote.online?(this.addTask(path,function(){this.local.get(path).then(function(r){return pending.resolve(r)})}.bind(this)),this.doTasks()):pending.reject("cannot fulfill maxAge requirement - remote is not online"):pending.reject("cannot fulfill maxAge requirement - remote is not connected"),pending.promise},corruptServerItemsMap:function(itemsMap,force02){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap){var item=itemsMap[itemName];if("object"!=typeof item)return!0;if("string"!=typeof item.ETag)return!0;if(isFolder(itemName)){if(-1!==itemName.substring(0,itemName.length-1).indexOf("/"))return!0}else{if(-1!==itemName.indexOf("/"))return!0;if(force02){if("string"!=typeof item["Content-Type"])return!0;if("number"!=typeof item["Content-Length"])return!0}}}return!1},corruptItemsMap:function(itemsMap){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap)if("boolean"!=typeof itemsMap[itemName])return!0;return!1},corruptRevision:function(rev){return"object"!=typeof rev||Array.isArray(rev)||rev.revision&&"string"!=typeof rev.revision||rev.body&&"string"!=typeof rev.body&&"object"!=typeof rev.body||rev.contentType&&"string"!=typeof rev.contentType||rev.contentLength&&"number"!=typeof rev.contentLength||rev.timestamp&&"number"!=typeof rev.timestamp||rev.itemsMap&&this.corruptItemsMap(rev.itemsMap)},isCorrupt:function(node){return"object"!=typeof node||Array.isArray(node)||"string"!=typeof node.path||this.corruptRevision(node.common)||node.local&&this.corruptRevision(node.local)||node.remote&&this.corruptRevision(node.remote)||node.push&&this.corruptRevision(node.push)},hasTasks:function(){return Object.getOwnPropertyNames(this._tasks).length>0},collectDiffTasks:function(){var num=0;return this.local.forAllNodes(function(node){num>100||(this.isCorrupt(node)?(RemoteStorage.log("[Sync] WARNING: corrupt node in local cache",node),"object"==typeof node&&node.path&&(this.addTask(node.path),num++)):this.needsFetch(node)&&this.access.checkPathPermission(node.path,"r")?(this.addTask(node.path),num++):isDocument(node.path)&&this.needsPush(node)&&this.access.checkPathPermission(node.path,"rw")&&(this.addTask(node.path),num++))}.bind(this)).then(function(){return num},function(err){throw err})},inConflict:function(node){return node.local&&node.remote&&(void 0!==node.remote.body||node.remote.itemsMap)},needsRefresh:function(node){return node.common?node.common.timestamp?this.now()-node.common.timestamp>syncInterval:!0:!1},needsFetch:function(node){return this.inConflict(node)?!0:node.common&&void 0===node.common.itemsMap&&void 0===node.common.body?!0:node.remote&&void 0===node.remote.itemsMap&&void 0===node.remote.body?!0:!1},needsPush:function(node){return this.inConflict(node)?!1:node.local&&!node.push?!0:void 0},needsRemotePut:function(node){return node.local&&node.local.body},needsRemoteDelete:function(node){return node.local&&node.local.body===!1},getParentPath:function(path){var parts=path.match(/^(.*\/)([^\/]+\/?)$/);if(parts)return parts[1];throw new Error('Not a valid path: "'+path+'"')},deleteChildPathsFromTasks:function(){for(var path in this._tasks)for(var paths=pathsFromRoot(path),i=1;i=numToAdd)return!0;for(path in this._tasks)if(!this._running[path]&&(this._timeStarted[path]=this.now(),this._running[path]=this.doTask(path),this._running[path].then(this.finishTask.bind(this)),numAdded++,numAdded>=numToAdd))return!0;return numAdded>=numToAdd},collectTasks:function(alsoCheckRefresh){return this.hasTasks()||this.stopped?Promise.resolve():this.collectDiffTasks().then(function(numDiffs){return numDiffs||alsoCheckRefresh===!1?Promise.resolve():this.collectRefreshTasks()}.bind(this),function(err){throw err})},addTask:function(path,cb){this._tasks[path]||(this._tasks[path]=[]),"function"==typeof cb&&this._tasks[path].push(cb)},sync:function(){return this.done=!1,this.doTasks()?Promise.resolve():this.collectTasks().then(function(){try{this.doTasks()}catch(e){console.error("[Sync] doTasks error",e)}}.bind(this),function(e){throw console.error("[Sync] Sync error",e),new Error("Local cache unavailable")})}},RemoteStorage.prototype.getSyncInterval=function(){return syncInterval},RemoteStorage.prototype.setSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=syncInterval;syncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getBackgroundSyncInterval=function(){return backgroundSyncInterval},RemoteStorage.prototype.setBackgroundSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=backgroundSyncInterval;backgroundSyncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getCurrentSyncInterval=function(){return isBackground?backgroundSyncInterval:syncInterval};var SyncError=function(originalError){var msg="Sync failed: ";msg+="object"==typeof originalError&&"message"in originalError?originalError.message:originalError,this.originalError=originalError,this.message=msg};SyncError.prototype=new Error,SyncError.prototype.constructor=SyncError,RemoteStorage.SyncError=SyncError,RemoteStorage.prototype.syncCycle=function(){this.sync.stopped||(this.sync.on("done",function(){RemoteStorage.log("[Sync] Sync done. Setting timer to",this.getCurrentSyncInterval()),this.sync.stopped||(this._syncTimer&&clearTimeout(this._syncTimer),this._syncTimer=setTimeout(this.sync.sync.bind(this.sync),this.getCurrentSyncInterval()))}.bind(this)),this.sync.sync())},RemoteStorage.prototype.stopSync=function(){this.sync?(RemoteStorage.log("[Sync] Stopping sync"),this.sync.stopped=!0):(RemoteStorage.log("[Sync] Will instantiate sync stopped"),this.syncStopped=!0)},RemoteStorage.prototype.startSync=function(){this.sync.stopped=!1,this.syncStopped=!1,this.sync.sync()};var syncCycleCb;RemoteStorage.Sync._rs_init=function(remoteStorage){syncCycleCb=function(){RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),RemoteStorage.Env.isBrowser()&&handleVisibility.bind(remoteStorage)(),remoteStorage.sync||(remoteStorage.sync=new RemoteStorage.Sync(remoteStorage.local,remoteStorage.remote,remoteStorage.access,remoteStorage.caching),remoteStorage.syncStopped&&(RemoteStorage.log("[Sync] Instantiating sync stopped"),remoteStorage.sync.stopped=!0,delete remoteStorage.syncStopped)),RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),remoteStorage.syncCycle()},syncOnConnect=function(){remoteStorage.removeEventListener("connected",syncOnConnect),remoteStorage.startSync()},remoteStorage.on("ready",syncCycleCb),remoteStorage.on("connected",syncOnConnect)},RemoteStorage.Sync._rs_cleanup=function(remoteStorage){remoteStorage.stopSync(),remoteStorage.removeEventListener("ready",syncCycleCb),remoteStorage.removeEventListener("connected",syncOnConnect),delete remoteStorage.sync}}("undefined"!=typeof window?window:global),function(){function getLatest(node){if("object"==typeof node&&"string"==typeof node.path)if(isFolder(node.path)){if(node.local&&node.local.itemsMap)return node.local;if(node.common&&node.common.itemsMap)return node.common}else{if(node.local&&node.local.body&&node.local.contentType)return node.local;if(node.common&&node.common.body&&node.common.contentType)return node.common;if(node.body&&node.contentType)return{body:node.body,contentType:node.contentType}}}function isOutdated(nodes,maxAge){var path;for(path in nodes){if(nodes[path]&&nodes[path].remote)return!0;var nodeVersion=getLatest(nodes[path]);if(nodeVersion&&nodeVersion.timestamp&&(new Date).getTime()-nodeVersion.timestamp<=maxAge)return!1;if(!nodeVersion)return!0}return!0}function makeNode(path){var node={path:path,common:{}};return isFolder(path)&&(node.common.itemsMap={}),node}function updateFolderNodeWithItemName(node,itemName){return node.common||(node.common={itemsMap:{}}),node.common.itemsMap||(node.common.itemsMap={}),node.local||(node.local=deepClone(node.common)),node.local.itemsMap||(node.local.itemsMap=node.common.itemsMap),node.local.itemsMap[itemName]=!0,node}var isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=(RemoteStorage.util.equal,RemoteStorage.util.pathsFromRoot),methods={get:function(path,maxAge,queueGetRequest){var self=this;return"number"==typeof maxAge?self.getNodes(pathsFromRoot(path)).then(function(objs){var node=getLatest(objs[path]);return isOutdated(objs,maxAge)?queueGetRequest(path):node?{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}:{statusCode:404}}):self.getNodes([path]).then(function(objs){var node=getLatest(objs[path]);if(node){if(isFolder(path))for(var i in node.itemsMap)node.itemsMap.hasOwnProperty(i)&&node.itemsMap[i]===!1&&delete node.itemsMap[i];return{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}}return{statusCode:404}})},put:function(path,body,contentType){function _processNodes(paths,nodes){try{for(var i=0,len=paths.length;len>i;i++){var previous,path=paths[i],node=nodes[path];if(node||(nodes[path]=node=makeNode(path)),0===i)previous=getLatest(node),node.local={body:body,contentType:contentType,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{var itemName=paths[i-1].substring(path.length);node=updateFolderNodeWithItemName(node,itemName)}}return nodes}catch(e){throw RemoteStorage.log("[Cachinglayer] Error during PUT",nodes,i,e),e}}var paths=pathsFromRoot(path);return this._updateNodes(paths,_processNodes)},"delete":function(path){var paths=pathsFromRoot(path);return this._updateNodes(paths,function(paths,nodes){for(var i=0,len=paths.length;len>i;i++){var path=paths[i],node=nodes[path];if(!node)throw new Error("Cannot delete non-existing node "+path);if(0===i)previous=getLatest(node),node.local={body:!1,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{node.local||(node.local=deepClone(node.common));var itemName=paths[i-1].substring(path.length);if(delete node.local.itemsMap[itemName],Object.getOwnPropertyNames(node.local.itemsMap).length>0)break}}return nodes})},flush:function(path){var self=this;return self._getAllDescendentPaths(path).then(function(paths){return self.getNodes(paths)}).then(function(nodes){for(var path in nodes){var node=nodes[path];node&&node.common&&node.local&&self._emitChange({path:node.path,origin:"local",oldValue:node.local.body===!1?void 0:node.local.body,newValue:node.common.body===!1?void 0:node.common.body}),nodes[path]=void 0}return self.setNodes(nodes)})},_emitChange:function(obj){RemoteStorage.config.changeEvents[obj.origin]&&this._emit("change",obj)},fireInitial:function(){if(RemoteStorage.config.changeEvents.local){var self=this;self.forAllNodes(function(node){var latest;isDocument(node.path)&&(latest=getLatest(node),latest&&self._emitChange({path:node.path,origin:"local",oldValue:void 0,oldContentType:void 0,newValue:latest.body,newContentType:latest.contentType}))}).then(function(){self._emit("local-events-done")})}},onDiff:function(diffHandler){this.diffHandler=diffHandler},migrate:function(node){return"object"!=typeof node||node.common||(node.common={},"string"==typeof node.path?"/"===node.path.substr(-1)&&"object"==typeof node.body&&(node.common.itemsMap=node.body):(node.local||(node.local={}),node.local.body=node.body,node.local.contentType=node.contentType)),node},_updateNodesRunning:!1,_updateNodesQueued:[],_updateNodes:function(paths,_processNodes){var pending=Promise.defer();return this._doUpdateNodes(paths,_processNodes,pending),pending.promise},_doUpdateNodes:function(paths,_processNodes,promise){var self=this;return self._updateNodesRunning?void self._updateNodesQueued.push({paths:paths,cb:_processNodes,promise:promise}):(self._updateNodesRunning=!0,void self.getNodes(paths).then(function(nodes){var node,existingNodes=deepClone(nodes),changeEvents=[],equal=RemoteStorage.util.equal;nodes=_processNodes(paths,nodes);for(var path in nodes)node=nodes[path],equal(node,existingNodes[path])?delete nodes[path]:isDocument(path)&&(equal(node.local.body,node.local.previousBody)&&node.local.contentType===node.local.previousContentType||changeEvents.push({path:path,origin:"window",oldValue:node.local.previousBody,newValue:node.local.body===!1?void 0:node.local.body,oldContentType:node.local.previousContentType,newContentType:node.local.contentType}),delete node.local.previousBody,delete node.local.previousContentType);self.setNodes(nodes).then(function(){self._emitChangeEvents(changeEvents),promise.resolve({statusCode:200})})}).then(function(){return Promise.resolve()},function(err){promise.reject(err)}).then(function(){self._updateNodesRunning=!1;var nextJob=self._updateNodesQueued.shift();nextJob&&self._doUpdateNodes(nextJob.paths,nextJob.cb,nextJob.promise)}))},_emitChangeEvents:function(events){for(var i=0,len=events.length;len>i;i++)this._emitChange(events[i]),this.diffHandler&&this.diffHandler(events[i].path)},_getAllDescendentPaths:function(path){var self=this;return isFolder(path)?self.getNodes([path]).then(function(nodes){var allPaths=[path],latest=getLatest(nodes[path]),itemNames=Object.keys(latest.itemsMap),calls=itemNames.map(function(itemName){return self._getAllDescendentPaths(path+itemName).then(function(paths){for(var i=0,len=paths.length;len>i;i++)allPaths.push(paths[i])})});return Promise.all(calls).then(function(){return allPaths})}):Promise.resolve([path])},_getInternals:function(){return{getLatest:getLatest,makeNode:makeNode,isOutdated:isOutdated}}};RemoteStorage.cachingLayer=function(object){for(var key in methods)object[key]=methods[key]}}(),function(global){var DEFAULT_DB,RS=RemoteStorage,DB_VERSION=2,DEFAULT_DB_NAME="remotestorage";RS.IndexedDB=function(database){return this.db=database||DEFAULT_DB,this.db?(RS.cachingLayer(this),RS.eventHandling(this,"change","local-events-done"),this.getsRunning=0,this.putsRunning=0,this.changesQueued={},void(this.changesRunning={})):void RemoteStorage.log("[IndexedDB] Failed to open DB")},RS.IndexedDB.prototype={getNodes:function(paths){for(var misses=[],fromCache={},i=0,len=paths.length;len>i;i++)void 0!==this.changesQueued[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesQueued[paths[i]]||void 0):void 0!==this.changesRunning[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesRunning[paths[i]]||void 0):misses.push(paths[i]);return misses.length>0?this.getNodesFromDb(misses).then(function(nodes){for(var i in fromCache)nodes[i]=fromCache[i];return nodes}):Promise.resolve(fromCache)},setNodes:function(nodes){for(var i in nodes)this.changesQueued[i]=nodes[i]||!1;return this.maybeFlush(),Promise.resolve()},maybeFlush:function(){0===this.putsRunning?this.flushChangesQueued():this.commitSlownessWarning||(this.commitSlownessWarning=setInterval(function(){console.log("WARNING: waited more than 10 seconds for previous commit to finish")},1e4))},flushChangesQueued:function(){this.commitSlownessWarning&&(clearInterval(this.commitSlownessWarning),this.commitSlownessWarning=null),Object.keys(this.changesQueued).length>0&&(this.changesRunning=this.changesQueued,this.changesQueued={},this.setNodesInDb(this.changesRunning).then(this.flushChangesQueued.bind(this)))},getNodesFromDb:function(paths){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),nodes=transaction.objectStore("nodes"),retrievedNodes={};(new Date).getTime();return this.getsRunning++,paths.map(function(path,i){nodes.get(path).onsuccess=function(evt){retrievedNodes[path]=evt.target.result}}),transaction.oncomplete=function(){pending.resolve(retrievedNodes),this.getsRunning--}.bind(this),transaction.onerror=transaction.onabort=function(){pending.reject("get transaction error/abort"),this.getsRunning--}.bind(this),pending.promise},setNodesInDb:function(nodes){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readwrite"),nodesStore=transaction.objectStore("nodes"),startTime=(new Date).getTime(); +this.putsRunning++,RemoteStorage.log("[IndexedDB] Starting put",nodes,this.putsRunning);for(var path in nodes){var node=nodes[path];if("object"==typeof node)try{nodesStore.put(node)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while putting",node,e),e}else try{nodesStore["delete"](path)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while removing",nodesStore,node,e),e}}return transaction.oncomplete=function(){this.putsRunning--,RemoteStorage.log("[IndexedDB] Finished put",nodes,this.putsRunning,(new Date).getTime()-startTime+"ms"),pending.resolve()}.bind(this),transaction.onerror=function(){this.putsRunning--,pending.reject("transaction error")}.bind(this),transaction.onabort=function(){pending.reject("transaction abort"),this.putsRunning--}.bind(this),pending.promise},reset:function(callback){var dbName=this.db.name,self=this;this.db.close(),RS.IndexedDB.clean(this.db.name,function(){RS.IndexedDB.open(dbName,function(err,other){err?RemoteStorage.log("[IndexedDB] Error while resetting local storage",err):self.db=other,"function"==typeof callback&&callback(self)})})},forAllNodes:function(cb){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),cursorReq=transaction.objectStore("nodes").openCursor();return cursorReq.onsuccess=function(evt){var cursor=evt.target.result;cursor?(cb(this.migrate(cursor.value)),cursor["continue"]()):pending.resolve()}.bind(this),pending.promise},closeDB:function(){this.db.close()}},RS.IndexedDB.open=function(name,callback){var timer=setTimeout(function(){callback("timeout trying to open db")},1e4);try{var req=indexedDB.open(name,DB_VERSION);req.onerror=function(){RemoteStorage.log("[IndexedDB] Opening DB failed",req),clearTimeout(timer),callback(req.error)},req.onupgradeneeded=function(event){var db=req.result;RemoteStorage.log("[IndexedDB] Upgrade: from ",event.oldVersion," to ",event.newVersion),1!==event.oldVersion&&(RemoteStorage.log("[IndexedDB] Creating object store: nodes"),db.createObjectStore("nodes",{keyPath:"path"})),RemoteStorage.log("[IndexedDB] Creating object store: changes"),db.createObjectStore("changes",{keyPath:"path"})},req.onsuccess=function(){clearTimeout(timer);var db=req.result;return db.objectStoreNames.contains("nodes")&&db.objectStoreNames.contains("changes")?void callback(null,req.result):(RemoteStorage.log("[IndexedDB] Missing object store. Resetting the database."),void RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)}))}}catch(error){RemoteStorage.log("[IndexedDB] Failed to open database: "+error),RemoteStorage.log("[IndexedDB] Resetting database and trying again."),clearTimeout(timer),RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)})}},RS.IndexedDB.clean=function(databaseName,callback){var req=indexedDB.deleteDatabase(databaseName);req.onsuccess=function(){RemoteStorage.log("[IndexedDB] Done removing DB"),callback()},req.onerror=req.onabort=function(evt){console.error('Failed to remove database "'+databaseName+'"',evt)}},RS.IndexedDB._rs_init=function(remoteStorage){var pending=Promise.defer();return RS.IndexedDB.open(DEFAULT_DB_NAME,function(err,db){err?pending.reject(err):(DEFAULT_DB=db,db.onerror=function(){remoteStorage._emit("error",err)},pending.resolve())}),pending.promise},RS.IndexedDB._rs_supported=function(){var pending=Promise.defer();global.indexedDB=global.indexedDB||global.webkitIndexedDB||global.mozIndexedDB||global.oIndexedDB||global.msIndexedDB;var poorIndexedDbSupport=!1;if("undefined"!=typeof global.navigator&&global.navigator.userAgent.match(/Android (2|3|4\.[0-3])/)&&(navigator.userAgent.match(/Chrome|Firefox/)||(poorIndexedDbSupport=!0)),"indexedDB"in global&&!poorIndexedDbSupport)try{var check=indexedDB.open("rs-check");check.onerror=function(event){pending.reject()},check.onsuccess=function(event){check.result.close(),indexedDB.deleteDatabase("rs-check"),pending.resolve()}}catch(e){pending.reject()}else pending.reject();return pending.promise},RS.IndexedDB._rs_cleanup=function(remoteStorage){var pending=Promise.defer();return remoteStorage.local&&remoteStorage.local.closeDB(),RS.IndexedDB.clean(DEFAULT_DB_NAME,function(){pending.resolve()}),pending.promise}}("undefined"!=typeof window?window:global),function(global){function isRemoteStorageKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX||key.substr(0,CHANGES_PREFIX.length)===CHANGES_PREFIX}function isNodeKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX}var NODES_PREFIX="remotestorage:cache:nodes:",CHANGES_PREFIX="remotestorage:cache:changes:";RemoteStorage.LocalStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[LocalStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done")},RemoteStorage.LocalStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)try{nodes[paths[i]]=JSON.parse(localStorage[NODES_PREFIX+paths[i]])}catch(e){nodes[paths[i]]=void 0}return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)localStorage[NODES_PREFIX+path]=JSON.stringify(nodes[path]);return Promise.resolve()},forAllNodes:function(cb){for(var node,i=0,len=localStorage.length;len>i;i++)if(isNodeKey(localStorage.key(i))){try{node=this.migrate(JSON.parse(localStorage[localStorage.key(i)]))}catch(e){node=void 0}node&&cb(node)}return Promise.resolve()}},RemoteStorage.LocalStorage._rs_init=function(){},RemoteStorage.LocalStorage._rs_supported=function(){return RemoteStorage.util.localStorageAvailable()},RemoteStorage.LocalStorage._rs_cleanup=function(){for(var keys=[],i=0,len=localStorage.length;len>i;i++){var key=localStorage.key(i);isRemoteStorageKey(key)&&keys.push(key)}keys.forEach(function(key){RemoteStorage.log("[LocalStorage] Removing",key),delete localStorage[key]})}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.InMemoryStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[InMemoryStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done"),this._storage={}},RemoteStorage.InMemoryStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)nodes[paths[i]]=this._storage[paths[i]];return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)void 0===nodes[path]?delete this._storage[path]:this._storage[path]=nodes[path];return Promise.resolve()},forAllNodes:function(cb){for(var path in this._storage)cb(this.migrate(this._storage[path]));return Promise.resolve()}},RemoteStorage.InMemoryStorage._rs_init=function(){},RemoteStorage.InMemoryStorage._rs_supported=function(){return!0},RemoteStorage.InMemoryStorage._rs_cleanup=function(){}}("undefined"!=typeof window?window:global),function(){RemoteStorage.MODULES={},RemoteStorage.defineModule=function(moduleName,builder){if(RemoteStorage.MODULES[moduleName]=builder,Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",isFolder=RemoteStorage.util.isFolder,Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){return rs._emit("error",new RemoteStorage.SyncError(err)),Promise.reject(err)})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",isFolder=RemoteStorage.util.isFolder,getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?(self.online&&(self.online=!1,self.rs._emit("network-offline")),global.setTimeout(self._request(method,url,options),3210)):(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return; +rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){return this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),Promise.resolve(args)}.bind(this)).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response)}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):((200===resp.status||404===resp.status)&&(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file diff --git a/release/stable/remotestorage-nocache.amd.js b/release/stable/remotestorage-nocache.amd.js index 8567a6400..4ec23e6ae 100644 --- a/release/stable/remotestorage-nocache.amd.js +++ b/release/stable/remotestorage-nocache.amd.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.0, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ define([], function() { /** FILE: src/remotestorage.js **/ @@ -171,6 +171,18 @@ define([], function() { * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -180,8 +192,9 @@ define([], function() { RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -316,6 +329,20 @@ define([], function() { * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -368,7 +395,7 @@ define([], function() { this._emit('connecting'); var discoveryTimeout = setTimeout(function () { - this._emit('error', new RemoteStorage.DiscoveryError("No storage information found at that user address.")); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this), RemoteStorage.config.discoveryTimeout); RemoteStorage.Discover(userAddress).then(function (info) { @@ -400,7 +427,8 @@ define([], function() { } } }.bind(this), function(err) { - this._emit('error', new RemoteStorage.DiscoveryError("Failed to contact storage server.")); + clearTimeout(discoveryTimeout); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this)); }, @@ -1616,6 +1644,7 @@ define([], function() { * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -1627,7 +1656,8 @@ define([], function() { * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -1713,13 +1743,17 @@ define([], function() { body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -1755,11 +1789,16 @@ define([], function() { } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -2060,7 +2099,7 @@ define([], function() { webFinger.lookup(userAddress, function (err, response) { if (err) { - return pending.reject(err.message); + return pending.reject(err); } else if ((typeof response.idx.links.remotestorage !== 'object') || (typeof response.idx.links.remotestorage.length !== 'number') || (response.idx.links.remotestorage.length <= 0)) { @@ -2116,11 +2155,11 @@ define([], function() { /* global define */ /*! * webfinger.js - * version 2.3.2 + * version 2.4.2 * http://github.com/silverbucket/webfinger.js * * Developed and Maintained by: - * Nick Jennings 2012 - 2014 + * Nick Jennings 2012 - 2016 * * webfinger.js is released under the AGPL (see LICENSE). * @@ -2177,7 +2216,7 @@ if (typeof XMLHttpRequest === 'undefined') { return obj; } - // given a URL ensures it's HTTPS. + // given a URL ensures it's HTTPS. // returns false for null string or non-HTTPS URL. function isSecure(url) { if (typeof url !== 'string') { @@ -2214,56 +2253,64 @@ if (typeof XMLHttpRequest === 'undefined') { // make an http request and look for JRD response, fails if request fails // or response not json. - WebFinger.prototype.__fetchJRD = function (_url, errorHandler, sucessHandler) { + WebFinger.prototype.__fetchJRD = function (url, errorHandler, sucessHandler) { var self = this; - function __makeRequest(url) { - var xhr = new XMLHttpRequest(); - + + var xhr = new XMLHttpRequest(); + + function __processState() { + if (xhr.status === 200) { + if (self.__isValidJSON(xhr.responseText)) { + return sucessHandler(xhr.responseText); + } else { + return errorHandler(generateErrorObject({ + message: 'invalid json', + url: url, + status: xhr.status + })); + } + } else if (xhr.status === 404) { + return errorHandler(generateErrorObject({ + message: 'resource not found', + url: url, + status: xhr.status + })); + } else if ((xhr.status >= 301) && (xhr.status <= 302)) { + var location = xhr.getResponseHeader('Location'); + if (isSecure(location)) { + return __makeRequest(location); // follow redirect + } else { + return errorHandler(generateErrorObject({ + message: 'no redirect URL found', + url: url, + status: xhr.status + })); + } + } else { + return errorHandler(generateErrorObject({ + message: 'error during request', + url: url, + status: xhr.status + })); + } + } + + function __makeRequest() { xhr.onreadystatechange = function () { if (xhr.readyState === 4) { - if (xhr.status === 200) { - if (self.__isValidJSON(xhr.responseText)) { - return sucessHandler(xhr.responseText); - } else { - return errorHandler(generateErrorObject({ - message: 'invalid json', - url: url, - status: xhr.status - })); - } - } else if (xhr.status === 404) { - return errorHandler(generateErrorObject({ - message: 'endpoint unreachable', - url: url, - status: xhr.status - })); - } else if ((xhr.status >= 301) && (xhr.status <= 302)) { - var location = xhr.getResponseHeader('Location'); - if (isSecure(location)) { - return __makeRequest(location); // follow redirect - } else { - return errorHandler(generateErrorObject({ - message: 'no redirect URL found', - url: url, - status: xhr.status - })); - } - } else { - return errorHandler(generateErrorObject({ - message: 'error during request', - url: url, - status: xhr.status - })); - } + __processState(); } }; - + + xhr.onload = function (a, b) { + __processState(); + } xhr.open('GET', url, true); xhr.setRequestHeader('Accept', 'application/jrd+json, application/json'); xhr.send(); } - - return __makeRequest(_url); + + return __makeRequest(); }; WebFinger.prototype.__isValidJSON = function (str) { @@ -2282,16 +2329,15 @@ if (typeof XMLHttpRequest === 'undefined') { // processes JRD object as if it's a webfinger response object // looks for known properties and adds them to profile datat struct. - WebFinger.prototype.__processJRD = function (JRD, errorHandler, successHandler) { + WebFinger.prototype.__processJRD = function (URL, JRD, errorHandler, successHandler) { var parsedJRD = JSON.parse(JRD); if ((typeof parsedJRD !== 'object') || (typeof parsedJRD.links !== 'object')) { if (typeof parsedJRD.error !== 'undefined') { - return errorHandler(generateErrorObject({ message: parsedJRD.error })); + return errorHandler(generateErrorObject({ message: parsedJRD.error, request: URL })); } else { - return errorHandler(generateErrorObject({ message: 'unknown response from server' })); + return errorHandler(generateErrorObject({ message: 'unknown response from server', request: URL })); } - return false; } var links = parsedJRD.links; @@ -2339,20 +2385,29 @@ if (typeof XMLHttpRequest === 'undefined') { } var self = this; - var parts = address.replace(/ /g,'').split('@'); - var host = parts[1]; // host name for this useraddress + var host = ''; + if (address.indexOf('://') > -1) { + // other uri format + host = address.replace(/ /g,'').split('://')[1]; + } else { + // useraddress + host = address.replace(/ /g,'').split('@')[1]; + } var uri_index = 0; // track which URIS we've tried already var protocol = 'https'; // we use https by default - if (parts.length !== 2) { - return cb(generateErrorObject({ message: 'invalid user address ' + address + ' ( expected format: user@host.com )' })); - } else if (self.__isLocalhost(host)) { + if (self.__isLocalhost(host)) { protocol = 'http'; } function __buildURL() { + var uri = ''; + if (! address.split('://')[1]) { + // the URI has not been defined, default to acct + uri = 'acct:'; + } return protocol + '://' + host + '/.well-known/' + - URIS[uri_index] + '?resource=acct:' + address; + URIS[uri_index] + '?resource=' + uri + address; } // control flow for failures, what to do in various cases, etc. @@ -2374,12 +2429,13 @@ if (typeof XMLHttpRequest === 'undefined') { // (stored somewhere in control of the user) // 3. make a request to that url and get the json // 4. process it like a normal webfinger response - self.__fetchJRD(__buildURL(), cb, function (data) { // get link to users JRD - self.__processJRD(data, cb, function (result) { + var URL = __buildURL(); + self.__fetchJRD(URL, cb, function (data) { // get link to users JRD + self.__processJRD(URL, data, cb, function (result) { if ((typeof result.idx.links.webfist === 'object') && (typeof result.idx.links.webfist[0].href === 'string')) { self.__fetchJRD(result.idx.links.webfist[0].href, cb, function (JRD) { - self.__processJRD(JRD, cb, function (result) { + self.__processJRD(URL, JRD, cb, function (result) { return cb(null, cb); }); }); @@ -2393,8 +2449,9 @@ if (typeof XMLHttpRequest === 'undefined') { function __call() { // make request - self.__fetchJRD(__buildURL(), __fallbackChecks, function (JRD) { - self.__processJRD(JRD, cb, function (result) { cb(null, result); }); + var URL = __buildURL(); + self.__fetchJRD(URL, __fallbackChecks, function (JRD) { + self.__processJRD(URL, JRD, cb, function (result) { cb(null, result); }); }); } @@ -3134,10 +3191,10 @@ RemoteStorage.Assets = { return typeof(document) !== 'undefined'; }; - function stateSetter(widget, state) { + function stateSetter(widget, state, message) { RemoteStorage.log('[Widget] Producing stateSetter for', state); return function () { - RemoteStorage.log('[Widget] Setting state', state, arguments); + RemoteStorage.log('[Widget] Setting state', state, message); if (hasLocalStorage) { localStorage[LS_STATE_KEY] = state; } @@ -3145,7 +3202,7 @@ RemoteStorage.Assets = { if (widget.rs.remote) { widget.view.setUserAddress(widget.rs.remote.userAddress); } - widget.view.setState(state, arguments); + widget.view.setState(state, message); } else { widget._rememberedState = state; } @@ -3157,9 +3214,9 @@ RemoteStorage.Assets = { var s; if (error instanceof RemoteStorage.DiscoveryError) { console.error('Discovery failed', error, '"' + error.message + '"'); - s = stateSetter(widget, 'initial', [error.message]); + s = stateSetter(widget, 'initial', error.message); } else if (error instanceof RemoteStorage.SyncError) { - s = stateSetter(widget, 'offline', []); + s = stateSetter(widget, 'offline'); } else if (error instanceof RemoteStorage.Unauthorized) { s = stateSetter(widget, 'unauthorized'); } else { @@ -3250,13 +3307,13 @@ RemoteStorage.Assets = { * state * args **/ - setState: function (state, args) { - RemoteStorage.log('[View] widget.view.setState(',state,',',args,');'); + setState: function (state, message) { + RemoteStorage.log('[View] widget.view.setState(',state,',',message,');'); var s = this.states[state]; if (typeof(s) === 'undefined') { throw new Error("Bad State assigned to view: " + state); } - s.apply(this, args); + s.apply(this, [message]); }, /** @@ -6593,6 +6650,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -6958,15 +7017,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); } - return xhr; + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -7043,6 +7132,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -7611,15 +7702,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -7698,8 +7823,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -7847,7 +7972,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -7856,6 +7981,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -7866,7 +7992,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/stable/remotestorage-nocache.js b/release/stable/remotestorage-nocache.js index 5ecf7745e..1e52cf4ca 100644 --- a/release/stable/remotestorage-nocache.js +++ b/release/stable/remotestorage-nocache.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.0, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ /** FILE: lib/bluebird.js **/ /** @@ -3441,6 +3441,18 @@ module.exports = ret; * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -3450,8 +3462,9 @@ module.exports = ret; RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -3586,6 +3599,20 @@ module.exports = ret; * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -3638,7 +3665,7 @@ module.exports = ret; this._emit('connecting'); var discoveryTimeout = setTimeout(function () { - this._emit('error', new RemoteStorage.DiscoveryError("No storage information found at that user address.")); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this), RemoteStorage.config.discoveryTimeout); RemoteStorage.Discover(userAddress).then(function (info) { @@ -3670,7 +3697,8 @@ module.exports = ret; } } }.bind(this), function(err) { - this._emit('error', new RemoteStorage.DiscoveryError("Failed to contact storage server.")); + clearTimeout(discoveryTimeout); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this)); }, @@ -4886,6 +4914,7 @@ module.exports = ret; * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -4897,7 +4926,8 @@ module.exports = ret; * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -4983,13 +5013,17 @@ module.exports = ret; body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -5025,11 +5059,16 @@ module.exports = ret; } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -5330,7 +5369,7 @@ module.exports = ret; webFinger.lookup(userAddress, function (err, response) { if (err) { - return pending.reject(err.message); + return pending.reject(err); } else if ((typeof response.idx.links.remotestorage !== 'object') || (typeof response.idx.links.remotestorage.length !== 'number') || (response.idx.links.remotestorage.length <= 0)) { @@ -5386,11 +5425,11 @@ module.exports = ret; /* global define */ /*! * webfinger.js - * version 2.3.2 + * version 2.4.2 * http://github.com/silverbucket/webfinger.js * * Developed and Maintained by: - * Nick Jennings 2012 - 2014 + * Nick Jennings 2012 - 2016 * * webfinger.js is released under the AGPL (see LICENSE). * @@ -5447,7 +5486,7 @@ if (typeof XMLHttpRequest === 'undefined') { return obj; } - // given a URL ensures it's HTTPS. + // given a URL ensures it's HTTPS. // returns false for null string or non-HTTPS URL. function isSecure(url) { if (typeof url !== 'string') { @@ -5484,56 +5523,64 @@ if (typeof XMLHttpRequest === 'undefined') { // make an http request and look for JRD response, fails if request fails // or response not json. - WebFinger.prototype.__fetchJRD = function (_url, errorHandler, sucessHandler) { + WebFinger.prototype.__fetchJRD = function (url, errorHandler, sucessHandler) { var self = this; - function __makeRequest(url) { - var xhr = new XMLHttpRequest(); - + + var xhr = new XMLHttpRequest(); + + function __processState() { + if (xhr.status === 200) { + if (self.__isValidJSON(xhr.responseText)) { + return sucessHandler(xhr.responseText); + } else { + return errorHandler(generateErrorObject({ + message: 'invalid json', + url: url, + status: xhr.status + })); + } + } else if (xhr.status === 404) { + return errorHandler(generateErrorObject({ + message: 'resource not found', + url: url, + status: xhr.status + })); + } else if ((xhr.status >= 301) && (xhr.status <= 302)) { + var location = xhr.getResponseHeader('Location'); + if (isSecure(location)) { + return __makeRequest(location); // follow redirect + } else { + return errorHandler(generateErrorObject({ + message: 'no redirect URL found', + url: url, + status: xhr.status + })); + } + } else { + return errorHandler(generateErrorObject({ + message: 'error during request', + url: url, + status: xhr.status + })); + } + } + + function __makeRequest() { xhr.onreadystatechange = function () { if (xhr.readyState === 4) { - if (xhr.status === 200) { - if (self.__isValidJSON(xhr.responseText)) { - return sucessHandler(xhr.responseText); - } else { - return errorHandler(generateErrorObject({ - message: 'invalid json', - url: url, - status: xhr.status - })); - } - } else if (xhr.status === 404) { - return errorHandler(generateErrorObject({ - message: 'endpoint unreachable', - url: url, - status: xhr.status - })); - } else if ((xhr.status >= 301) && (xhr.status <= 302)) { - var location = xhr.getResponseHeader('Location'); - if (isSecure(location)) { - return __makeRequest(location); // follow redirect - } else { - return errorHandler(generateErrorObject({ - message: 'no redirect URL found', - url: url, - status: xhr.status - })); - } - } else { - return errorHandler(generateErrorObject({ - message: 'error during request', - url: url, - status: xhr.status - })); - } + __processState(); } }; - + + xhr.onload = function (a, b) { + __processState(); + } xhr.open('GET', url, true); xhr.setRequestHeader('Accept', 'application/jrd+json, application/json'); xhr.send(); } - - return __makeRequest(_url); + + return __makeRequest(); }; WebFinger.prototype.__isValidJSON = function (str) { @@ -5552,16 +5599,15 @@ if (typeof XMLHttpRequest === 'undefined') { // processes JRD object as if it's a webfinger response object // looks for known properties and adds them to profile datat struct. - WebFinger.prototype.__processJRD = function (JRD, errorHandler, successHandler) { + WebFinger.prototype.__processJRD = function (URL, JRD, errorHandler, successHandler) { var parsedJRD = JSON.parse(JRD); if ((typeof parsedJRD !== 'object') || (typeof parsedJRD.links !== 'object')) { if (typeof parsedJRD.error !== 'undefined') { - return errorHandler(generateErrorObject({ message: parsedJRD.error })); + return errorHandler(generateErrorObject({ message: parsedJRD.error, request: URL })); } else { - return errorHandler(generateErrorObject({ message: 'unknown response from server' })); + return errorHandler(generateErrorObject({ message: 'unknown response from server', request: URL })); } - return false; } var links = parsedJRD.links; @@ -5609,20 +5655,29 @@ if (typeof XMLHttpRequest === 'undefined') { } var self = this; - var parts = address.replace(/ /g,'').split('@'); - var host = parts[1]; // host name for this useraddress + var host = ''; + if (address.indexOf('://') > -1) { + // other uri format + host = address.replace(/ /g,'').split('://')[1]; + } else { + // useraddress + host = address.replace(/ /g,'').split('@')[1]; + } var uri_index = 0; // track which URIS we've tried already var protocol = 'https'; // we use https by default - if (parts.length !== 2) { - return cb(generateErrorObject({ message: 'invalid user address ' + address + ' ( expected format: user@host.com )' })); - } else if (self.__isLocalhost(host)) { + if (self.__isLocalhost(host)) { protocol = 'http'; } function __buildURL() { + var uri = ''; + if (! address.split('://')[1]) { + // the URI has not been defined, default to acct + uri = 'acct:'; + } return protocol + '://' + host + '/.well-known/' + - URIS[uri_index] + '?resource=acct:' + address; + URIS[uri_index] + '?resource=' + uri + address; } // control flow for failures, what to do in various cases, etc. @@ -5644,12 +5699,13 @@ if (typeof XMLHttpRequest === 'undefined') { // (stored somewhere in control of the user) // 3. make a request to that url and get the json // 4. process it like a normal webfinger response - self.__fetchJRD(__buildURL(), cb, function (data) { // get link to users JRD - self.__processJRD(data, cb, function (result) { + var URL = __buildURL(); + self.__fetchJRD(URL, cb, function (data) { // get link to users JRD + self.__processJRD(URL, data, cb, function (result) { if ((typeof result.idx.links.webfist === 'object') && (typeof result.idx.links.webfist[0].href === 'string')) { self.__fetchJRD(result.idx.links.webfist[0].href, cb, function (JRD) { - self.__processJRD(JRD, cb, function (result) { + self.__processJRD(URL, JRD, cb, function (result) { return cb(null, cb); }); }); @@ -5663,8 +5719,9 @@ if (typeof XMLHttpRequest === 'undefined') { function __call() { // make request - self.__fetchJRD(__buildURL(), __fallbackChecks, function (JRD) { - self.__processJRD(JRD, cb, function (result) { cb(null, result); }); + var URL = __buildURL(); + self.__fetchJRD(URL, __fallbackChecks, function (JRD) { + self.__processJRD(URL, JRD, cb, function (result) { cb(null, result); }); }); } @@ -6404,10 +6461,10 @@ RemoteStorage.Assets = { return typeof(document) !== 'undefined'; }; - function stateSetter(widget, state) { + function stateSetter(widget, state, message) { RemoteStorage.log('[Widget] Producing stateSetter for', state); return function () { - RemoteStorage.log('[Widget] Setting state', state, arguments); + RemoteStorage.log('[Widget] Setting state', state, message); if (hasLocalStorage) { localStorage[LS_STATE_KEY] = state; } @@ -6415,7 +6472,7 @@ RemoteStorage.Assets = { if (widget.rs.remote) { widget.view.setUserAddress(widget.rs.remote.userAddress); } - widget.view.setState(state, arguments); + widget.view.setState(state, message); } else { widget._rememberedState = state; } @@ -6427,9 +6484,9 @@ RemoteStorage.Assets = { var s; if (error instanceof RemoteStorage.DiscoveryError) { console.error('Discovery failed', error, '"' + error.message + '"'); - s = stateSetter(widget, 'initial', [error.message]); + s = stateSetter(widget, 'initial', error.message); } else if (error instanceof RemoteStorage.SyncError) { - s = stateSetter(widget, 'offline', []); + s = stateSetter(widget, 'offline'); } else if (error instanceof RemoteStorage.Unauthorized) { s = stateSetter(widget, 'unauthorized'); } else { @@ -6520,13 +6577,13 @@ RemoteStorage.Assets = { * state * args **/ - setState: function (state, args) { - RemoteStorage.log('[View] widget.view.setState(',state,',',args,');'); + setState: function (state, message) { + RemoteStorage.log('[View] widget.view.setState(',state,',',message,');'); var s = this.states[state]; if (typeof(s) === 'undefined') { throw new Error("Bad State assigned to view: " + state); } - s.apply(this, args); + s.apply(this, [message]); }, /** @@ -9863,6 +9920,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -10228,15 +10287,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); + } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); } - return xhr; + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -10313,6 +10402,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -10881,15 +10972,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -10968,8 +11093,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -11117,7 +11242,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -11126,6 +11251,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -11136,7 +11262,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/stable/remotestorage-nocache.min.js b/release/stable/remotestorage-nocache.min.js index 34a60c3bc..bc24de22b 100644 --- a/release/stable/remotestorage-nocache.min.js +++ b/release/stable/remotestorage-nocache.min.js @@ -1,8 +1,8 @@ -/** remotestorage.js 0.13.0, http://remotestorage.io, MIT-licensed **/ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o0},Async.prototype.invokeLater=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn)),this._lateBuffer.push(fn,receiver,arg),this._queueTick()},Async.prototype.invoke=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn));var functionBuffer=this._functionBuffer;functionBuffer.push(fn,receiver,arg),this._length=functionBuffer.length(),this._queueTick()},Async.prototype._consumeFunctionBuffer=function(){for(var functionBuffer=this._functionBuffer;functionBuffer.length()>0;){var fn=functionBuffer.shift(),receiver=functionBuffer.shift(),arg=functionBuffer.shift();fn.call(receiver,arg)}this._reset(),this._consumeLateBuffer()},Async.prototype._consumeLateBuffer=function(){for(var buffer=this._lateBuffer;buffer.length()>0;){var fn=buffer.shift(),receiver=buffer.shift(),arg=buffer.shift(),res=tryCatch1(fn,receiver,arg);if(res===errorObj){if(this._queueTick(),null==fn.domain)throw res.e;fn.domain.emit("error",res.e)}}},Async.prototype._queueTick=function(){this._isTickUsed||(this._schedule(this.consumeFunctionBuffer),this._isTickUsed=!0)},Async.prototype._reset=function(){this._isTickUsed=!1,this._length=0},module.exports=new Async},{"./queue.js":15,"./schedule.js":16,"./util.js":19}],2:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise.js")();module.exports=Promise},{"./promise.js":12}],3:[function(_dereq_,module,exports){"use strict";module.exports=function(){function formatNonError(obj){var str;if("function"==typeof obj)str="[function "+(obj.name||"anonymous")+"]";else{str=obj.toString();var ruselessToString=/\[object [a-zA-Z0-9$_]+\]/;if(ruselessToString.test(str))try{var newStr=JSON.stringify(obj);str=newStr}catch(e){}0===str.length&&(str="(empty array)")}return"(<"+snip(str)+">, no stack trace)"}function snip(str){var maxChars=41;return str.length=0;--i){var line=prev[i];if(current[curLast]!==line)break;current.pop(),curLast--}current.push("From previous event:");for(var lines=current.concat(prev),ret=[],i=0,len=lines.length;len>i;++i)rignore.test(lines[i])&&rtraceline.test(lines[i])||i>0&&!rtraceline.test(lines[i])&&"From previous event:"!==lines[i]||ret.push(lines[i]);return ret},CapturedTrace.protectErrorMessageNewlines=function(stack){for(var i=0;i=i)){for(var errorMessageLines=[],j=0;i>j;++j)errorMessageLines.push(stack.shift());stack.unshift(errorMessageLines.join("\x00"))}},CapturedTrace.isSupported=function(){return"function"==typeof captureStackTrace};var captureStackTrace=function stackDetection(){if("number"==typeof Error.stackTraceLimit&&"function"==typeof Error.captureStackTrace){rtraceline=/^\s*at\s*/,formatStack=function(stack,error){return"string"==typeof stack?stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)};var captureStackTrace=Error.captureStackTrace;return function(receiver,ignoreUntil){captureStackTrace(receiver,ignoreUntil)}}var err=new Error;if("string"==typeof err.stack&&"function"==typeof"".startsWith&&err.stack.startsWith("stackDetection@")&&"stackDetection"===stackDetection.name){defineProperty(Error,"stackTraceLimit",{writable:!0,enumerable:!1,configurable:!1,value:25}),rtraceline=/@/;var rline=/[@\n]/;return formatStack=function(stack,error){return"string"==typeof stack?error.name+". "+error.message+"\n"+stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)},function(o){for(var stack=(new Error).stack,split=stack.split(rline),len=split.length,ret="",i=0;len>i;i+=2)ret+=split[i],ret+="@",ret+=split[i+1],ret+="\n";o.stack=ret}}return formatStack=function(stack,error){return"string"==typeof stack?stack:"object"!=typeof error&&"function"!=typeof error||void 0===error.name||void 0===error.message?formatNonError(error):error.name+". "+error.message},null}();return CapturedTrace}},{"./es5.js":8,"./util.js":19}],4:[function(_dereq_,module,exports){"use strict";module.exports=function(NEXT_FILTER){function CatchFilter(instances,callback,promise){this._instances=instances,this._callback=callback,this._promise=promise}function CatchFilter$_safePredicate(predicate,e){var safeObject={},retfilter=tryCatch1(predicate,safeObject,e);if(retfilter===errorObj)return retfilter;var safeKeys=keys(safeObject);return safeKeys.length?(errorObj.e=new TypeError("Catch filter must inherit from Error or be a simple predicate function"),errorObj):retfilter}var util=_dereq_("./util.js"),errors=_dereq_("./errors.js"),tryCatch1=util.tryCatch1,errorObj=util.errorObj,keys=_dereq_("./es5.js").keys,TypeError=errors.TypeError;return CatchFilter.prototype.doFilter=function(e){for(var cb=this._callback,promise=this._promise,boundTo=promise._boundTo,i=0,len=this._instances.length;len>i;++i){var item=this._instances[i],itemIsErrorType=item===Error||null!=item&&item.prototype instanceof Error;if(itemIsErrorType&&e instanceof item){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}if("function"==typeof item&&!itemIsErrorType){var shouldHandle=CatchFilter$_safePredicate(item,e);if(shouldHandle===errorObj){var trace=errors.canAttach(errorObj.e)?errorObj.e:new Error(errorObj.e+"");this._promise._attachExtraTrace(trace),e=errorObj.e;break}if(shouldHandle){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}}}return NEXT_FILTER.e=e,NEXT_FILTER},CatchFilter}},{"./errors.js":6,"./es5.js":8,"./util.js":19}],5:[function(_dereq_,module,exports){"use strict";var util=_dereq_("./util.js"),isPrimitive=util.isPrimitive,wrapsPrimitiveReceiver=util.wrapsPrimitiveReceiver;module.exports=function(Promise){var returner=function(){return this},thrower=function(){throw this},wrapper=function(value,action){return 1===action?function(){throw value}:2===action?function(){return value}:void 0};Promise.prototype["return"]=Promise.prototype.thenReturn=function(value){return wrapsPrimitiveReceiver&&isPrimitive(value)?this._then(wrapper(value,2),void 0,void 0,void 0,void 0):this._then(returner,void 0,void 0,value,void 0)},Promise.prototype["throw"]=Promise.prototype.thenThrow=function(reason){return wrapsPrimitiveReceiver&&isPrimitive(reason)?this._then(wrapper(reason,1),void 0,void 0,void 0,void 0):this._then(thrower,void 0,void 0,reason,void 0)}}},{"./util.js":19}],6:[function(_dereq_,module,exports){"use strict";function markAsOriginatingFromRejection(e){try{notEnumerableProp(e,"isOperational",!0)}catch(ignore){}}function originatesFromRejection(e){return null==e?!1:e instanceof OperationalError||e.isOperational===!0}function isError(obj){return obj instanceof Error}function canAttach(obj){return isError(obj)}function subError(nameProperty,defaultMessage){function SubError(message){return this instanceof SubError?(this.message="string"==typeof message?message:defaultMessage,this.name=nameProperty,void(Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor))):new SubError(message)}return inherits(SubError,Error),SubError}function OperationalError(message){this.name="OperationalError",this.message=message,this.cause=message,this.isOperational=!0,message instanceof Error?(this.message=message.message,this.stack=message.stack):Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}var _TypeError,_RangeError,Objectfreeze=_dereq_("./es5.js").freeze,util=_dereq_("./util.js"),inherits=util.inherits,notEnumerableProp=util.notEnumerableProp,CancellationError=subError("CancellationError","cancellation error"),TimeoutError=subError("TimeoutError","timeout error"),AggregateError=subError("AggregateError","aggregate error");try{_TypeError=TypeError,_RangeError=RangeError}catch(e){_TypeError=subError("TypeError","type error"),_RangeError=subError("RangeError","range error")}for(var methods="join pop push shift unshift slice filter forEach some every map indexOf lastIndexOf reduce reduceRight sort reverse".split(" "),i=0;i=i;++i)values.push("holder.p"+i);return new Function("holder"," \n 'use strict'; \n var callback = holder.fn; \n return callback(values); \n ".replace(/values/g,values.join(", ")))},thenCallbacks=[],callers=[void 0],i=1;5>=i;++i)thenCallbacks.push(thenCallback(i)),callers.push(caller(i));var Holder=function(total,fn){this.p1=this.p2=this.p3=this.p4=this.p5=null,this.fn=fn,this.total=total,this.now=0};Holder.prototype.callers=callers,Holder.prototype.checkFulfillment=function(promise){var now=this.now;now++;var total=this.total;if(now>=total){var handler=this.callers[total],ret=tryCatch1(handler,void 0,this);ret===errorObj?promise._rejectUnchecked(ret.e):promise._tryFollow(ret)||promise._fulfillUnchecked(ret)}else this.now=now}}Promise.join=function(){var fn,last=arguments.length-1;if(last>0&&"function"==typeof arguments[last]&&(fn=arguments[last],6>last&&canEvaluate)){var ret=new Promise(INTERNAL);ret._setTrace(void 0);for(var holder=new Holder(last,fn),reject=ret._reject,callbacks=thenCallbacks,i=0;last>i;++i){var maybePromise=cast(arguments[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._then(callbacks[i],reject,void 0,ret,holder):maybePromise.isFulfilled()?callbacks[i].call(ret,maybePromise._settledValue,holder):(ret._reject(maybePromise._settledValue),maybePromise._unsetRejectionIsUnhandled()):callbacks[i].call(ret,maybePromise,holder)}return ret}for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];var ret=new PromiseArray(args).promise();return void 0!==fn?ret.spread(fn):ret}}},{"./util.js":19}],11:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function thrower(r){throw r}function Promise$_spreadAdapter(val,receiver){if(!util.isArray(val))return Promise$_successAdapter(val,receiver);var ret=util.tryCatchApply(this,[null].concat(val),receiver);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_successAdapter(val,receiver){var nodeback=this,ret=void 0===val?tryCatch1(nodeback,receiver,null):tryCatch2(nodeback,receiver,null,val);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_errorAdapter(reason,receiver){var nodeback=this,ret=tryCatch1(nodeback,receiver,reason);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),tryCatch2=util.tryCatch2,tryCatch1=util.tryCatch1,errorObj=util.errorObj;Promise.prototype.nodeify=function(nodeback,options){if("function"==typeof nodeback){var adapter=Promise$_successAdapter;void 0!==options&&Object(options).spread&&(adapter=Promise$_spreadAdapter),this._then(adapter,Promise$_errorAdapter,void 0,nodeback,this._boundTo)}return this}}},{"./async.js":1,"./util.js":19}],12:[function(_dereq_,module,exports){"use strict";function noConflict(bluebird){try{Promise===bluebird&&(Promise=old)}catch(e){}return bluebird}var old;"undefined"!=typeof Promise&&(old=Promise),module.exports=function(){function Promise(resolver){if("function"!=typeof resolver)throw new TypeError("the promise constructor requires a resolver function");if(this.constructor!==Promise)throw new TypeError("the promise constructor cannot be invoked directly");this._bitField=0,this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0,this._settledValue=void 0,this._boundTo=void 0,resolver!==INTERNAL&&this._resolveFromResolver(resolver)}function returnFirstElement(elements){return elements[0]}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),errors=_dereq_("./errors.js"),INTERNAL=function(){},APPLY={},NEXT_FILTER={e:null},cast=_dereq_("./thenables.js")(Promise,INTERNAL),PromiseArray=_dereq_("./promise_array.js")(Promise,INTERNAL,cast),CapturedTrace=_dereq_("./captured_trace.js")(),CatchFilter=_dereq_("./catch_filter.js")(NEXT_FILTER),PromiseResolver=_dereq_("./promise_resolver.js"),isArray=util.isArray,errorObj=util.errorObj,tryCatch1=util.tryCatch1,tryCatch2=util.tryCatch2,tryCatchApply=util.tryCatchApply,RangeError=errors.RangeError,TypeError=errors.TypeError,CancellationError=errors.CancellationError,TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,originatesFromRejection=errors.originatesFromRejection,markAsOriginatingFromRejection=errors.markAsOriginatingFromRejection,canAttach=errors.canAttach,thrower=util.thrower,apiRejection=_dereq_("./errors_api_rejection")(Promise),makeSelfResolutionError=function(){return new TypeError("circular promise resolution chain")};Promise.prototype.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(maybePromise instanceof Promise){var binder=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)}),p=Promise.all([this,binder]).then(returnFirstElement);ret._follow(p)}else ret._follow(this),ret._setBoundTo(thisArg);return ret._propagateFrom(this,3),ret},Promise.prototype.toString=function(){return"[object Promise]"},Promise.prototype.caught=Promise.prototype["catch"]=function(fn){var len=arguments.length;if(len>1){var i,catchInstances=new Array(len-1),j=0;for(i=0;len-1>i;++i){var item=arguments[i];if("function"!=typeof item){var catchFilterTypeError=new TypeError("A catch filter must be an error constructor or a filter function");return this._attachExtraTrace(catchFilterTypeError),Promise.reject(catchFilterTypeError)}catchInstances[j++]=item}catchInstances.length=j,fn=arguments[i],this._resetTrace();var catchFilter=new CatchFilter(catchInstances,fn,this);return this._then(void 0,catchFilter.doFilter,void 0,catchFilter,void 0)}return this._then(void 0,fn,void 0,void 0,void 0)},Promise.prototype.then=function(didFulfill,didReject,didProgress){return this._then(didFulfill,didReject,didProgress,void 0,void 0)},Promise.prototype.done=function(didFulfill,didReject,didProgress){var promise=this._then(didFulfill,didReject,didProgress,void 0,void 0);promise._setIsFinal()},Promise.prototype.spread=function(didFulfill,didReject){return this._then(didFulfill,didReject,void 0,APPLY,void 0)},Promise.prototype.isCancellable=function(){return!this.isResolved()&&this._cancellable()},Promise.prototype.toJSON=function(){var ret={isFulfilled:!1,isRejected:!1,fulfillmentValue:void 0,rejectionReason:void 0};return this.isFulfilled()?(ret.fulfillmentValue=this._settledValue,ret.isFulfilled=!0):this.isRejected()&&(ret.rejectionReason=this._settledValue,ret.isRejected=!0),ret},Promise.prototype.all=function(){return new PromiseArray(this).promise()},Promise.is=function(val){return val instanceof Promise},Promise.all=function(promises){return new PromiseArray(promises).promise()},Promise.prototype.error=function(fn){return this.caught(originatesFromRejection,fn)},Promise.prototype._resolveFromSyncValue=function(value){if(value===errorObj)this._cleanValues(),this._setRejected(),this._settledValue=value.e,this._ensurePossibleRejectionHandled();else{var maybePromise=cast(value,void 0);maybePromise instanceof Promise?this._follow(maybePromise):(this._cleanValues(),this._setFulfilled(),this._settledValue=value)}},Promise.method=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");return function(){var value;switch(arguments.length){case 0:value=tryCatch1(fn,this,void 0);break;case 1:value=tryCatch1(fn,this,arguments[0]);break;case 2:value=tryCatch2(fn,this,arguments[0],arguments[1]);break;default:for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];value=tryCatchApply(fn,args,this)}var ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret}},Promise.attempt=Promise["try"]=function(fn,args,ctx){if("function"!=typeof fn)return apiRejection("fn must be a function");var value=isArray(args)?tryCatchApply(fn,args,ctx):tryCatch1(fn,ctx,args),ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret},Promise.defer=Promise.pending=function(){var promise=new Promise(INTERNAL);return promise._setTrace(void 0),new PromiseResolver(promise)},Promise.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(ret._setTrace(void 0),maybePromise instanceof Promise){var p=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)});ret._follow(p)}else ret._setBoundTo(thisArg),ret._setFulfilled();return ret},Promise.cast=function(obj){var ret=cast(obj,void 0);if(!(ret instanceof Promise)){var val=ret;ret=new Promise(INTERNAL),ret._setTrace(void 0),ret._setFulfilled(),ret._cleanValues(),ret._settledValue=val}return ret},Promise.resolve=Promise.fulfilled=Promise.cast,Promise.reject=Promise.rejected=function(reason){var ret=new Promise(INTERNAL);if(ret._setTrace(void 0),markAsOriginatingFromRejection(reason),ret._cleanValues(),ret._setRejected(),ret._settledValue=reason,!canAttach(reason)){var trace=new Error(reason+"");ret._setCarriedStackTrace(trace)}return ret._ensurePossibleRejectionHandled(),ret},Promise.onPossiblyUnhandledRejection=function(fn){CapturedTrace.possiblyUnhandledRejection="function"==typeof fn?fn:void 0};var unhandledRejectionHandled;Promise.onUnhandledRejectionHandled=function(fn){unhandledRejectionHandled="function"==typeof fn?fn:void 0};var debugging=!("undefined"==typeof process||"string"!=typeof process.execPath||"object"!=typeof process.env||!process.env.BLUEBIRD_DEBUG&&"development"!==process.env.NODE_ENV);Promise.longStackTraces=function(){if(async.haveItemsQueued()&&debugging===!1)throw new Error("cannot enable long stack traces after promises have been created");debugging=CapturedTrace.isSupported()},Promise.hasLongStackTraces=function(){return debugging&&CapturedTrace.isSupported()},Promise.prototype._then=function(didFulfill,didReject,didProgress,receiver,internalData){var haveInternalData=void 0!==internalData,ret=haveInternalData?internalData:new Promise(INTERNAL);if(!haveInternalData){if(debugging){var haveSameContext=this._peekContext()===this._traceParent;ret._traceParent=haveSameContext?this._traceParent:this}ret._propagateFrom(this,7)}var callbackIndex=this._addCallbacks(didFulfill,didReject,didProgress,ret,receiver);return this.isResolved()&&async.invoke(this._queueSettleAt,this,callbackIndex),ret},Promise.prototype._length=function(){return 262143&this._bitField},Promise.prototype._isFollowingOrFulfilledOrRejected=function(){return(939524096&this._bitField)>0},Promise.prototype._isFollowing=function(){return 536870912===(536870912&this._bitField)},Promise.prototype._setLength=function(len){this._bitField=-262144&this._bitField|262143&len},Promise.prototype._setFulfilled=function(){this._bitField=268435456|this._bitField},Promise.prototype._setRejected=function(){this._bitField=134217728|this._bitField},Promise.prototype._setFollowing=function(){this._bitField=536870912|this._bitField},Promise.prototype._setIsFinal=function(){this._bitField=33554432|this._bitField},Promise.prototype._isFinal=function(){return(33554432&this._bitField)>0},Promise.prototype._cancellable=function(){return(67108864&this._bitField)>0},Promise.prototype._setCancellable=function(){this._bitField=67108864|this._bitField},Promise.prototype._unsetCancellable=function(){this._bitField=-67108865&this._bitField},Promise.prototype._setRejectionIsUnhandled=function(){this._bitField=2097152|this._bitField},Promise.prototype._unsetRejectionIsUnhandled=function(){this._bitField=-2097153&this._bitField,this._isUnhandledRejectionNotified()&&(this._unsetUnhandledRejectionIsNotified(),this._notifyUnhandledRejectionIsHandled())},Promise.prototype._isRejectionUnhandled=function(){return(2097152&this._bitField)>0},Promise.prototype._setUnhandledRejectionIsNotified=function(){this._bitField=524288|this._bitField},Promise.prototype._unsetUnhandledRejectionIsNotified=function(){this._bitField=-524289&this._bitField},Promise.prototype._isUnhandledRejectionNotified=function(){return(524288&this._bitField)>0},Promise.prototype._setCarriedStackTrace=function(capturedTrace){this._bitField=1048576|this._bitField,this._fulfillmentHandler0=capturedTrace},Promise.prototype._unsetCarriedStackTrace=function(){this._bitField=-1048577&this._bitField,this._fulfillmentHandler0=void 0},Promise.prototype._isCarryingStackTrace=function(){return(1048576&this._bitField)>0},Promise.prototype._getCarriedStackTrace=function(){return this._isCarryingStackTrace()?this._fulfillmentHandler0:void 0},Promise.prototype._receiverAt=function(index){var ret=0===index?this._receiver0:this[(index<<2)+index-5+4];return this._isBound()&&void 0===ret?this._boundTo:ret},Promise.prototype._promiseAt=function(index){return 0===index?this._promise0:this[(index<<2)+index-5+3]},Promise.prototype._fulfillmentHandlerAt=function(index){return 0===index?this._fulfillmentHandler0:this[(index<<2)+index-5+0]},Promise.prototype._rejectionHandlerAt=function(index){return 0===index?this._rejectionHandler0:this[(index<<2)+index-5+1]},Promise.prototype._addCallbacks=function(fulfill,reject,progress,promise,receiver){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promise,void 0!==receiver&&(this._receiver0=receiver),"function"!=typeof fulfill||this._isCarryingStackTrace()||(this._fulfillmentHandler0=fulfill),"function"==typeof reject&&(this._rejectionHandler0=reject),"function"==typeof progress&&(this._progressHandler0=progress);else{var base=(index<<2)+index-5;this[base+3]=promise,this[base+4]=receiver,this[base+0]="function"==typeof fulfill?fulfill:void 0,this[base+1]="function"==typeof reject?reject:void 0,this[base+2]="function"==typeof progress?progress:void 0}return this._setLength(index+1),index},Promise.prototype._setProxyHandlers=function(receiver,promiseSlotValue){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promiseSlotValue,this._receiver0=receiver;else{var base=(index<<2)+index-5;this[base+3]=promiseSlotValue,this[base+4]=receiver,this[base+0]=this[base+1]=this[base+2]=void 0}this._setLength(index+1)},Promise.prototype._proxyPromiseArray=function(promiseArray,index){this._setProxyHandlers(promiseArray,index)},Promise.prototype._proxyPromise=function(promise){promise._setProxied(),this._setProxyHandlers(promise,-15)},Promise.prototype._setBoundTo=function(obj){void 0!==obj?(this._bitField=8388608|this._bitField,this._boundTo=obj):this._bitField=-8388609&this._bitField},Promise.prototype._isBound=function(){return 8388608===(8388608&this._bitField)},Promise.prototype._resolveFromResolver=function(resolver){function Promise$_resolver(val){promise._tryFollow(val)||promise._fulfill(val)}function Promise$_rejecter(val){var trace=canAttach(val)?val:new Error(val+"");promise._attachExtraTrace(trace),markAsOriginatingFromRejection(val),promise._reject(val,trace===val?void 0:trace)}var promise=this;this._setTrace(void 0),this._pushContext();var r=tryCatch2(resolver,void 0,Promise$_resolver,Promise$_rejecter);if(this._popContext(),void 0!==r&&r===errorObj){var e=r.e,trace=canAttach(e)?e:new Error(e+"");promise._reject(e,trace)}},Promise.prototype._spreadSlowCase=function(targetFn,promise,values,boundTo){var promiseForAll=new PromiseArray(values).promise(),promise2=promiseForAll._then(function(){return targetFn.apply(boundTo,arguments)},void 0,void 0,APPLY,void 0);promise._follow(promise2)},Promise.prototype._callSpread=function(handler,promise,value){var boundTo=this._boundTo;if(isArray(value))for(var i=0,len=value.length;len>i;++i)if(cast(value[i],void 0)instanceof Promise)return void this._spreadSlowCase(handler,promise,value,boundTo);return promise._pushContext(),tryCatchApply(handler,value,boundTo)},Promise.prototype._callHandler=function(handler,receiver,promise,value){var x;return receiver!==APPLY||this.isRejected()?(promise._pushContext(),x=tryCatch1(handler,receiver,value)):x=this._callSpread(handler,promise,value),promise._popContext(),x},Promise.prototype._settlePromiseFromHandler=function(handler,receiver,value,promise){if(!(promise instanceof Promise))return void handler.call(receiver,value,promise);var x=this._callHandler(handler,receiver,promise,value);if(!promise._isFollowing())if(x===errorObj||x===promise||x===NEXT_FILTER){var err=x===promise?makeSelfResolutionError():x.e,trace=canAttach(err)?err:new Error(err+""); -x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string");RemoteStorage.config.cordovaRedirectUri=uri; -},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.connected=!1,RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),self.online=!0,isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err.message);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(_url,errorHandler,sucessHandler){function __makeRequest(url){var xhr=new XMLHttpRequest;xhr.onreadystatechange=function(){if(4===xhr.readyState){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"endpoint unreachable",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this;return __makeRequest(_url)},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error}):generateErrorObject({message:"unknown response from server"}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){return protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource=acct:"+address}function __fallbackChecks(err){return self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1?(uri_index+=1,__call()):self.config.tls_only||"https"!==protocol?self.config.webfist_fallback&&"webfist.org"!==host?(uri_index=0,protocol="http",host="webfist.org",self.__fetchJRD(__buildURL(),cb,function(data){self.__processJRD(data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(JRD,cb,function(result){return cb(null,cb)})})})}),void 0):cb(err):(uri_index=0,protocol="http",__call())}function __call(){self.__fetchJRD(__buildURL(),__fallbackChecks,function(JRD){self.__processJRD(JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,parts=address.replace(/ /g,"").split("@"),host=parts[1],uri_index=0,protocol="https";return 2!==parts.length?cb(generateErrorObject({message:"invalid user address "+address+" ( expected format: user@host.com )"})):(self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0))},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId),!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href, -storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' -},function(window){function stateSetter(widget,state){return RemoteStorage.log("[Widget] Producing stateSetter for",state),function(){RemoteStorage.log("[Widget] Setting state",state,arguments),hasLocalStorage&&(localStorage[LS_STATE_KEY]=state),widget.view?(widget.rs.remote&&widget.view.setUserAddress(widget.rs.remote.userAddress),widget.view.setState(state,arguments)):widget._rememberedState=state}}function errorsHandler(widget){return function(error){var s;error instanceof RemoteStorage.DiscoveryError?(console.error("Discovery failed",error,'"'+error.message+'"'),s=stateSetter(widget,"initial",[error.message])):error instanceof RemoteStorage.SyncError?s=stateSetter(widget,"offline",[]):error instanceof RemoteStorage.Unauthorized?s=stateSetter(widget,"unauthorized"):(RemoteStorage.log("[Widget] Unknown error"),s=stateSetter(widget,"error",[error])),s.apply()}}function flashFor(evt){return"GET"!==evt.method||!evt.isFolder}var hasLocalStorage,LS_STATE_KEY="remotestorage:widget:state",VALID_ENTRY_STATES={initial:!0,connected:!0,offline:!0};RemoteStorage.Widget=function(remoteStorage){var self=this,requestsToFlashFor=0;if(this.rs=remoteStorage,this.rs.remote.on("connected",stateSetter(this,"connected")),this.rs.on("disconnected",stateSetter(this,"initial")),this.rs.on("connecting",stateSetter(this,"authing")),this.rs.on("authing",stateSetter(this,"authing")),this.rs.on("error",errorsHandler(this)),this.rs.remote&&(this.rs.remote.on("wire-busy",function(evt){flashFor(evt)&&(requestsToFlashFor++,stateSetter(self,"busy")())}),this.rs.remote.on("wire-done",function(evt){flashFor(evt)&&requestsToFlashFor--,0>=requestsToFlashFor&&evt.success&&stateSetter(self,"connected")()})),hasLocalStorage){var state=localStorage[LS_STATE_KEY];state&&VALID_ENTRY_STATES[state]&&(this._rememberedState=state)}},RemoteStorage.Widget.prototype={display:function(options){return"string"==typeof options?options={domID:options}:"undefined"==typeof options&&(options={}),this.view||this.setView(new RemoteStorage.Widget.View(this.rs)),this.view.display(options),this},linkWidgetToSync:function(){"object"==typeof this.rs.sync&&"function"==typeof this.rs.sync.sync?this.view.on("sync",this.rs.sync.sync.bind(this.rs.sync)):(RemoteStorage.log("[Widget] typeof this.rs.sync check fail",this.rs.sync),setTimeout(this.linkWidgetToSync.bind(this),1e3))},setView:function(view){this.view=view,this.view.on("connect",function(options){"string"==typeof options?this.rs.connect(options):options.special&&this.rs[options.special].connect(options)}.bind(this)),this.view.on("secret-entered",function(secretKey){this.view.setUserSecretKey(secretKey),stateSetter(this,"ciphered")()}.bind(this)),this.view.on("secret-cancelled",function(){stateSetter(this,"notciphered")()}.bind(this)),this.view.on("disconnect",this.rs.disconnect.bind(this.rs)),this.linkWidgetToSync();try{this.view.on("reset",function(){var location=RemoteStorage.Authorize.getLocation();this.rs.on("disconnected",location.reload.bind(location)),this.rs.disconnect()}.bind(this))}catch(e){if(!e.message||!e.message.match(/Unknown event/))throw e}this._rememberedState&&(setTimeout(stateSetter(this,this._rememberedState),0),delete this._rememberedState)}},RemoteStorage.prototype.displayWidget=function(options){return this.widget.display(options)},RemoteStorage.Widget._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.widget||(remoteStorage.widget=new RemoteStorage.Widget(remoteStorage))},RemoteStorage.Widget._rs_supported=function(remoteStorage){return"undefined"!=typeof document}}("undefined"!=typeof window?window:global),function(window){function removeClass(el,className){return el.classList.remove(className)}function addClass(el,className){return el.classList.add(className)}function stopPropagation(event){"function"==typeof event.stopPropagation?event.stopPropagation():event.cancelBubble=!0}function setupButton(parent,className,iconName,eventListener){var element=parent.querySelector("."+className);if("undefined"!=typeof iconName){var img=element.querySelector("img");(img||element).src=RemoteStorage.Assets[iconName]}return element.addEventListener("click",eventListener),element}function handleButtonState(event){event.target.value?event.target.nextElementSibling.removeAttribute("disabled"):event.target.nextElementSibling.setAttribute("disabled","disabled")}var t=RemoteStorage.I18n.translate;RemoteStorage.Widget.View=function(remoteStorage){if(this.rs=remoteStorage,"undefined"==typeof document)throw"Widget not supported";RemoteStorage.eventHandling(this,"connect","secret-entered","secret-cancelled","disconnect","sync","display","reset");for(var event in this.events)this.events[event]=this.events[event].bind(this);this.hideBubbleOnBodyClick=function(event){for(var p=event.target;p!==document.body;p=p.parentElement)if("remotestorage-widget"===p.id)return;this.hideBubble()}.bind(this)},RemoteStorage.Widget.View.prototype={connectGdrive:function(){this._emit("connect",{special:"googledrive"})},connectDropbox:function(){this._emit("connect",{special:"dropbox"})},setState:function(state,args){RemoteStorage.log("[View] widget.view.setState(",state,",",args,");");var s=this.states[state];if("undefined"==typeof s)throw new Error("Bad State assigned to view: "+state);s.apply(this,args)},setUserAddress:function(addr){this.userAddress=addr||"";var el;this.div&&(el=this.div.querySelector("form.remotestorage-initial").userAddress)&&(el.value=this.userAddress)},setUserSecretKey:function(secretKey){this.userSecretKey=secretKey},toggleBubble:function(event){this.bubble.className.search("rs-hidden")<0?this.hideBubble(event):this.showBubble(event)},hideBubble:function(){addClass(this.bubble,"rs-hidden"),document.body.removeEventListener("click",this.hideBubbleOnBodyClick)},showBubble:function(event){removeClass(this.bubble,"rs-hidden"),"undefined"!=typeof event&&stopPropagation(event),document.body.addEventListener("click",this.hideBubbleOnBodyClick),this.div.querySelector(".remotestorage-connected").classList.contains("remotestorage-cipher")&&!this.userSecretKey?this.bubble.querySelector("form.remotestorage-cipher-form").userSecretKey.focus():this.bubble.querySelector("form.remotestorage-initial").userAddress.focus()},display:function(options){if("undefined"!=typeof this.div)return this.div;var element=document.createElement("div"),style=document.createElement("style");if(style.innerHTML=RemoteStorage.Assets.widgetCss,element.id="remotestorage-widget",element.innerHTML=RemoteStorage.Assets.widget,element.appendChild(style),options.domID){var parent=document.getElementById(options.domID);if(!parent)throw'Failed to find target DOM element with id="'+options.domID+'"';parent.appendChild(element)}else document.body.appendChild(element);setupButton(element,"rs-sync","syncIcon",this.events.sync),setupButton(element,"rs-disconnect","disconnectIcon",this.events.disconnect),setupButton(element,"remotestorage-reset",void 0,this.events.reset);setupButton(element,"connect","connectIcon",this.events.connect);this.form=element.querySelector("form.remotestorage-initial");var el=this.form.userAddress;if(el.addEventListener("load",handleButtonState),el.addEventListener("keyup",handleButtonState),this.userAddress&&(el.value=this.userAddress),options.encryption){this.cipher=!0;var secretKeyInput=element.querySelector("form.remotestorage-cipher-form").userSecretKey;secretKeyInput.type="password";setupButton(element,"rs-cipher","cipherIcon",this.events["secret-entered"]);secretKeyInput.addEventListener("load",handleButtonState),secretKeyInput.addEventListener("keyup",handleButtonState),setupButton(element,"rs-nocipher","nocipherIcon",this.events["secret-cancelled"])}this.cube=setupButton(element,"rs-cube","remoteStorageIcon",this.toggleBubble.bind(this)),setupButton(element,"rs-dropbox","dropbox",this.connectDropbox.bind(this)),setupButton(element,"rs-googledrive","googledrive",this.connectGdrive.bind(this));var bubbleDontCatch={INPUT:!0,BUTTON:!0,IMG:!0},eventListener=function(event){bubbleDontCatch[event.target.tagName]||this.div.classList.contains("remotestorage-state-unauthorized")||this.showBubble(event)}.bind(this);return this.bubble=setupButton(element,"rs-bubble",void 0,eventListener),this.hideBubble(),this.div=element,this.states.initial.call(this),this.events.display.call(this),this.div},states:{initial:function(message){var cube=this.cube,info=message||t("view_info");cube.src=RemoteStorage.Assets.remoteStorageIcon,this._renderTranslatedInitialContent(),message?(cube.src=RemoteStorage.Assets.remoteStorageIconError,removeClass(this.cube,"remotestorage-loading"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},2e3)):this.hideBubble(),this.div.className="remotestorage-state-initial",this.userSecretKey&&delete this.userSecretKey;var backends=1;this._activateBackend("dropbox")&&(backends+=1),this._activateBackend("googledrive")&&(backends+=1),this.div.querySelector(".rs-bubble-text").style.paddingRight=32*backends+8+"px";var cb=this.div.querySelector(".connect");this.form.userAddress.value&&cb.removeAttribute("disabled");var infoEl=this.div.querySelector(".rs-info-msg");infoEl.innerHTML=info,message?infoEl.classList.add("remotestorage-error-info"):infoEl.classList.remove("remotestorage-error-info")},authing:function(){this.div.removeEventListener("click",this.events.connect),this.div.className="remotestorage-state-authing",this.div.querySelector(".rs-status-text").innerHTML=t("view_connecting",this.userAddress),addClass(this.cube,"remotestorage-loading")},connected:function(){var cube=this.cube;this.div.className="remotestorage-state-connected",this.div.querySelector(".userAddress").innerHTML=this.userAddress,cube.src=RemoteStorage.Assets.remoteStorageIcon,removeClass(cube,"remotestorage-loading"),this.cipher&&(this.userSecretKey?this.userSecretKeyError?(cube.src=RemoteStorage.Assets.remoteStorageIconError,addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),addClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},5e3)):(removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),cube.src=RemoteStorage.Assets.remoteStorageIconCiphered):(addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.showBubble()));var icons={googledrive:this.div.querySelector(".rs-googledrive"),dropbox:this.div.querySelector(".rs-dropbox")};icons.googledrive.style.display=icons.dropbox.style.display="none",icons[this.rs.backend]?(icons[this.rs.backend].style.display="inline-block",this.div.querySelector(".rs-bubble-text").style.paddingRight="72px"):this.div.querySelector(".rs-bubble-text").style.paddingRight="40px"},ciphered:function(){this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value="",removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.cube.src=RemoteStorage.Assets.remoteStorageIconCiphered,this.hideBubble()},notciphered:function(){this.cipher=!1,removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.hideBubble()},busy:function(){this.div.className="remotestorage-state-busy",addClass(this.cube,"remotestorage-loading")},offline:function(){this.div.className="remotestorage-state-offline",this.cube.src=RemoteStorage.Assets.remoteStorageIconOffline,this.div.querySelector(".rs-status-text").innerHTML=t("view_offline")},error:function(err){var errorMsg=err;this.div.className="remotestorage-state-error",this.div.querySelector(".rs-bubble-text").innerHTML=""+t("view_error_occured")+"",err instanceof Error&&(errorMsg=err.message+"\n\n"+err.stack),this.div.querySelector(".rs-error-msg").textContent=errorMsg,this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble()},unauthorized:function(){this.div.className="remotestorage-state-unauthorized",this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble(),this.div.addEventListener("click",this.events.connect)}},events:{connect:function(event){stopPropagation(event),event.preventDefault(),this._emit("connect",this.div.querySelector("form.remotestorage-initial").userAddress.value)},"secret-entered":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-entered",this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value)},"secret-cancelled":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-cancelled")},sync:function(event){stopPropagation(event),event.preventDefault(),this._emit("sync")},disconnect:function(event){stopPropagation(event),event.preventDefault(),this._emit("disconnect")},reset:function(event){event.preventDefault();var result=window.confirm(t("view_confirm_reset"));result&&this._emit("reset")},display:function(event){event&&event.preventDefault(),this._emit("display")}},_renderTranslatedInitialContent:function(){this.div.querySelector(".rs-status-text").innerHTML=t("view_connect"),this.div.querySelector(".remotestorage-reset").innerHTML=t("view_get_me_out"),this.div.querySelector(".rs-error-plz-report").innerHTML=t("view_error_plz_report"),this.div.querySelector(".remotestorage-unauthorized").innerHTML=t("view_unauthorized"),this.div.querySelector(".remotestorage-invalid-key").innerHTML=t("view_invalid_key")},_activateBackend:function(backendName){var className="rs-"+backendName;return this.rs.apiKeys[backendName]?(this.div.querySelector("."+className).style.display="inline-block",!0):(this.div.querySelector("."+className).style.display="none",!1)}}}("undefined"!=typeof window?window:global),function(global,factory){"function"==typeof define&&define.amd?define([],factory):"undefined"!=typeof module&&module.exports?module.exports=factory():global.tv4=factory()}(this,function(){function notReallyPercentEncode(string){return encodeURI(string).replace(/%25[0-9][0-9]/g,function(doubleEncoded){return"%"+doubleEncoded.substring(3)})}function uriTemplateSubstitution(spec){var modifier="";uriTemplateGlobalModifiers[spec.charAt(0)]&&(modifier=spec.charAt(0),spec=spec.substring(1));var separator="",prefix="",shouldEscape=!0,showVariables=!1,trimEmptyString=!1;"+"===modifier?shouldEscape=!1:"."===modifier?(prefix=".",separator="."):"/"===modifier?(prefix="/",separator="/"):"#"===modifier?(prefix="#",shouldEscape=!1):";"===modifier?(prefix=";",separator=";",showVariables=!0,trimEmptyString=!0):"?"===modifier?(prefix="?",separator="&",showVariables=!0):"&"===modifier&&(prefix="&",separator="&",showVariables=!0);for(var varNames=[],varList=spec.split(","),varSpecs=[],varSpecMap={},i=0;i0&&(result+=varSpec.suffices["*"]?separator||",":",",varSpec.suffices["*"]&&showVariables&&(result+=varSpec.name+"=")),result+=shouldEscape?encodeURIComponent(value[j]).replace(/!/g,"%21"):notReallyPercentEncode(value[j])}else if("object"==typeof value){showVariables&&!varSpec.suffices["*"]&&(result+=varSpec.name+"=");var first=!0;for(var key in value)first||(result+=varSpec.suffices["*"]?separator||",":","),first=!1,result+=shouldEscape?encodeURIComponent(key).replace(/!/g,"%21"):notReallyPercentEncode(key),result+=varSpec.suffices["*"]?"=":",",result+=shouldEscape?encodeURIComponent(value[key]).replace(/!/g,"%21"):notReallyPercentEncode(value[key])}else showVariables&&(result+=varSpec.name,trimEmptyString&&""===value||(result+="=")),null!=varSpec.truncate&&(value=value.substring(0,varSpec.truncate)),result+=shouldEscape?encodeURIComponent(value).replace(/!/g,"%21"):notReallyPercentEncode(value)}return result};return subFunction.varNames=varNames,{prefix:prefix,substitution:subFunction}}function UriTemplate(template){if(!(this instanceof UriTemplate))return new UriTemplate(template);for(var parts=template.split("{"),textParts=[parts.shift()],prefixes=[],substitutions=[],varNames=[];parts.length>0;){var part=parts.shift(),spec=part.split("}")[0],remainder=part.substring(spec.length+1),funcs=uriTemplateSubstitution(spec);substitutions.push(funcs.substitution),prefixes.push(funcs.prefix),textParts.push(remainder),varNames=varNames.concat(funcs.substitution.varNames)}this.fill=function(valueFunction){for(var result=textParts[0],i=0;i0&&"/"===testUrl.charAt(baseUrl.length-1)||"#"===remainder.charAt(0)||"?"===remainder.charAt(0))return!0}return!1}function createApi(language){var currentLanguage,customErrorReporter,globalContext=new ValidatorContext,api={setErrorReporter:function(reporter){return"string"==typeof reporter?this.language(reporter):(customErrorReporter=reporter,!0)},addFormat:function(){globalContext.addFormat.apply(globalContext,arguments)},language:function(code){return code?(languages[code]||(code=code.split("-")[0]),languages[code]?(currentLanguage=code,code):!1):currentLanguage},addLanguage:function(code,messageMap){var key;for(key in ErrorCodes)messageMap[key]&&!messageMap[ErrorCodes[key]]&&(messageMap[ErrorCodes[key]]=messageMap[key]);var rootCode=code.split("-")[0];if(languages[rootCode]){languages[code]=Object.create(languages[rootCode]);for(key in messageMap)"undefined"==typeof languages[rootCode][key]&&(languages[rootCode][key]=messageMap[key]),languages[code][key]=messageMap[key]}else languages[code]=messageMap,languages[rootCode]=messageMap;return this},freshApi:function(language){var result=createApi();return language&&result.language(language),result},validate:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!1,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema);var error=context.validateAll(data,schema,null,null,"");return!error&&banUnknownProperties&&(error=context.banUnknownProperties(data,schema)),this.error=error,this.missing=context.missing,this.valid=null===error,this.valid},validateResult:function(){var result={};return this.validate.apply(result,arguments),result},validateMultiple:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!0,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema),context.validateAll(data,schema,null,null,""),banUnknownProperties&&context.banUnknownProperties(data,schema);var result={};return result.errors=context.errors,result.missing=context.missing,result.valid=0===result.errors.length,result},addSchema:function(){return globalContext.addSchema.apply(globalContext,arguments)},getSchema:function(){return globalContext.getSchema.apply(globalContext,arguments)},getSchemaMap:function(){return globalContext.getSchemaMap.apply(globalContext,arguments)},getSchemaUris:function(){return globalContext.getSchemaUris.apply(globalContext,arguments)},getMissingUris:function(){return globalContext.getMissingUris.apply(globalContext,arguments)},dropSchemas:function(){globalContext.dropSchemas.apply(globalContext,arguments)},defineKeyword:function(){globalContext.defineKeyword.apply(globalContext,arguments)},defineError:function(codeName,codeNumber,defaultMessage){if("string"!=typeof codeName||!/^[A-Z]+(_[A-Z]+)*$/.test(codeName))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof codeNumber||codeNumber%1!==0||1e4>codeNumber)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof ErrorCodes[codeName])throw new Error("Error already defined: "+codeName+" as "+ErrorCodes[codeName]);if("undefined"!=typeof ErrorCodeLookup[codeNumber])throw new Error("Error code already used: "+ErrorCodeLookup[codeNumber]+" as "+codeNumber);ErrorCodes[codeName]=codeNumber,ErrorCodeLookup[codeNumber]=codeName,ErrorMessagesDefault[codeName]=ErrorMessagesDefault[codeNumber]=defaultMessage;for(var langCode in languages){var language=languages[langCode];language[codeName]&&(language[codeNumber]=language[codeNumber]||language[codeName])}},reset:function(){globalContext.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:normSchema,resolveUrl:resolveUrl,getDocumentUri:getDocumentUri,errorCodes:ErrorCodes};return api.language(language||"en"),api}Object.keys||(Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if("object"!=typeof obj&&"function"!=typeof obj||null===obj)throw new TypeError("Object.keys called on non-object");var result=[];for(var prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(var i=0;dontEnumsLength>i;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result}}()),Object.create||(Object.create=function(){function F(){}return function(o){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Array.isArray||(Array.isArray=function(vArg){return"[object Array]"===Object.prototype.toString.call(vArg)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(searchElement){if(null===this)throw new TypeError;var t=Object(this),len=t.length>>>0;if(0===len)return-1;var n=0;if(arguments.length>1&&(n=Number(arguments[1]),n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=len)return-1;for(var k=n>=0?n:Math.max(len-Math.abs(n),0);len>k;k++)if(k in t&&t[k]===searchElement)return k;return-1}),Object.isFrozen||(Object.isFrozen=function(obj){for(var key="tv4_test_frozen_key";obj.hasOwnProperty(key);)key+=Math.random();try{return obj[key]=!0,delete obj[key],!1}catch(e){return!0}});var uriTemplateGlobalModifiers={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},uriTemplateSuffices={"*":!0};UriTemplate.prototype={toString:function(){return this.template},fillFromObject:function(obj){return this.fill(function(varName){return obj[varName]})}};var ValidatorContext=function(parent,collectMultiple,errorReporter,checkRecursive,trackUnknownProperties){if(this.missing=[],this.missingMap={},this.formatValidators=parent?Object.create(parent.formatValidators):{},this.schemas=parent?Object.create(parent.schemas):{},this.collectMultiple=collectMultiple,this.errors=[],this.handleError=collectMultiple?this.collectError:this.returnError,checkRecursive&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),trackUnknownProperties&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=errorReporter||defaultErrorReporter("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},parent)for(var key in parent.definedKeywords)this.definedKeywords[key]=parent.definedKeywords[key].slice(0)};ValidatorContext.prototype.defineKeyword=function(keyword,keywordFunction){this.definedKeywords[keyword]=this.definedKeywords[keyword]||[],this.definedKeywords[keyword].push(keywordFunction)},ValidatorContext.prototype.createError=function(code,messageParams,dataPath,schemaPath,subErrors,data,schema){var error=new ValidationError(code,messageParams,dataPath,schemaPath,subErrors);return error.message=this.errorReporter(error,data,schema),error},ValidatorContext.prototype.returnError=function(error){return error},ValidatorContext.prototype.collectError=function(error){return error&&this.errors.push(error),null},ValidatorContext.prototype.prefixErrors=function(startIndex,dataPath,schemaPath){for(var i=startIndex;i0},Async.prototype.invokeLater=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn)),this._lateBuffer.push(fn,receiver,arg),this._queueTick()},Async.prototype.invoke=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn));var functionBuffer=this._functionBuffer;functionBuffer.push(fn,receiver,arg),this._length=functionBuffer.length(),this._queueTick()},Async.prototype._consumeFunctionBuffer=function(){for(var functionBuffer=this._functionBuffer;functionBuffer.length()>0;){var fn=functionBuffer.shift(),receiver=functionBuffer.shift(),arg=functionBuffer.shift();fn.call(receiver,arg)}this._reset(),this._consumeLateBuffer()},Async.prototype._consumeLateBuffer=function(){for(var buffer=this._lateBuffer;buffer.length()>0;){var fn=buffer.shift(),receiver=buffer.shift(),arg=buffer.shift(),res=tryCatch1(fn,receiver,arg);if(res===errorObj){if(this._queueTick(),null==fn.domain)throw res.e;fn.domain.emit("error",res.e)}}},Async.prototype._queueTick=function(){this._isTickUsed||(this._schedule(this.consumeFunctionBuffer),this._isTickUsed=!0)},Async.prototype._reset=function(){this._isTickUsed=!1,this._length=0},module.exports=new Async},{"./queue.js":15,"./schedule.js":16,"./util.js":19}],2:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise.js")();module.exports=Promise},{"./promise.js":12}],3:[function(_dereq_,module,exports){"use strict";module.exports=function(){function formatNonError(obj){var str;if("function"==typeof obj)str="[function "+(obj.name||"anonymous")+"]";else{str=obj.toString();var ruselessToString=/\[object [a-zA-Z0-9$_]+\]/;if(ruselessToString.test(str))try{var newStr=JSON.stringify(obj);str=newStr}catch(e){}0===str.length&&(str="(empty array)")}return"(<"+snip(str)+">, no stack trace)"}function snip(str){var maxChars=41;return str.length=0;--i){var line=prev[i];if(current[curLast]!==line)break;current.pop(),curLast--}current.push("From previous event:");for(var lines=current.concat(prev),ret=[],i=0,len=lines.length;len>i;++i)rignore.test(lines[i])&&rtraceline.test(lines[i])||i>0&&!rtraceline.test(lines[i])&&"From previous event:"!==lines[i]||ret.push(lines[i]);return ret},CapturedTrace.protectErrorMessageNewlines=function(stack){for(var i=0;i=i)){for(var errorMessageLines=[],j=0;i>j;++j)errorMessageLines.push(stack.shift());stack.unshift(errorMessageLines.join("\x00"))}},CapturedTrace.isSupported=function(){return"function"==typeof captureStackTrace};var captureStackTrace=function stackDetection(){if("number"==typeof Error.stackTraceLimit&&"function"==typeof Error.captureStackTrace){rtraceline=/^\s*at\s*/,formatStack=function(stack,error){return"string"==typeof stack?stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)};var captureStackTrace=Error.captureStackTrace;return function(receiver,ignoreUntil){captureStackTrace(receiver,ignoreUntil)}}var err=new Error;if("string"==typeof err.stack&&"function"==typeof"".startsWith&&err.stack.startsWith("stackDetection@")&&"stackDetection"===stackDetection.name){defineProperty(Error,"stackTraceLimit",{writable:!0,enumerable:!1,configurable:!1,value:25}),rtraceline=/@/;var rline=/[@\n]/;return formatStack=function(stack,error){return"string"==typeof stack?error.name+". "+error.message+"\n"+stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)},function(o){for(var stack=(new Error).stack,split=stack.split(rline),len=split.length,ret="",i=0;len>i;i+=2)ret+=split[i],ret+="@",ret+=split[i+1],ret+="\n";o.stack=ret}}return formatStack=function(stack,error){return"string"==typeof stack?stack:"object"!=typeof error&&"function"!=typeof error||void 0===error.name||void 0===error.message?formatNonError(error):error.name+". "+error.message},null}();return CapturedTrace}},{"./es5.js":8,"./util.js":19}],4:[function(_dereq_,module,exports){"use strict";module.exports=function(NEXT_FILTER){function CatchFilter(instances,callback,promise){this._instances=instances,this._callback=callback,this._promise=promise}function CatchFilter$_safePredicate(predicate,e){var safeObject={},retfilter=tryCatch1(predicate,safeObject,e);if(retfilter===errorObj)return retfilter;var safeKeys=keys(safeObject);return safeKeys.length?(errorObj.e=new TypeError("Catch filter must inherit from Error or be a simple predicate function"),errorObj):retfilter}var util=_dereq_("./util.js"),errors=_dereq_("./errors.js"),tryCatch1=util.tryCatch1,errorObj=util.errorObj,keys=_dereq_("./es5.js").keys,TypeError=errors.TypeError;return CatchFilter.prototype.doFilter=function(e){for(var cb=this._callback,promise=this._promise,boundTo=promise._boundTo,i=0,len=this._instances.length;len>i;++i){var item=this._instances[i],itemIsErrorType=item===Error||null!=item&&item.prototype instanceof Error;if(itemIsErrorType&&e instanceof item){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}if("function"==typeof item&&!itemIsErrorType){var shouldHandle=CatchFilter$_safePredicate(item,e);if(shouldHandle===errorObj){var trace=errors.canAttach(errorObj.e)?errorObj.e:new Error(errorObj.e+"");this._promise._attachExtraTrace(trace),e=errorObj.e;break}if(shouldHandle){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}}}return NEXT_FILTER.e=e,NEXT_FILTER},CatchFilter}},{"./errors.js":6,"./es5.js":8,"./util.js":19}],5:[function(_dereq_,module,exports){"use strict";var util=_dereq_("./util.js"),isPrimitive=util.isPrimitive,wrapsPrimitiveReceiver=util.wrapsPrimitiveReceiver;module.exports=function(Promise){var returner=function(){return this},thrower=function(){throw this},wrapper=function(value,action){return 1===action?function(){throw value}:2===action?function(){return value}:void 0};Promise.prototype["return"]=Promise.prototype.thenReturn=function(value){return wrapsPrimitiveReceiver&&isPrimitive(value)?this._then(wrapper(value,2),void 0,void 0,void 0,void 0):this._then(returner,void 0,void 0,value,void 0)},Promise.prototype["throw"]=Promise.prototype.thenThrow=function(reason){return wrapsPrimitiveReceiver&&isPrimitive(reason)?this._then(wrapper(reason,1),void 0,void 0,void 0,void 0):this._then(thrower,void 0,void 0,reason,void 0)}}},{"./util.js":19}],6:[function(_dereq_,module,exports){"use strict";function markAsOriginatingFromRejection(e){try{notEnumerableProp(e,"isOperational",!0)}catch(ignore){}}function originatesFromRejection(e){return null==e?!1:e instanceof OperationalError||e.isOperational===!0}function isError(obj){return obj instanceof Error}function canAttach(obj){return isError(obj)}function subError(nameProperty,defaultMessage){function SubError(message){return this instanceof SubError?(this.message="string"==typeof message?message:defaultMessage,this.name=nameProperty,void(Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor))):new SubError(message)}return inherits(SubError,Error),SubError}function OperationalError(message){this.name="OperationalError",this.message=message,this.cause=message,this.isOperational=!0,message instanceof Error?(this.message=message.message,this.stack=message.stack):Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}var _TypeError,_RangeError,Objectfreeze=_dereq_("./es5.js").freeze,util=_dereq_("./util.js"),inherits=util.inherits,notEnumerableProp=util.notEnumerableProp,CancellationError=subError("CancellationError","cancellation error"),TimeoutError=subError("TimeoutError","timeout error"),AggregateError=subError("AggregateError","aggregate error");try{_TypeError=TypeError,_RangeError=RangeError}catch(e){_TypeError=subError("TypeError","type error"),_RangeError=subError("RangeError","range error")}for(var methods="join pop push shift unshift slice filter forEach some every map indexOf lastIndexOf reduce reduceRight sort reverse".split(" "),i=0;i=i;++i)values.push("holder.p"+i);return new Function("holder"," \n 'use strict'; \n var callback = holder.fn; \n return callback(values); \n ".replace(/values/g,values.join(", ")))},thenCallbacks=[],callers=[void 0],i=1;5>=i;++i)thenCallbacks.push(thenCallback(i)),callers.push(caller(i));var Holder=function(total,fn){this.p1=this.p2=this.p3=this.p4=this.p5=null,this.fn=fn,this.total=total,this.now=0};Holder.prototype.callers=callers,Holder.prototype.checkFulfillment=function(promise){var now=this.now;now++;var total=this.total;if(now>=total){var handler=this.callers[total],ret=tryCatch1(handler,void 0,this);ret===errorObj?promise._rejectUnchecked(ret.e):promise._tryFollow(ret)||promise._fulfillUnchecked(ret)}else this.now=now}}Promise.join=function(){var fn,last=arguments.length-1;if(last>0&&"function"==typeof arguments[last]&&(fn=arguments[last],6>last&&canEvaluate)){var ret=new Promise(INTERNAL);ret._setTrace(void 0);for(var holder=new Holder(last,fn),reject=ret._reject,callbacks=thenCallbacks,i=0;last>i;++i){var maybePromise=cast(arguments[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._then(callbacks[i],reject,void 0,ret,holder):maybePromise.isFulfilled()?callbacks[i].call(ret,maybePromise._settledValue,holder):(ret._reject(maybePromise._settledValue),maybePromise._unsetRejectionIsUnhandled()):callbacks[i].call(ret,maybePromise,holder)}return ret}for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];var ret=new PromiseArray(args).promise();return void 0!==fn?ret.spread(fn):ret}}},{"./util.js":19}],11:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function thrower(r){throw r}function Promise$_spreadAdapter(val,receiver){if(!util.isArray(val))return Promise$_successAdapter(val,receiver);var ret=util.tryCatchApply(this,[null].concat(val),receiver);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_successAdapter(val,receiver){var nodeback=this,ret=void 0===val?tryCatch1(nodeback,receiver,null):tryCatch2(nodeback,receiver,null,val);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_errorAdapter(reason,receiver){var nodeback=this,ret=tryCatch1(nodeback,receiver,reason);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),tryCatch2=util.tryCatch2,tryCatch1=util.tryCatch1,errorObj=util.errorObj;Promise.prototype.nodeify=function(nodeback,options){if("function"==typeof nodeback){var adapter=Promise$_successAdapter;void 0!==options&&Object(options).spread&&(adapter=Promise$_spreadAdapter),this._then(adapter,Promise$_errorAdapter,void 0,nodeback,this._boundTo)}return this}}},{"./async.js":1,"./util.js":19}],12:[function(_dereq_,module,exports){"use strict";function noConflict(bluebird){try{Promise===bluebird&&(Promise=old)}catch(e){}return bluebird}var old;"undefined"!=typeof Promise&&(old=Promise),module.exports=function(){function Promise(resolver){if("function"!=typeof resolver)throw new TypeError("the promise constructor requires a resolver function");if(this.constructor!==Promise)throw new TypeError("the promise constructor cannot be invoked directly");this._bitField=0,this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0,this._settledValue=void 0,this._boundTo=void 0,resolver!==INTERNAL&&this._resolveFromResolver(resolver)}function returnFirstElement(elements){return elements[0]}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),errors=_dereq_("./errors.js"),INTERNAL=function(){},APPLY={},NEXT_FILTER={e:null},cast=_dereq_("./thenables.js")(Promise,INTERNAL),PromiseArray=_dereq_("./promise_array.js")(Promise,INTERNAL,cast),CapturedTrace=_dereq_("./captured_trace.js")(),CatchFilter=_dereq_("./catch_filter.js")(NEXT_FILTER),PromiseResolver=_dereq_("./promise_resolver.js"),isArray=util.isArray,errorObj=util.errorObj,tryCatch1=util.tryCatch1,tryCatch2=util.tryCatch2,tryCatchApply=util.tryCatchApply,RangeError=errors.RangeError,TypeError=errors.TypeError,CancellationError=errors.CancellationError,TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,originatesFromRejection=errors.originatesFromRejection,markAsOriginatingFromRejection=errors.markAsOriginatingFromRejection,canAttach=errors.canAttach,thrower=util.thrower,apiRejection=_dereq_("./errors_api_rejection")(Promise),makeSelfResolutionError=function(){return new TypeError("circular promise resolution chain")};Promise.prototype.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(maybePromise instanceof Promise){var binder=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)}),p=Promise.all([this,binder]).then(returnFirstElement);ret._follow(p)}else ret._follow(this),ret._setBoundTo(thisArg);return ret._propagateFrom(this,3),ret},Promise.prototype.toString=function(){return"[object Promise]"},Promise.prototype.caught=Promise.prototype["catch"]=function(fn){var len=arguments.length;if(len>1){var i,catchInstances=new Array(len-1),j=0;for(i=0;len-1>i;++i){var item=arguments[i];if("function"!=typeof item){var catchFilterTypeError=new TypeError("A catch filter must be an error constructor or a filter function");return this._attachExtraTrace(catchFilterTypeError),Promise.reject(catchFilterTypeError)}catchInstances[j++]=item}catchInstances.length=j,fn=arguments[i],this._resetTrace();var catchFilter=new CatchFilter(catchInstances,fn,this);return this._then(void 0,catchFilter.doFilter,void 0,catchFilter,void 0)}return this._then(void 0,fn,void 0,void 0,void 0)},Promise.prototype.then=function(didFulfill,didReject,didProgress){return this._then(didFulfill,didReject,didProgress,void 0,void 0)},Promise.prototype.done=function(didFulfill,didReject,didProgress){var promise=this._then(didFulfill,didReject,didProgress,void 0,void 0);promise._setIsFinal()},Promise.prototype.spread=function(didFulfill,didReject){return this._then(didFulfill,didReject,void 0,APPLY,void 0)},Promise.prototype.isCancellable=function(){return!this.isResolved()&&this._cancellable()},Promise.prototype.toJSON=function(){var ret={isFulfilled:!1,isRejected:!1,fulfillmentValue:void 0,rejectionReason:void 0};return this.isFulfilled()?(ret.fulfillmentValue=this._settledValue,ret.isFulfilled=!0):this.isRejected()&&(ret.rejectionReason=this._settledValue,ret.isRejected=!0),ret},Promise.prototype.all=function(){return new PromiseArray(this).promise()},Promise.is=function(val){return val instanceof Promise},Promise.all=function(promises){return new PromiseArray(promises).promise()},Promise.prototype.error=function(fn){return this.caught(originatesFromRejection,fn)},Promise.prototype._resolveFromSyncValue=function(value){if(value===errorObj)this._cleanValues(),this._setRejected(),this._settledValue=value.e,this._ensurePossibleRejectionHandled();else{var maybePromise=cast(value,void 0);maybePromise instanceof Promise?this._follow(maybePromise):(this._cleanValues(),this._setFulfilled(),this._settledValue=value)}},Promise.method=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");return function(){var value;switch(arguments.length){case 0:value=tryCatch1(fn,this,void 0);break;case 1:value=tryCatch1(fn,this,arguments[0]);break;case 2:value=tryCatch2(fn,this,arguments[0],arguments[1]);break;default:for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];value=tryCatchApply(fn,args,this)}var ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret}},Promise.attempt=Promise["try"]=function(fn,args,ctx){if("function"!=typeof fn)return apiRejection("fn must be a function");var value=isArray(args)?tryCatchApply(fn,args,ctx):tryCatch1(fn,ctx,args),ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret},Promise.defer=Promise.pending=function(){var promise=new Promise(INTERNAL);return promise._setTrace(void 0),new PromiseResolver(promise)},Promise.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(ret._setTrace(void 0),maybePromise instanceof Promise){var p=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)});ret._follow(p)}else ret._setBoundTo(thisArg),ret._setFulfilled();return ret},Promise.cast=function(obj){var ret=cast(obj,void 0);if(!(ret instanceof Promise)){var val=ret;ret=new Promise(INTERNAL),ret._setTrace(void 0),ret._setFulfilled(),ret._cleanValues(),ret._settledValue=val}return ret},Promise.resolve=Promise.fulfilled=Promise.cast,Promise.reject=Promise.rejected=function(reason){var ret=new Promise(INTERNAL);if(ret._setTrace(void 0),markAsOriginatingFromRejection(reason),ret._cleanValues(),ret._setRejected(),ret._settledValue=reason,!canAttach(reason)){var trace=new Error(reason+"");ret._setCarriedStackTrace(trace)}return ret._ensurePossibleRejectionHandled(),ret},Promise.onPossiblyUnhandledRejection=function(fn){CapturedTrace.possiblyUnhandledRejection="function"==typeof fn?fn:void 0};var unhandledRejectionHandled;Promise.onUnhandledRejectionHandled=function(fn){unhandledRejectionHandled="function"==typeof fn?fn:void 0};var debugging=!("undefined"==typeof process||"string"!=typeof process.execPath||"object"!=typeof process.env||!process.env.BLUEBIRD_DEBUG&&"development"!==process.env.NODE_ENV);Promise.longStackTraces=function(){if(async.haveItemsQueued()&&debugging===!1)throw new Error("cannot enable long stack traces after promises have been created");debugging=CapturedTrace.isSupported()},Promise.hasLongStackTraces=function(){return debugging&&CapturedTrace.isSupported()},Promise.prototype._then=function(didFulfill,didReject,didProgress,receiver,internalData){var haveInternalData=void 0!==internalData,ret=haveInternalData?internalData:new Promise(INTERNAL);if(!haveInternalData){if(debugging){var haveSameContext=this._peekContext()===this._traceParent;ret._traceParent=haveSameContext?this._traceParent:this}ret._propagateFrom(this,7)}var callbackIndex=this._addCallbacks(didFulfill,didReject,didProgress,ret,receiver);return this.isResolved()&&async.invoke(this._queueSettleAt,this,callbackIndex),ret},Promise.prototype._length=function(){return 262143&this._bitField},Promise.prototype._isFollowingOrFulfilledOrRejected=function(){return(939524096&this._bitField)>0},Promise.prototype._isFollowing=function(){return 536870912===(536870912&this._bitField)},Promise.prototype._setLength=function(len){this._bitField=-262144&this._bitField|262143&len},Promise.prototype._setFulfilled=function(){this._bitField=268435456|this._bitField},Promise.prototype._setRejected=function(){this._bitField=134217728|this._bitField},Promise.prototype._setFollowing=function(){this._bitField=536870912|this._bitField},Promise.prototype._setIsFinal=function(){this._bitField=33554432|this._bitField},Promise.prototype._isFinal=function(){return(33554432&this._bitField)>0},Promise.prototype._cancellable=function(){return(67108864&this._bitField)>0},Promise.prototype._setCancellable=function(){this._bitField=67108864|this._bitField},Promise.prototype._unsetCancellable=function(){this._bitField=-67108865&this._bitField},Promise.prototype._setRejectionIsUnhandled=function(){this._bitField=2097152|this._bitField},Promise.prototype._unsetRejectionIsUnhandled=function(){this._bitField=-2097153&this._bitField,this._isUnhandledRejectionNotified()&&(this._unsetUnhandledRejectionIsNotified(),this._notifyUnhandledRejectionIsHandled())},Promise.prototype._isRejectionUnhandled=function(){return(2097152&this._bitField)>0},Promise.prototype._setUnhandledRejectionIsNotified=function(){this._bitField=524288|this._bitField},Promise.prototype._unsetUnhandledRejectionIsNotified=function(){this._bitField=-524289&this._bitField},Promise.prototype._isUnhandledRejectionNotified=function(){return(524288&this._bitField)>0},Promise.prototype._setCarriedStackTrace=function(capturedTrace){this._bitField=1048576|this._bitField,this._fulfillmentHandler0=capturedTrace},Promise.prototype._unsetCarriedStackTrace=function(){this._bitField=-1048577&this._bitField,this._fulfillmentHandler0=void 0},Promise.prototype._isCarryingStackTrace=function(){return(1048576&this._bitField)>0},Promise.prototype._getCarriedStackTrace=function(){return this._isCarryingStackTrace()?this._fulfillmentHandler0:void 0},Promise.prototype._receiverAt=function(index){var ret=0===index?this._receiver0:this[(index<<2)+index-5+4];return this._isBound()&&void 0===ret?this._boundTo:ret},Promise.prototype._promiseAt=function(index){return 0===index?this._promise0:this[(index<<2)+index-5+3]},Promise.prototype._fulfillmentHandlerAt=function(index){return 0===index?this._fulfillmentHandler0:this[(index<<2)+index-5+0]},Promise.prototype._rejectionHandlerAt=function(index){return 0===index?this._rejectionHandler0:this[(index<<2)+index-5+1]},Promise.prototype._addCallbacks=function(fulfill,reject,progress,promise,receiver){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promise,void 0!==receiver&&(this._receiver0=receiver),"function"!=typeof fulfill||this._isCarryingStackTrace()||(this._fulfillmentHandler0=fulfill),"function"==typeof reject&&(this._rejectionHandler0=reject),"function"==typeof progress&&(this._progressHandler0=progress);else{var base=(index<<2)+index-5;this[base+3]=promise,this[base+4]=receiver,this[base+0]="function"==typeof fulfill?fulfill:void 0,this[base+1]="function"==typeof reject?reject:void 0,this[base+2]="function"==typeof progress?progress:void 0}return this._setLength(index+1),index},Promise.prototype._setProxyHandlers=function(receiver,promiseSlotValue){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promiseSlotValue,this._receiver0=receiver;else{var base=(index<<2)+index-5;this[base+3]=promiseSlotValue,this[base+4]=receiver,this[base+0]=this[base+1]=this[base+2]=void 0}this._setLength(index+1)},Promise.prototype._proxyPromiseArray=function(promiseArray,index){this._setProxyHandlers(promiseArray,index)},Promise.prototype._proxyPromise=function(promise){promise._setProxied(),this._setProxyHandlers(promise,-15)},Promise.prototype._setBoundTo=function(obj){void 0!==obj?(this._bitField=8388608|this._bitField,this._boundTo=obj):this._bitField=-8388609&this._bitField},Promise.prototype._isBound=function(){return 8388608===(8388608&this._bitField)},Promise.prototype._resolveFromResolver=function(resolver){function Promise$_resolver(val){promise._tryFollow(val)||promise._fulfill(val)}function Promise$_rejecter(val){var trace=canAttach(val)?val:new Error(val+"");promise._attachExtraTrace(trace),markAsOriginatingFromRejection(val),promise._reject(val,trace===val?void 0:trace)}var promise=this;this._setTrace(void 0),this._pushContext();var r=tryCatch2(resolver,void 0,Promise$_resolver,Promise$_rejecter);if(this._popContext(),void 0!==r&&r===errorObj){var e=r.e,trace=canAttach(e)?e:new Error(e+"");promise._reject(e,trace)}},Promise.prototype._spreadSlowCase=function(targetFn,promise,values,boundTo){var promiseForAll=new PromiseArray(values).promise(),promise2=promiseForAll._then(function(){return targetFn.apply(boundTo,arguments)},void 0,void 0,APPLY,void 0);promise._follow(promise2)},Promise.prototype._callSpread=function(handler,promise,value){var boundTo=this._boundTo;if(isArray(value))for(var i=0,len=value.length;len>i;++i)if(cast(value[i],void 0)instanceof Promise)return void this._spreadSlowCase(handler,promise,value,boundTo);return promise._pushContext(),tryCatchApply(handler,value,boundTo)},Promise.prototype._callHandler=function(handler,receiver,promise,value){var x;return receiver!==APPLY||this.isRejected()?(promise._pushContext(),x=tryCatch1(handler,receiver,value)):x=this._callSpread(handler,promise,value),promise._popContext(),x},Promise.prototype._settlePromiseFromHandler=function(handler,receiver,value,promise){if(!(promise instanceof Promise))return void handler.call(receiver,value,promise);var x=this._callHandler(handler,receiver,promise,value);if(!promise._isFollowing())if(x===errorObj||x===promise||x===NEXT_FILTER){var err=x===promise?makeSelfResolutionError():x.e,trace=canAttach(err)?err:new Error(err+""); +x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string"); +RemoteStorage.config.cordovaRedirectUri=uri},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.rs=rs,this.connected=!1,RS.eventHandling(this,"change","connected","not-connected","wire-busy","wire-done"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]?!0:!1}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(url,errorHandler,sucessHandler){function __processState(){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"resource not found",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}function __makeRequest(){xhr.onreadystatechange=function(){4===xhr.readyState&&__processState()},xhr.onload=function(a,b){__processState()},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this,xhr=new XMLHttpRequest;return __makeRequest()},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(URL,JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error,request:URL}):generateErrorObject({message:"unknown response from server",request:URL}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){var uri="";return address.split("://")[1]||(uri="acct:"),protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource="+uri+address}function __fallbackChecks(err){if(self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1)return uri_index+=1,__call();if(!self.config.tls_only&&"https"===protocol)return uri_index=0,protocol="http",__call();if(!self.config.webfist_fallback||"webfist.org"===host)return cb(err);uri_index=0,protocol="http",host="webfist.org";var URL=__buildURL();self.__fetchJRD(URL,cb,function(data){self.__processJRD(URL,data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(URL,JRD,cb,function(result){return cb(null,cb)})})})})}function __call(){var URL=__buildURL();self.__fetchJRD(URL,__fallbackChecks,function(JRD){self.__processJRD(URL,JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,host="";host=address.indexOf("://")>-1?address.replace(/ /g,"").split("://")[1]:address.replace(/ /g,"").split("@")[1];var uri_index=0,protocol="https";return self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0)},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId), +!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href,storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' +},function(window){function stateSetter(widget,state,message){return RemoteStorage.log("[Widget] Producing stateSetter for",state),function(){RemoteStorage.log("[Widget] Setting state",state,message),hasLocalStorage&&(localStorage[LS_STATE_KEY]=state),widget.view?(widget.rs.remote&&widget.view.setUserAddress(widget.rs.remote.userAddress),widget.view.setState(state,message)):widget._rememberedState=state}}function errorsHandler(widget){return function(error){var s;error instanceof RemoteStorage.DiscoveryError?(console.error("Discovery failed",error,'"'+error.message+'"'),s=stateSetter(widget,"initial",error.message)):error instanceof RemoteStorage.SyncError?s=stateSetter(widget,"offline"):error instanceof RemoteStorage.Unauthorized?s=stateSetter(widget,"unauthorized"):(RemoteStorage.log("[Widget] Unknown error"),s=stateSetter(widget,"error",[error])),s.apply()}}function flashFor(evt){return"GET"===evt.method&&evt.isFolder?!1:!0}var hasLocalStorage,LS_STATE_KEY="remotestorage:widget:state",VALID_ENTRY_STATES={initial:!0,connected:!0,offline:!0};RemoteStorage.Widget=function(remoteStorage){var self=this,requestsToFlashFor=0;if(this.rs=remoteStorage,this.rs.remote.on("connected",stateSetter(this,"connected")),this.rs.on("disconnected",stateSetter(this,"initial")),this.rs.on("connecting",stateSetter(this,"authing")),this.rs.on("authing",stateSetter(this,"authing")),this.rs.on("error",errorsHandler(this)),this.rs.remote&&(this.rs.remote.on("wire-busy",function(evt){flashFor(evt)&&(requestsToFlashFor++,stateSetter(self,"busy")())}),this.rs.remote.on("wire-done",function(evt){flashFor(evt)&&requestsToFlashFor--,0>=requestsToFlashFor&&evt.success&&stateSetter(self,"connected")()})),hasLocalStorage){var state=localStorage[LS_STATE_KEY];state&&VALID_ENTRY_STATES[state]&&(this._rememberedState=state)}},RemoteStorage.Widget.prototype={display:function(options){return"string"==typeof options?options={domID:options}:"undefined"==typeof options&&(options={}),this.view||this.setView(new RemoteStorage.Widget.View(this.rs)),this.view.display(options),this},linkWidgetToSync:function(){"object"==typeof this.rs.sync&&"function"==typeof this.rs.sync.sync?this.view.on("sync",this.rs.sync.sync.bind(this.rs.sync)):(RemoteStorage.log("[Widget] typeof this.rs.sync check fail",this.rs.sync),setTimeout(this.linkWidgetToSync.bind(this),1e3))},setView:function(view){this.view=view,this.view.on("connect",function(options){"string"==typeof options?this.rs.connect(options):options.special&&this.rs[options.special].connect(options)}.bind(this)),this.view.on("secret-entered",function(secretKey){this.view.setUserSecretKey(secretKey),stateSetter(this,"ciphered")()}.bind(this)),this.view.on("secret-cancelled",function(){stateSetter(this,"notciphered")()}.bind(this)),this.view.on("disconnect",this.rs.disconnect.bind(this.rs)),this.linkWidgetToSync();try{this.view.on("reset",function(){var location=RemoteStorage.Authorize.getLocation();this.rs.on("disconnected",location.reload.bind(location)),this.rs.disconnect()}.bind(this))}catch(e){if(!e.message||!e.message.match(/Unknown event/))throw e}this._rememberedState&&(setTimeout(stateSetter(this,this._rememberedState),0),delete this._rememberedState)}},RemoteStorage.prototype.displayWidget=function(options){return this.widget.display(options)},RemoteStorage.Widget._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.widget||(remoteStorage.widget=new RemoteStorage.Widget(remoteStorage))},RemoteStorage.Widget._rs_supported=function(remoteStorage){return"undefined"!=typeof document}}("undefined"!=typeof window?window:global),function(window){function removeClass(el,className){return el.classList.remove(className)}function addClass(el,className){return el.classList.add(className)}function stopPropagation(event){"function"==typeof event.stopPropagation?event.stopPropagation():event.cancelBubble=!0}function setupButton(parent,className,iconName,eventListener){var element=parent.querySelector("."+className);if("undefined"!=typeof iconName){var img=element.querySelector("img");(img||element).src=RemoteStorage.Assets[iconName]}return element.addEventListener("click",eventListener),element}function handleButtonState(event){event.target.value?event.target.nextElementSibling.removeAttribute("disabled"):event.target.nextElementSibling.setAttribute("disabled","disabled")}var t=RemoteStorage.I18n.translate;RemoteStorage.Widget.View=function(remoteStorage){if(this.rs=remoteStorage,"undefined"==typeof document)throw"Widget not supported";RemoteStorage.eventHandling(this,"connect","secret-entered","secret-cancelled","disconnect","sync","display","reset");for(var event in this.events)this.events[event]=this.events[event].bind(this);this.hideBubbleOnBodyClick=function(event){for(var p=event.target;p!==document.body;p=p.parentElement)if("remotestorage-widget"===p.id)return;this.hideBubble()}.bind(this)},RemoteStorage.Widget.View.prototype={connectGdrive:function(){this._emit("connect",{special:"googledrive"})},connectDropbox:function(){this._emit("connect",{special:"dropbox"})},setState:function(state,message){RemoteStorage.log("[View] widget.view.setState(",state,",",message,");");var s=this.states[state];if("undefined"==typeof s)throw new Error("Bad State assigned to view: "+state);s.apply(this,[message])},setUserAddress:function(addr){this.userAddress=addr||"";var el;this.div&&(el=this.div.querySelector("form.remotestorage-initial").userAddress)&&(el.value=this.userAddress)},setUserSecretKey:function(secretKey){this.userSecretKey=secretKey},toggleBubble:function(event){this.bubble.className.search("rs-hidden")<0?this.hideBubble(event):this.showBubble(event)},hideBubble:function(){addClass(this.bubble,"rs-hidden"),document.body.removeEventListener("click",this.hideBubbleOnBodyClick)},showBubble:function(event){removeClass(this.bubble,"rs-hidden"),"undefined"!=typeof event&&stopPropagation(event),document.body.addEventListener("click",this.hideBubbleOnBodyClick),this.div.querySelector(".remotestorage-connected").classList.contains("remotestorage-cipher")&&!this.userSecretKey?this.bubble.querySelector("form.remotestorage-cipher-form").userSecretKey.focus():this.bubble.querySelector("form.remotestorage-initial").userAddress.focus()},display:function(options){if("undefined"!=typeof this.div)return this.div;var element=document.createElement("div"),style=document.createElement("style");if(style.innerHTML=RemoteStorage.Assets.widgetCss,element.id="remotestorage-widget",element.innerHTML=RemoteStorage.Assets.widget,element.appendChild(style),options.domID){var parent=document.getElementById(options.domID);if(!parent)throw'Failed to find target DOM element with id="'+options.domID+'"';parent.appendChild(element)}else document.body.appendChild(element);setupButton(element,"rs-sync","syncIcon",this.events.sync),setupButton(element,"rs-disconnect","disconnectIcon",this.events.disconnect),setupButton(element,"remotestorage-reset",void 0,this.events.reset);setupButton(element,"connect","connectIcon",this.events.connect);this.form=element.querySelector("form.remotestorage-initial");var el=this.form.userAddress;if(el.addEventListener("load",handleButtonState),el.addEventListener("keyup",handleButtonState),this.userAddress&&(el.value=this.userAddress),options.encryption){this.cipher=!0;var secretKeyInput=element.querySelector("form.remotestorage-cipher-form").userSecretKey;secretKeyInput.type="password";setupButton(element,"rs-cipher","cipherIcon",this.events["secret-entered"]);secretKeyInput.addEventListener("load",handleButtonState),secretKeyInput.addEventListener("keyup",handleButtonState),setupButton(element,"rs-nocipher","nocipherIcon",this.events["secret-cancelled"])}this.cube=setupButton(element,"rs-cube","remoteStorageIcon",this.toggleBubble.bind(this)),setupButton(element,"rs-dropbox","dropbox",this.connectDropbox.bind(this)),setupButton(element,"rs-googledrive","googledrive",this.connectGdrive.bind(this));var bubbleDontCatch={INPUT:!0,BUTTON:!0,IMG:!0},eventListener=function(event){bubbleDontCatch[event.target.tagName]||this.div.classList.contains("remotestorage-state-unauthorized")||this.showBubble(event)}.bind(this);return this.bubble=setupButton(element,"rs-bubble",void 0,eventListener),this.hideBubble(),this.div=element,this.states.initial.call(this),this.events.display.call(this),this.div},states:{initial:function(message){var cube=this.cube,info=message||t("view_info");cube.src=RemoteStorage.Assets.remoteStorageIcon,this._renderTranslatedInitialContent(),message?(cube.src=RemoteStorage.Assets.remoteStorageIconError,removeClass(this.cube,"remotestorage-loading"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},2e3)):this.hideBubble(),this.div.className="remotestorage-state-initial",this.userSecretKey&&delete this.userSecretKey;var backends=1;this._activateBackend("dropbox")&&(backends+=1),this._activateBackend("googledrive")&&(backends+=1),this.div.querySelector(".rs-bubble-text").style.paddingRight=32*backends+8+"px";var cb=this.div.querySelector(".connect");this.form.userAddress.value&&cb.removeAttribute("disabled");var infoEl=this.div.querySelector(".rs-info-msg");infoEl.innerHTML=info,message?infoEl.classList.add("remotestorage-error-info"):infoEl.classList.remove("remotestorage-error-info")},authing:function(){this.div.removeEventListener("click",this.events.connect),this.div.className="remotestorage-state-authing",this.div.querySelector(".rs-status-text").innerHTML=t("view_connecting",this.userAddress),addClass(this.cube,"remotestorage-loading")},connected:function(){var cube=this.cube;this.div.className="remotestorage-state-connected",this.div.querySelector(".userAddress").innerHTML=this.userAddress,cube.src=RemoteStorage.Assets.remoteStorageIcon,removeClass(cube,"remotestorage-loading"),this.cipher&&(this.userSecretKey?this.userSecretKeyError?(cube.src=RemoteStorage.Assets.remoteStorageIconError,addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),addClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},5e3)):(removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),cube.src=RemoteStorage.Assets.remoteStorageIconCiphered):(addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.showBubble()));var icons={googledrive:this.div.querySelector(".rs-googledrive"),dropbox:this.div.querySelector(".rs-dropbox")};icons.googledrive.style.display=icons.dropbox.style.display="none",icons[this.rs.backend]?(icons[this.rs.backend].style.display="inline-block",this.div.querySelector(".rs-bubble-text").style.paddingRight="72px"):this.div.querySelector(".rs-bubble-text").style.paddingRight="40px"},ciphered:function(){this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value="",removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.cube.src=RemoteStorage.Assets.remoteStorageIconCiphered,this.hideBubble()},notciphered:function(){this.cipher=!1,removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.hideBubble()},busy:function(){this.div.className="remotestorage-state-busy",addClass(this.cube,"remotestorage-loading")},offline:function(){this.div.className="remotestorage-state-offline",this.cube.src=RemoteStorage.Assets.remoteStorageIconOffline,this.div.querySelector(".rs-status-text").innerHTML=t("view_offline")},error:function(err){var errorMsg=err;this.div.className="remotestorage-state-error",this.div.querySelector(".rs-bubble-text").innerHTML=""+t("view_error_occured")+"",err instanceof Error&&(errorMsg=err.message+"\n\n"+err.stack),this.div.querySelector(".rs-error-msg").textContent=errorMsg,this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble()},unauthorized:function(){this.div.className="remotestorage-state-unauthorized",this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble(),this.div.addEventListener("click",this.events.connect)}},events:{connect:function(event){stopPropagation(event),event.preventDefault(),this._emit("connect",this.div.querySelector("form.remotestorage-initial").userAddress.value)},"secret-entered":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-entered",this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value)},"secret-cancelled":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-cancelled")},sync:function(event){stopPropagation(event),event.preventDefault(),this._emit("sync")},disconnect:function(event){stopPropagation(event),event.preventDefault(),this._emit("disconnect")},reset:function(event){event.preventDefault();var result=window.confirm(t("view_confirm_reset"));result&&this._emit("reset")},display:function(event){event&&event.preventDefault(),this._emit("display")}},_renderTranslatedInitialContent:function(){this.div.querySelector(".rs-status-text").innerHTML=t("view_connect"),this.div.querySelector(".remotestorage-reset").innerHTML=t("view_get_me_out"),this.div.querySelector(".rs-error-plz-report").innerHTML=t("view_error_plz_report"),this.div.querySelector(".remotestorage-unauthorized").innerHTML=t("view_unauthorized"),this.div.querySelector(".remotestorage-invalid-key").innerHTML=t("view_invalid_key")},_activateBackend:function(backendName){var className="rs-"+backendName;return this.rs.apiKeys[backendName]?(this.div.querySelector("."+className).style.display="inline-block",!0):(this.div.querySelector("."+className).style.display="none",!1)}}}("undefined"!=typeof window?window:global),function(global,factory){"function"==typeof define&&define.amd?define([],factory):"undefined"!=typeof module&&module.exports?module.exports=factory():global.tv4=factory()}(this,function(){function notReallyPercentEncode(string){return encodeURI(string).replace(/%25[0-9][0-9]/g,function(doubleEncoded){return"%"+doubleEncoded.substring(3)})}function uriTemplateSubstitution(spec){var modifier="";uriTemplateGlobalModifiers[spec.charAt(0)]&&(modifier=spec.charAt(0),spec=spec.substring(1));var separator="",prefix="",shouldEscape=!0,showVariables=!1,trimEmptyString=!1;"+"===modifier?shouldEscape=!1:"."===modifier?(prefix=".",separator="."):"/"===modifier?(prefix="/",separator="/"):"#"===modifier?(prefix="#",shouldEscape=!1):";"===modifier?(prefix=";",separator=";",showVariables=!0,trimEmptyString=!0):"?"===modifier?(prefix="?",separator="&",showVariables=!0):"&"===modifier&&(prefix="&",separator="&",showVariables=!0);for(var varNames=[],varList=spec.split(","),varSpecs=[],varSpecMap={},i=0;i0&&(result+=varSpec.suffices["*"]?separator||",":",",varSpec.suffices["*"]&&showVariables&&(result+=varSpec.name+"=")),result+=shouldEscape?encodeURIComponent(value[j]).replace(/!/g,"%21"):notReallyPercentEncode(value[j])}else if("object"==typeof value){showVariables&&!varSpec.suffices["*"]&&(result+=varSpec.name+"=");var first=!0;for(var key in value)first||(result+=varSpec.suffices["*"]?separator||",":","),first=!1,result+=shouldEscape?encodeURIComponent(key).replace(/!/g,"%21"):notReallyPercentEncode(key),result+=varSpec.suffices["*"]?"=":",",result+=shouldEscape?encodeURIComponent(value[key]).replace(/!/g,"%21"):notReallyPercentEncode(value[key])}else showVariables&&(result+=varSpec.name,trimEmptyString&&""===value||(result+="=")),null!=varSpec.truncate&&(value=value.substring(0,varSpec.truncate)),result+=shouldEscape?encodeURIComponent(value).replace(/!/g,"%21"):notReallyPercentEncode(value)}return result};return subFunction.varNames=varNames,{prefix:prefix,substitution:subFunction}}function UriTemplate(template){if(!(this instanceof UriTemplate))return new UriTemplate(template);for(var parts=template.split("{"),textParts=[parts.shift()],prefixes=[],substitutions=[],varNames=[];parts.length>0;){var part=parts.shift(),spec=part.split("}")[0],remainder=part.substring(spec.length+1),funcs=uriTemplateSubstitution(spec);substitutions.push(funcs.substitution),prefixes.push(funcs.prefix),textParts.push(remainder),varNames=varNames.concat(funcs.substitution.varNames)}this.fill=function(valueFunction){for(var result=textParts[0],i=0;i0&&"/"===testUrl.charAt(baseUrl.length-1)||"#"===remainder.charAt(0)||"?"===remainder.charAt(0))return!0}return!1}function createApi(language){var currentLanguage,customErrorReporter,globalContext=new ValidatorContext,api={setErrorReporter:function(reporter){return"string"==typeof reporter?this.language(reporter):(customErrorReporter=reporter,!0)},addFormat:function(){globalContext.addFormat.apply(globalContext,arguments)},language:function(code){return code?(languages[code]||(code=code.split("-")[0]),languages[code]?(currentLanguage=code,code):!1):currentLanguage},addLanguage:function(code,messageMap){var key;for(key in ErrorCodes)messageMap[key]&&!messageMap[ErrorCodes[key]]&&(messageMap[ErrorCodes[key]]=messageMap[key]);var rootCode=code.split("-")[0];if(languages[rootCode]){languages[code]=Object.create(languages[rootCode]);for(key in messageMap)"undefined"==typeof languages[rootCode][key]&&(languages[rootCode][key]=messageMap[key]),languages[code][key]=messageMap[key]}else languages[code]=messageMap,languages[rootCode]=messageMap;return this},freshApi:function(language){var result=createApi();return language&&result.language(language),result},validate:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!1,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema);var error=context.validateAll(data,schema,null,null,"");return!error&&banUnknownProperties&&(error=context.banUnknownProperties(data,schema)),this.error=error,this.missing=context.missing,this.valid=null===error,this.valid},validateResult:function(){var result={};return this.validate.apply(result,arguments),result},validateMultiple:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!0,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema),context.validateAll(data,schema,null,null,""),banUnknownProperties&&context.banUnknownProperties(data,schema);var result={};return result.errors=context.errors,result.missing=context.missing,result.valid=0===result.errors.length,result},addSchema:function(){return globalContext.addSchema.apply(globalContext,arguments)},getSchema:function(){return globalContext.getSchema.apply(globalContext,arguments)},getSchemaMap:function(){return globalContext.getSchemaMap.apply(globalContext,arguments)},getSchemaUris:function(){return globalContext.getSchemaUris.apply(globalContext,arguments)},getMissingUris:function(){return globalContext.getMissingUris.apply(globalContext,arguments)},dropSchemas:function(){globalContext.dropSchemas.apply(globalContext,arguments)},defineKeyword:function(){globalContext.defineKeyword.apply(globalContext,arguments)},defineError:function(codeName,codeNumber,defaultMessage){if("string"!=typeof codeName||!/^[A-Z]+(_[A-Z]+)*$/.test(codeName))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof codeNumber||codeNumber%1!==0||1e4>codeNumber)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof ErrorCodes[codeName])throw new Error("Error already defined: "+codeName+" as "+ErrorCodes[codeName]);if("undefined"!=typeof ErrorCodeLookup[codeNumber])throw new Error("Error code already used: "+ErrorCodeLookup[codeNumber]+" as "+codeNumber);ErrorCodes[codeName]=codeNumber,ErrorCodeLookup[codeNumber]=codeName,ErrorMessagesDefault[codeName]=ErrorMessagesDefault[codeNumber]=defaultMessage;for(var langCode in languages){var language=languages[langCode];language[codeName]&&(language[codeNumber]=language[codeNumber]||language[codeName])}},reset:function(){globalContext.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:normSchema,resolveUrl:resolveUrl,getDocumentUri:getDocumentUri,errorCodes:ErrorCodes};return api.language(language||"en"),api}Object.keys||(Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if("object"!=typeof obj&&"function"!=typeof obj||null===obj)throw new TypeError("Object.keys called on non-object");var result=[];for(var prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(var i=0;dontEnumsLength>i;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result}}()),Object.create||(Object.create=function(){function F(){}return function(o){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Array.isArray||(Array.isArray=function(vArg){return"[object Array]"===Object.prototype.toString.call(vArg)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(searchElement){if(null===this)throw new TypeError;var t=Object(this),len=t.length>>>0;if(0===len)return-1;var n=0;if(arguments.length>1&&(n=Number(arguments[1]),n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=len)return-1;for(var k=n>=0?n:Math.max(len-Math.abs(n),0);len>k;k++)if(k in t&&t[k]===searchElement)return k;return-1}),Object.isFrozen||(Object.isFrozen=function(obj){for(var key="tv4_test_frozen_key";obj.hasOwnProperty(key);)key+=Math.random();try{return obj[key]=!0,delete obj[key],!1}catch(e){return!0}});var uriTemplateGlobalModifiers={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},uriTemplateSuffices={"*":!0};UriTemplate.prototype={toString:function(){return this.template},fillFromObject:function(obj){return this.fill(function(varName){return obj[varName]})}};var ValidatorContext=function(parent,collectMultiple,errorReporter,checkRecursive,trackUnknownProperties){if(this.missing=[],this.missingMap={},this.formatValidators=parent?Object.create(parent.formatValidators):{},this.schemas=parent?Object.create(parent.schemas):{},this.collectMultiple=collectMultiple,this.errors=[],this.handleError=collectMultiple?this.collectError:this.returnError,checkRecursive&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),trackUnknownProperties&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=errorReporter||defaultErrorReporter("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},parent)for(var key in parent.definedKeywords)this.definedKeywords[key]=parent.definedKeywords[key].slice(0)};ValidatorContext.prototype.defineKeyword=function(keyword,keywordFunction){this.definedKeywords[keyword]=this.definedKeywords[keyword]||[],this.definedKeywords[keyword].push(keywordFunction)},ValidatorContext.prototype.createError=function(code,messageParams,dataPath,schemaPath,subErrors,data,schema){var error=new ValidationError(code,messageParams,dataPath,schemaPath,subErrors);return error.message=this.errorReporter(error,data,schema),error},ValidatorContext.prototype.returnError=function(error){return error},ValidatorContext.prototype.collectError=function(error){return error&&this.errors.push(error),null},ValidatorContext.prototype.prefixErrors=function(startIndex,dataPath,schemaPath){for(var i=startIndex;i=CLOSE_ENOUGH_LOW&&CLOSE_ENOUGH_HIGH>remainder)return this.createError(ErrorCodes.NUMBER_MULTIPLE_OF,{value:data,multipleOf:multipleOf},"","",null,data,schema)}return null},ValidatorContext.prototype.validateMinMax=function(data,schema){if("number"!=typeof data)return null;if(void 0!==schema.minimum){if(dataschema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM,{value:data,maximum:schema.maximum},"","/maximum",null,data,schema);if(schema.exclusiveMaximum&&data===schema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM_EXCLUSIVE,{value:data,maximum:schema.maximum},"","/exclusiveMaximum",null,data,schema)}return null},ValidatorContext.prototype.validateNaN=function(data,schema){return"number"!=typeof data?null:isNaN(data)===!0||data===1/0||data===-(1/0)?this.createError(ErrorCodes.NUMBER_NOT_A_NUMBER,{value:data},"","/type",null,data,schema):null},ValidatorContext.prototype.validateString=function(data,schema,dataPointerPath){return this.validateStringLength(data,schema,dataPointerPath)||this.validateStringPattern(data,schema,dataPointerPath)||null},ValidatorContext.prototype.validateStringLength=function(data,schema){return"string"!=typeof data?null:void 0!==schema.minLength&&data.lengthschema.maxLength?this.createError(ErrorCodes.STRING_LENGTH_LONG,{length:data.length,maximum:schema.maxLength},"","/maxLength",null,data,schema):null},ValidatorContext.prototype.validateStringPattern=function(data,schema){if("string"!=typeof data||"string"!=typeof schema.pattern&&!(schema.pattern instanceof RegExp))return null;var regexp;if(schema.pattern instanceof RegExp)regexp=schema.pattern;else{var body,flags="",literal=schema.pattern.match(/^\/(.+)\/([img]*)$/);literal?(body=literal[1],flags=literal[2]):body=schema.pattern,regexp=new RegExp(body,flags)}return regexp.test(data)?null:this.createError(ErrorCodes.STRING_PATTERN,{pattern:schema.pattern},"","/pattern",null,data,schema)},ValidatorContext.prototype.validateArray=function(data,schema,dataPointerPath){return Array.isArray(data)?this.validateArrayLength(data,schema,dataPointerPath)||this.validateArrayUniqueItems(data,schema,dataPointerPath)||this.validateArrayItems(data,schema,dataPointerPath)||null:null},ValidatorContext.prototype.validateArrayLength=function(data,schema){var error;return void 0!==schema.minItems&&data.lengthschema.maxItems&&(error=this.createError(ErrorCodes.ARRAY_LENGTH_LONG,{length:data.length,maximum:schema.maxItems},"","/maxItems",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateArrayUniqueItems=function(data,schema){if(schema.uniqueItems)for(var i=0;ischema.maxProperties&&(error=this.createError(ErrorCodes.OBJECT_PROPERTIES_MAXIMUM,{propertyCount:keys.length,maximum:schema.maxProperties},"","/maxProperties",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateObjectRequiredProperties=function(data,schema){if(void 0!==schema.required)for(var i=0;ii;i++)uuid[i]=chars[0|Math.random()*radix];else{var r;for(uuid[8]=uuid[13]=uuid[18]=uuid[23]="-",uuid[14]="4",i=0;36>i;i++)uuid[i]||(r=0|16*Math.random(),uuid[i]=chars[19==i?3&r|8:r])}return uuid.join("")},function(global){function deprecate(thing,replacement){console.log("WARNING: "+thing+" is deprecated. Use "+replacement+" instead.")}var RS=RemoteStorage;RS.BaseClient=function(storage,base){if("/"!==base[base.length-1])throw"Not a folder: "+base;"/"===base&&(this.makePath=function(path){return("/"===path[0]?"":"/")+path}),this.storage=storage,this.base=base;var parts=this.base.split("/");parts.length>2?this.moduleName=parts[1]:this.moduleName="root",RS.eventHandling(this,"change"),this.on=this.on.bind(this),storage.onChange(this.base,this._fireChange.bind(this))},RS.BaseClient.prototype={extend:function(object){for(var key in object)this[key]=object[key];return this},scope:function(path){return new RS.BaseClient(this.storage,this.makePath(path))},getListing:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){return 404===r.statusCode?{}:r.body})},getAll:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){if(404===r.statusCode)return{};if("object"==typeof r.body){var keys=Object.keys(r.body);if(0===keys.length)return{};var calls=keys.map(function(key){return this.storage.get(this.makePath(path+key),maxAge).then(function(o){if("string"==typeof o.body)try{o.body=JSON.parse(o.body)}catch(e){}"object"==typeof o.body&&(r.body[key]=o.body)})}.bind(this));return Promise.all(calls).then(function(){return r.body})}}.bind(this))},getFile:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getFile must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){return{data:r.body,contentType:r.contentType,revision:r.revision}})},storeFile:function(mimeType,path,body){return"string"!=typeof mimeType?Promise.reject("Argument 'mimeType' of baseClient.storeFile must be a string"):"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.storeFile must be a string"):"string"!=typeof body&&"object"!=typeof body?Promise.reject("Argument 'body' of baseClient.storeFile must be a string, ArrayBuffer, or ArrayBufferView"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Editing a document to which only read access ('r') was claimed"),this.storage.put(this.makePath(path),body,mimeType).then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this)))},getObject:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getObject must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){if("object"==typeof r.body)return r.body;if("string"==typeof r.body)try{return JSON.parse(r.body)}catch(e){throw"Not valid JSON: "+this.makePath(path)}else if("undefined"!=typeof r.body&&200===r.statusCode)return Promise.reject("Not an object: "+this.makePath(path))}.bind(this))},storeObject:function(typeAlias,path,object){if("string"!=typeof typeAlias)return Promise.reject("Argument 'typeAlias' of baseClient.storeObject must be a string");if("string"!=typeof path)return Promise.reject("Argument 'path' of baseClient.storeObject must be a string");if("object"!=typeof object)return Promise.reject("Argument 'object' of baseClient.storeObject must be an object");this._attachType(object,typeAlias);try{var validationResult=this.validate(object);if(!validationResult.valid)return Promise.reject(validationResult)}catch(exc){return Promise.reject(exc)}return this.storage.put(this.makePath(path),JSON.stringify(object),"application/json; charset=UTF-8").then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this))},remove:function(path){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.remove must be a string"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Removing a document to which only read access ('r') was claimed"),this.storage["delete"](this.makePath(path)))},cache:function(path,strategy){if("string"!=typeof path)throw"Argument 'path' of baseClient.cache must be a string";if(strategy===!1?(deprecate("caching strategy ",'<"FLUSH">'),strategy="FLUSH"):void 0===strategy?strategy="ALL":"string"!=typeof strategy&&(deprecate("that caching strategy",'<"ALL">'),strategy="ALL"),"FLUSH"!==strategy&&"SEEN"!==strategy&&"ALL"!==strategy)throw'Argument \'strategy\' of baseclient.cache must be one of ["FLUSH", "SEEN", "ALL"]';return this.storage.caching.set(this.makePath(path),strategy),this},flush:function(path){return this.storage.local.flush(path)},makePath:function(path){return this.base+(path||"")},_fireChange:function(event){RemoteStorage.config.changeEvents[event.origin]&&(["new","old","lastCommon"].forEach(function(fieldNamePrefix){if((!event[fieldNamePrefix+"ContentType"]||/^application\/(.*)json(.*)/.exec(event[fieldNamePrefix+"ContentType"]))&&"string"==typeof event[fieldNamePrefix+"Value"])try{event[fieldNamePrefix+"Value"]=JSON.parse(event[fieldNamePrefix+"Value"])}catch(e){}}),this._emit("change",event))},_cleanPath:RemoteStorage.util.cleanPath,getItemURL:function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.getItemURL must be a string";return this.storage.connected?(path=this._cleanPath(this.makePath(path)),this.storage.remote.href+path):void 0},uuid:function(){return Math.uuid()}},RS.BaseClient._rs_init=function(){RS.prototype.scope=function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.scope must be a string";if(!this.access.checkPathPermission(path,"r")){var escapedPath=path.replace(/(['\\])/g,"\\$1");console.warn("WARNING: please call remoteStorage.access.claim('"+escapedPath+"', 'r') (read only) or remoteStorage.access.claim('"+escapedPath+"', 'rw') (read/write) first")}return new RS.BaseClient(this,path)}}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.BaseClient.Types={uris:{},schemas:{},aliases:{},declare:function(moduleName,alias,uri,schema){var fullAlias=moduleName+"/"+alias;if(schema["extends"]){var extendedAlias,parts=schema["extends"].split("/");extendedAlias=1===parts.length?moduleName+"/"+parts.shift():parts.join("/");var extendedUri=this.uris[extendedAlias];if(!extendedUri)throw"Type '"+fullAlias+"' tries to extend unknown schema '"+extendedAlias+"'";schema["extends"]=this.schemas[extendedUri]}this.uris[fullAlias]=uri,this.aliases[uri]=fullAlias,this.schemas[uri]=schema},resolveAlias:function(alias){return this.uris[alias]},getSchema:function(uri){return this.schemas[uri]},inScope:function(moduleName){var ml=moduleName.length,schemas={};for(var alias in this.uris)if(alias.substr(0,ml+1)===moduleName+"/"){var uri=this.uris[alias];schemas[uri]=this.schemas[uri]}return schemas}};var SchemaNotFound=function(uri){var error=new Error("Schema not found: "+uri);return error.name="SchemaNotFound",error};SchemaNotFound.prototype=Error.prototype,RemoteStorage.BaseClient.Types.SchemaNotFound=SchemaNotFound,RemoteStorage.BaseClient.prototype.extend({declareType:function(alias,uri,schema){schema||(schema=uri,uri=this._defaultTypeURI(alias)),RemoteStorage.BaseClient.Types.declare(this.moduleName,alias,uri,schema)},validate:function(object){var schema=RemoteStorage.BaseClient.Types.getSchema(object["@context"]);if(schema)return tv4.validateResult(object,schema);throw new SchemaNotFound(object["@context"])},_defaultTypeURI:function(alias){return"http://remotestorage.io/spec/modules/"+encodeURIComponent(this.moduleName)+"/"+encodeURIComponent(alias)},_attachType:function(object,alias){object["@context"]=RemoteStorage.BaseClient.Types.resolveAlias(this.moduleName+"/"+alias)||this._defaultTypeURI(alias)}}),Object.defineProperty(RemoteStorage.BaseClient.prototype,"schemas",{configurable:!0,get:function(){return RemoteStorage.BaseClient.Types.inScope(this.moduleName)}})}("undefined"!=typeof window?window:global),function(){RemoteStorage.MODULES={},RemoteStorage.defineModule=function(moduleName,builder){if(RemoteStorage.MODULES[moduleName]=builder, -Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,RS.WireClient.request(method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():xhr})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){rs._emit("error",new RemoteStorage.SyncError(err))})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?global.setTimeout(self._request(method,url,options),3210):Promise.resolve(xhr)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return;rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),promise.reject(err)}).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response)}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):(200!==resp.status&&404!==resp.status||(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file +Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",isFolder=RemoteStorage.util.isFolder,Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){return rs._emit("error",new RemoteStorage.SyncError(err)),Promise.reject(err)})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",isFolder=RemoteStorage.util.isFolder,getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?(self.online&&(self.online=!1,self.rs._emit("network-offline")),global.setTimeout(self._request(method,url,options),3210)):(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return;rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){return this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),Promise.resolve(args)}.bind(this)).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response)}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):((200===resp.status||404===resp.status)&&(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file diff --git a/release/stable/remotestorage.amd.js b/release/stable/remotestorage.amd.js index 83d3bcc7a..22bef1ae8 100644 --- a/release/stable/remotestorage.amd.js +++ b/release/stable/remotestorage.amd.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.0, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ define([], function() { /** FILE: src/remotestorage.js **/ @@ -171,6 +171,18 @@ define([], function() { * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -180,8 +192,9 @@ define([], function() { RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -316,6 +329,20 @@ define([], function() { * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -368,7 +395,7 @@ define([], function() { this._emit('connecting'); var discoveryTimeout = setTimeout(function () { - this._emit('error', new RemoteStorage.DiscoveryError("No storage information found at that user address.")); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this), RemoteStorage.config.discoveryTimeout); RemoteStorage.Discover(userAddress).then(function (info) { @@ -400,7 +427,8 @@ define([], function() { } } }.bind(this), function(err) { - this._emit('error', new RemoteStorage.DiscoveryError("Failed to contact storage server.")); + clearTimeout(discoveryTimeout); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this)); }, @@ -1616,6 +1644,7 @@ define([], function() { * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -1627,7 +1656,8 @@ define([], function() { * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -1713,13 +1743,17 @@ define([], function() { body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -1755,11 +1789,16 @@ define([], function() { } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -2060,7 +2099,7 @@ define([], function() { webFinger.lookup(userAddress, function (err, response) { if (err) { - return pending.reject(err.message); + return pending.reject(err); } else if ((typeof response.idx.links.remotestorage !== 'object') || (typeof response.idx.links.remotestorage.length !== 'number') || (response.idx.links.remotestorage.length <= 0)) { @@ -2116,11 +2155,11 @@ define([], function() { /* global define */ /*! * webfinger.js - * version 2.3.2 + * version 2.4.2 * http://github.com/silverbucket/webfinger.js * * Developed and Maintained by: - * Nick Jennings 2012 - 2014 + * Nick Jennings 2012 - 2016 * * webfinger.js is released under the AGPL (see LICENSE). * @@ -2177,7 +2216,7 @@ if (typeof XMLHttpRequest === 'undefined') { return obj; } - // given a URL ensures it's HTTPS. + // given a URL ensures it's HTTPS. // returns false for null string or non-HTTPS URL. function isSecure(url) { if (typeof url !== 'string') { @@ -2214,56 +2253,64 @@ if (typeof XMLHttpRequest === 'undefined') { // make an http request and look for JRD response, fails if request fails // or response not json. - WebFinger.prototype.__fetchJRD = function (_url, errorHandler, sucessHandler) { + WebFinger.prototype.__fetchJRD = function (url, errorHandler, sucessHandler) { var self = this; - function __makeRequest(url) { - var xhr = new XMLHttpRequest(); - + + var xhr = new XMLHttpRequest(); + + function __processState() { + if (xhr.status === 200) { + if (self.__isValidJSON(xhr.responseText)) { + return sucessHandler(xhr.responseText); + } else { + return errorHandler(generateErrorObject({ + message: 'invalid json', + url: url, + status: xhr.status + })); + } + } else if (xhr.status === 404) { + return errorHandler(generateErrorObject({ + message: 'resource not found', + url: url, + status: xhr.status + })); + } else if ((xhr.status >= 301) && (xhr.status <= 302)) { + var location = xhr.getResponseHeader('Location'); + if (isSecure(location)) { + return __makeRequest(location); // follow redirect + } else { + return errorHandler(generateErrorObject({ + message: 'no redirect URL found', + url: url, + status: xhr.status + })); + } + } else { + return errorHandler(generateErrorObject({ + message: 'error during request', + url: url, + status: xhr.status + })); + } + } + + function __makeRequest() { xhr.onreadystatechange = function () { if (xhr.readyState === 4) { - if (xhr.status === 200) { - if (self.__isValidJSON(xhr.responseText)) { - return sucessHandler(xhr.responseText); - } else { - return errorHandler(generateErrorObject({ - message: 'invalid json', - url: url, - status: xhr.status - })); - } - } else if (xhr.status === 404) { - return errorHandler(generateErrorObject({ - message: 'endpoint unreachable', - url: url, - status: xhr.status - })); - } else if ((xhr.status >= 301) && (xhr.status <= 302)) { - var location = xhr.getResponseHeader('Location'); - if (isSecure(location)) { - return __makeRequest(location); // follow redirect - } else { - return errorHandler(generateErrorObject({ - message: 'no redirect URL found', - url: url, - status: xhr.status - })); - } - } else { - return errorHandler(generateErrorObject({ - message: 'error during request', - url: url, - status: xhr.status - })); - } + __processState(); } }; - + + xhr.onload = function (a, b) { + __processState(); + } xhr.open('GET', url, true); xhr.setRequestHeader('Accept', 'application/jrd+json, application/json'); xhr.send(); } - - return __makeRequest(_url); + + return __makeRequest(); }; WebFinger.prototype.__isValidJSON = function (str) { @@ -2282,16 +2329,15 @@ if (typeof XMLHttpRequest === 'undefined') { // processes JRD object as if it's a webfinger response object // looks for known properties and adds them to profile datat struct. - WebFinger.prototype.__processJRD = function (JRD, errorHandler, successHandler) { + WebFinger.prototype.__processJRD = function (URL, JRD, errorHandler, successHandler) { var parsedJRD = JSON.parse(JRD); if ((typeof parsedJRD !== 'object') || (typeof parsedJRD.links !== 'object')) { if (typeof parsedJRD.error !== 'undefined') { - return errorHandler(generateErrorObject({ message: parsedJRD.error })); + return errorHandler(generateErrorObject({ message: parsedJRD.error, request: URL })); } else { - return errorHandler(generateErrorObject({ message: 'unknown response from server' })); + return errorHandler(generateErrorObject({ message: 'unknown response from server', request: URL })); } - return false; } var links = parsedJRD.links; @@ -2339,20 +2385,29 @@ if (typeof XMLHttpRequest === 'undefined') { } var self = this; - var parts = address.replace(/ /g,'').split('@'); - var host = parts[1]; // host name for this useraddress + var host = ''; + if (address.indexOf('://') > -1) { + // other uri format + host = address.replace(/ /g,'').split('://')[1]; + } else { + // useraddress + host = address.replace(/ /g,'').split('@')[1]; + } var uri_index = 0; // track which URIS we've tried already var protocol = 'https'; // we use https by default - if (parts.length !== 2) { - return cb(generateErrorObject({ message: 'invalid user address ' + address + ' ( expected format: user@host.com )' })); - } else if (self.__isLocalhost(host)) { + if (self.__isLocalhost(host)) { protocol = 'http'; } function __buildURL() { + var uri = ''; + if (! address.split('://')[1]) { + // the URI has not been defined, default to acct + uri = 'acct:'; + } return protocol + '://' + host + '/.well-known/' + - URIS[uri_index] + '?resource=acct:' + address; + URIS[uri_index] + '?resource=' + uri + address; } // control flow for failures, what to do in various cases, etc. @@ -2374,12 +2429,13 @@ if (typeof XMLHttpRequest === 'undefined') { // (stored somewhere in control of the user) // 3. make a request to that url and get the json // 4. process it like a normal webfinger response - self.__fetchJRD(__buildURL(), cb, function (data) { // get link to users JRD - self.__processJRD(data, cb, function (result) { + var URL = __buildURL(); + self.__fetchJRD(URL, cb, function (data) { // get link to users JRD + self.__processJRD(URL, data, cb, function (result) { if ((typeof result.idx.links.webfist === 'object') && (typeof result.idx.links.webfist[0].href === 'string')) { self.__fetchJRD(result.idx.links.webfist[0].href, cb, function (JRD) { - self.__processJRD(JRD, cb, function (result) { + self.__processJRD(URL, JRD, cb, function (result) { return cb(null, cb); }); }); @@ -2393,8 +2449,9 @@ if (typeof XMLHttpRequest === 'undefined') { function __call() { // make request - self.__fetchJRD(__buildURL(), __fallbackChecks, function (JRD) { - self.__processJRD(JRD, cb, function (result) { cb(null, result); }); + var URL = __buildURL(); + self.__fetchJRD(URL, __fallbackChecks, function (JRD) { + self.__processJRD(URL, JRD, cb, function (result) { cb(null, result); }); }); } @@ -3134,10 +3191,10 @@ RemoteStorage.Assets = { return typeof(document) !== 'undefined'; }; - function stateSetter(widget, state) { + function stateSetter(widget, state, message) { RemoteStorage.log('[Widget] Producing stateSetter for', state); return function () { - RemoteStorage.log('[Widget] Setting state', state, arguments); + RemoteStorage.log('[Widget] Setting state', state, message); if (hasLocalStorage) { localStorage[LS_STATE_KEY] = state; } @@ -3145,7 +3202,7 @@ RemoteStorage.Assets = { if (widget.rs.remote) { widget.view.setUserAddress(widget.rs.remote.userAddress); } - widget.view.setState(state, arguments); + widget.view.setState(state, message); } else { widget._rememberedState = state; } @@ -3157,9 +3214,9 @@ RemoteStorage.Assets = { var s; if (error instanceof RemoteStorage.DiscoveryError) { console.error('Discovery failed', error, '"' + error.message + '"'); - s = stateSetter(widget, 'initial', [error.message]); + s = stateSetter(widget, 'initial', error.message); } else if (error instanceof RemoteStorage.SyncError) { - s = stateSetter(widget, 'offline', []); + s = stateSetter(widget, 'offline'); } else if (error instanceof RemoteStorage.Unauthorized) { s = stateSetter(widget, 'unauthorized'); } else { @@ -3250,13 +3307,13 @@ RemoteStorage.Assets = { * state * args **/ - setState: function (state, args) { - RemoteStorage.log('[View] widget.view.setState(',state,',',args,');'); + setState: function (state, message) { + RemoteStorage.log('[View] widget.view.setState(',state,',',message,');'); var s = this.states[state]; if (typeof(s) === 'undefined') { throw new Error("Bad State assigned to view: " + state); } - s.apply(this, args); + s.apply(this, [message]); }, /** @@ -7359,7 +7416,6 @@ Math.uuid = function (len, radix) { error = new RemoteStorage.Unauthorized(); } else if (status.networkProblems) { error = new RemoteStorage.SyncError('Network request failed.'); - this.remote.online = false; } else { error = new Error('HTTP response code ' + status.statusCode + ' received.'); } @@ -7390,7 +7446,6 @@ Math.uuid = function (len, radix) { .then(function (completed) { delete self._timeStarted[task.path]; delete self._running[task.path]; - self.remote.online = true; if (completed) { if (self._tasks[task.path]) { @@ -8975,6 +9030,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -9340,15 +9397,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); + } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); } - return xhr; + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -9425,6 +9512,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -9993,15 +10082,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -10080,8 +10203,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -10229,7 +10352,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -10238,6 +10361,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -10248,7 +10372,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/stable/remotestorage.js b/release/stable/remotestorage.js index 0f19e1b84..b5ebcaa9d 100644 --- a/release/stable/remotestorage.js +++ b/release/stable/remotestorage.js @@ -1,4 +1,4 @@ -/** remotestorage.js 0.13.0, http://remotestorage.io, MIT-licensed **/ +/** remotestorage.js 0.14.0, http://remotestorage.io, MIT-licensed **/ /** FILE: lib/bluebird.js **/ /** @@ -3441,6 +3441,18 @@ module.exports = ret; * * Fired when a wire request completes **/ + /** + * Event: network-offline + * + * Fired once when a wire request fails for the first time, and + * `remote.online` is set to false + **/ + /** + * Event: network-online + * + * Fired once when a wire request succeeds for the first time after a + * failed one, and `remote.online` is set back to true + **/ // Initial configuration property settings. if (typeof cfg === 'object') { @@ -3450,8 +3462,9 @@ module.exports = ret; RemoteStorage.eventHandling( this, 'ready', 'connected', 'disconnected', 'not-connected', 'conflict', - 'error', 'features-loaded', 'connecting', 'authing', 'wire-busy', - 'wire-done', 'sync-interval-change' + 'error', 'features-loaded', 'connecting', 'authing', + 'sync-interval-change', 'wire-busy', 'wire-done', + 'network-offline', 'network-online' ); // pending get/put/delete calls. @@ -3586,6 +3599,20 @@ module.exports = ret; * remoteStorage.scope('/public/pictures/').getListing(''); */ + /** + * Method: startSync + * + * Start synchronization with remote storage, downloading and uploading any + * changes within the cached paths. + * + * Please consider: local changes will attempt sync immediately, and remote + * changes should also be synced timely when using library defaults. So + * this is mostly useful for letting users sync manually, when pressing a + * sync button for example. This might feel safer to them sometimes, esp. + * when shifting between offline and online a lot. + */ + // (see src/sync.js for implementation) + /** * Method: connect * @@ -3638,7 +3665,7 @@ module.exports = ret; this._emit('connecting'); var discoveryTimeout = setTimeout(function () { - this._emit('error', new RemoteStorage.DiscoveryError("No storage information found at that user address.")); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this), RemoteStorage.config.discoveryTimeout); RemoteStorage.Discover(userAddress).then(function (info) { @@ -3670,7 +3697,8 @@ module.exports = ret; } } }.bind(this), function(err) { - this._emit('error', new RemoteStorage.DiscoveryError("Failed to contact storage server.")); + clearTimeout(discoveryTimeout); + this._emit('error', new RemoteStorage.DiscoveryError("No storage information found for this user address.")); }.bind(this)); }, @@ -4886,6 +4914,7 @@ module.exports = ret; * Class : RemoteStorage.WireClient **/ RS.WireClient = function (rs) { + this.rs = rs; this.connected = false; /** @@ -4897,7 +4926,8 @@ module.exports = ret; * Fired when the wireclient connect method realizes that it is in * possession of a token and href **/ - RS.eventHandling(this, 'change', 'connected', 'wire-busy', 'wire-done', 'not-connected'); + RS.eventHandling(this, 'change', 'connected', 'not-connected', + 'wire-busy', 'wire-done'); onErrorCb = function (error){ if (error instanceof RemoteStorage.Unauthorized) { @@ -4983,13 +5013,17 @@ module.exports = ret; body: body, headers: headers, responseType: 'arraybuffer' - }).then(function (response) { + }).then(function(response) { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: true }); - self.online = true; + if (isErrorStatus(response.status)) { RemoteStorage.log('[WireClient] Error response status', response.status); if (getEtag) { @@ -5025,11 +5059,16 @@ module.exports = ret; } } }, function (error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } self._emit('wire-done', { method: method, isFolder: isFolder(uri), success: false }); + return Promise.reject(error); }); }, @@ -5330,7 +5369,7 @@ module.exports = ret; webFinger.lookup(userAddress, function (err, response) { if (err) { - return pending.reject(err.message); + return pending.reject(err); } else if ((typeof response.idx.links.remotestorage !== 'object') || (typeof response.idx.links.remotestorage.length !== 'number') || (response.idx.links.remotestorage.length <= 0)) { @@ -5386,11 +5425,11 @@ module.exports = ret; /* global define */ /*! * webfinger.js - * version 2.3.2 + * version 2.4.2 * http://github.com/silverbucket/webfinger.js * * Developed and Maintained by: - * Nick Jennings 2012 - 2014 + * Nick Jennings 2012 - 2016 * * webfinger.js is released under the AGPL (see LICENSE). * @@ -5447,7 +5486,7 @@ if (typeof XMLHttpRequest === 'undefined') { return obj; } - // given a URL ensures it's HTTPS. + // given a URL ensures it's HTTPS. // returns false for null string or non-HTTPS URL. function isSecure(url) { if (typeof url !== 'string') { @@ -5484,56 +5523,64 @@ if (typeof XMLHttpRequest === 'undefined') { // make an http request and look for JRD response, fails if request fails // or response not json. - WebFinger.prototype.__fetchJRD = function (_url, errorHandler, sucessHandler) { + WebFinger.prototype.__fetchJRD = function (url, errorHandler, sucessHandler) { var self = this; - function __makeRequest(url) { - var xhr = new XMLHttpRequest(); - + + var xhr = new XMLHttpRequest(); + + function __processState() { + if (xhr.status === 200) { + if (self.__isValidJSON(xhr.responseText)) { + return sucessHandler(xhr.responseText); + } else { + return errorHandler(generateErrorObject({ + message: 'invalid json', + url: url, + status: xhr.status + })); + } + } else if (xhr.status === 404) { + return errorHandler(generateErrorObject({ + message: 'resource not found', + url: url, + status: xhr.status + })); + } else if ((xhr.status >= 301) && (xhr.status <= 302)) { + var location = xhr.getResponseHeader('Location'); + if (isSecure(location)) { + return __makeRequest(location); // follow redirect + } else { + return errorHandler(generateErrorObject({ + message: 'no redirect URL found', + url: url, + status: xhr.status + })); + } + } else { + return errorHandler(generateErrorObject({ + message: 'error during request', + url: url, + status: xhr.status + })); + } + } + + function __makeRequest() { xhr.onreadystatechange = function () { if (xhr.readyState === 4) { - if (xhr.status === 200) { - if (self.__isValidJSON(xhr.responseText)) { - return sucessHandler(xhr.responseText); - } else { - return errorHandler(generateErrorObject({ - message: 'invalid json', - url: url, - status: xhr.status - })); - } - } else if (xhr.status === 404) { - return errorHandler(generateErrorObject({ - message: 'endpoint unreachable', - url: url, - status: xhr.status - })); - } else if ((xhr.status >= 301) && (xhr.status <= 302)) { - var location = xhr.getResponseHeader('Location'); - if (isSecure(location)) { - return __makeRequest(location); // follow redirect - } else { - return errorHandler(generateErrorObject({ - message: 'no redirect URL found', - url: url, - status: xhr.status - })); - } - } else { - return errorHandler(generateErrorObject({ - message: 'error during request', - url: url, - status: xhr.status - })); - } + __processState(); } }; - + + xhr.onload = function (a, b) { + __processState(); + } xhr.open('GET', url, true); xhr.setRequestHeader('Accept', 'application/jrd+json, application/json'); xhr.send(); } - - return __makeRequest(_url); + + return __makeRequest(); }; WebFinger.prototype.__isValidJSON = function (str) { @@ -5552,16 +5599,15 @@ if (typeof XMLHttpRequest === 'undefined') { // processes JRD object as if it's a webfinger response object // looks for known properties and adds them to profile datat struct. - WebFinger.prototype.__processJRD = function (JRD, errorHandler, successHandler) { + WebFinger.prototype.__processJRD = function (URL, JRD, errorHandler, successHandler) { var parsedJRD = JSON.parse(JRD); if ((typeof parsedJRD !== 'object') || (typeof parsedJRD.links !== 'object')) { if (typeof parsedJRD.error !== 'undefined') { - return errorHandler(generateErrorObject({ message: parsedJRD.error })); + return errorHandler(generateErrorObject({ message: parsedJRD.error, request: URL })); } else { - return errorHandler(generateErrorObject({ message: 'unknown response from server' })); + return errorHandler(generateErrorObject({ message: 'unknown response from server', request: URL })); } - return false; } var links = parsedJRD.links; @@ -5609,20 +5655,29 @@ if (typeof XMLHttpRequest === 'undefined') { } var self = this; - var parts = address.replace(/ /g,'').split('@'); - var host = parts[1]; // host name for this useraddress + var host = ''; + if (address.indexOf('://') > -1) { + // other uri format + host = address.replace(/ /g,'').split('://')[1]; + } else { + // useraddress + host = address.replace(/ /g,'').split('@')[1]; + } var uri_index = 0; // track which URIS we've tried already var protocol = 'https'; // we use https by default - if (parts.length !== 2) { - return cb(generateErrorObject({ message: 'invalid user address ' + address + ' ( expected format: user@host.com )' })); - } else if (self.__isLocalhost(host)) { + if (self.__isLocalhost(host)) { protocol = 'http'; } function __buildURL() { + var uri = ''; + if (! address.split('://')[1]) { + // the URI has not been defined, default to acct + uri = 'acct:'; + } return protocol + '://' + host + '/.well-known/' + - URIS[uri_index] + '?resource=acct:' + address; + URIS[uri_index] + '?resource=' + uri + address; } // control flow for failures, what to do in various cases, etc. @@ -5644,12 +5699,13 @@ if (typeof XMLHttpRequest === 'undefined') { // (stored somewhere in control of the user) // 3. make a request to that url and get the json // 4. process it like a normal webfinger response - self.__fetchJRD(__buildURL(), cb, function (data) { // get link to users JRD - self.__processJRD(data, cb, function (result) { + var URL = __buildURL(); + self.__fetchJRD(URL, cb, function (data) { // get link to users JRD + self.__processJRD(URL, data, cb, function (result) { if ((typeof result.idx.links.webfist === 'object') && (typeof result.idx.links.webfist[0].href === 'string')) { self.__fetchJRD(result.idx.links.webfist[0].href, cb, function (JRD) { - self.__processJRD(JRD, cb, function (result) { + self.__processJRD(URL, JRD, cb, function (result) { return cb(null, cb); }); }); @@ -5663,8 +5719,9 @@ if (typeof XMLHttpRequest === 'undefined') { function __call() { // make request - self.__fetchJRD(__buildURL(), __fallbackChecks, function (JRD) { - self.__processJRD(JRD, cb, function (result) { cb(null, result); }); + var URL = __buildURL(); + self.__fetchJRD(URL, __fallbackChecks, function (JRD) { + self.__processJRD(URL, JRD, cb, function (result) { cb(null, result); }); }); } @@ -6404,10 +6461,10 @@ RemoteStorage.Assets = { return typeof(document) !== 'undefined'; }; - function stateSetter(widget, state) { + function stateSetter(widget, state, message) { RemoteStorage.log('[Widget] Producing stateSetter for', state); return function () { - RemoteStorage.log('[Widget] Setting state', state, arguments); + RemoteStorage.log('[Widget] Setting state', state, message); if (hasLocalStorage) { localStorage[LS_STATE_KEY] = state; } @@ -6415,7 +6472,7 @@ RemoteStorage.Assets = { if (widget.rs.remote) { widget.view.setUserAddress(widget.rs.remote.userAddress); } - widget.view.setState(state, arguments); + widget.view.setState(state, message); } else { widget._rememberedState = state; } @@ -6427,9 +6484,9 @@ RemoteStorage.Assets = { var s; if (error instanceof RemoteStorage.DiscoveryError) { console.error('Discovery failed', error, '"' + error.message + '"'); - s = stateSetter(widget, 'initial', [error.message]); + s = stateSetter(widget, 'initial', error.message); } else if (error instanceof RemoteStorage.SyncError) { - s = stateSetter(widget, 'offline', []); + s = stateSetter(widget, 'offline'); } else if (error instanceof RemoteStorage.Unauthorized) { s = stateSetter(widget, 'unauthorized'); } else { @@ -6520,13 +6577,13 @@ RemoteStorage.Assets = { * state * args **/ - setState: function (state, args) { - RemoteStorage.log('[View] widget.view.setState(',state,',',args,');'); + setState: function (state, message) { + RemoteStorage.log('[View] widget.view.setState(',state,',',message,');'); var s = this.states[state]; if (typeof(s) === 'undefined') { throw new Error("Bad State assigned to view: " + state); } - s.apply(this, args); + s.apply(this, [message]); }, /** @@ -10629,7 +10686,6 @@ Math.uuid = function (len, radix) { error = new RemoteStorage.Unauthorized(); } else if (status.networkProblems) { error = new RemoteStorage.SyncError('Network request failed.'); - this.remote.online = false; } else { error = new Error('HTTP response code ' + status.statusCode + ' received.'); } @@ -10660,7 +10716,6 @@ Math.uuid = function (len, radix) { .then(function (completed) { delete self._timeStarted[task.path]; delete self._running[task.path]; - self.remote.online = true; if (completed) { if (self._tasks[task.path]) { @@ -12245,6 +12300,8 @@ Math.uuid = function (len, radix) { var GD_DIR_MIME_TYPE = 'application/vnd.google-apps.folder'; var RS_DIR_MIME_TYPE = 'application/json; charset=UTF-8'; + var isFolder = RemoteStorage.util.isFolder; + function buildQueryString(params) { return Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); @@ -12610,15 +12667,45 @@ Math.uuid = function (len, radix) { _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + self.token; - return RS.WireClient.request(method, url, options).then(function (xhr) { - // google tokens expire from time to time... + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // Google tokens expire from time to time... if (xhr && xhr.status === 401) { self.connect(); return; + } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + + return Promise.resolve(xhr); + } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); } - return xhr; + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); } }; @@ -12695,6 +12782,8 @@ Math.uuid = function (len, radix) { var SETTINGS_KEY = 'remotestorage:dropbox'; var PATH_PREFIX = '/remotestorage'; + var isFolder = RemoteStorage.util.isFolder; + /** * Function: getDropboxPath(path) * @@ -13263,15 +13352,49 @@ Math.uuid = function (len, radix) { */ _request: function (method, url, options) { var self = this; + if (! options.headers) { options.headers = {}; } options.headers['Authorization'] = 'Bearer ' + this.token; - return RS.WireClient.request.call(this, method, url, options).then(function (xhr) { - //503 means retry this later + + this._emit('wire-busy', { + method: method, + isFolder: isFolder(url) + }); + + return RS.WireClient.request.call(this, method, url, options).then(function(xhr) { + // 503 means retry this later if (xhr && xhr.status === 503) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + return global.setTimeout(self._request(method, url, options), 3210); } else { + if (!self.online) { + self.online = true; + self.rs._emit('network-online'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: true + }); + return Promise.resolve(xhr); } + }, function(error) { + if (self.online) { + self.online = false; + self.rs._emit('network-offline'); + } + self._emit('wire-done', { + method: method, + isFolder: isFolder(url), + success: false + }); + + return Promise.reject(error); }); }, @@ -13350,8 +13473,8 @@ Math.uuid = function (len, radix) { }, function (err) { this.rs.log('fetchDeltas', err); this.rs._emit('error', new RemoteStorage.SyncError('fetchDeltas failed.' + err)); - promise.reject(err); - }).then(function () { + return Promise.resolve(args); + }.bind(this)).then(function () { if (self._revCache) { var args = Array.prototype.slice.call(arguments); self._revCache._activatePropagation(); @@ -13499,7 +13622,7 @@ Math.uuid = function (len, radix) { } }; - //hooking and unhooking the sync + // Hooking and unhooking the sync function hookSync(rs) { if (rs._dropboxOrigSync) { return; } // already hooked @@ -13508,6 +13631,7 @@ Math.uuid = function (len, radix) { return this.dropbox.fetchDelta.apply(this.dropbox, arguments). then(rs._dropboxOrigSync, function (err) { rs._emit('error', new RemoteStorage.SyncError(err)); + return Promise.reject(err); }); }.bind(rs); } @@ -13518,7 +13642,7 @@ Math.uuid = function (len, radix) { delete rs._dropboxOrigSync; } - // hooking and unhooking getItemURL + // Hooking and unhooking getItemURL function hookGetItemURL(rs) { if (rs._origBaseClientGetItemURL) { return; } diff --git a/release/stable/remotestorage.min.js b/release/stable/remotestorage.min.js index 343d418a5..2cbe3751e 100644 --- a/release/stable/remotestorage.min.js +++ b/release/stable/remotestorage.min.js @@ -1,10 +1,10 @@ -/** remotestorage.js 0.13.0, http://remotestorage.io, MIT-licensed **/ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o0},Async.prototype.invokeLater=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn)),this._lateBuffer.push(fn,receiver,arg),this._queueTick()},Async.prototype.invoke=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn));var functionBuffer=this._functionBuffer;functionBuffer.push(fn,receiver,arg),this._length=functionBuffer.length(),this._queueTick()},Async.prototype._consumeFunctionBuffer=function(){for(var functionBuffer=this._functionBuffer;functionBuffer.length()>0;){var fn=functionBuffer.shift(),receiver=functionBuffer.shift(),arg=functionBuffer.shift();fn.call(receiver,arg)}this._reset(),this._consumeLateBuffer()},Async.prototype._consumeLateBuffer=function(){for(var buffer=this._lateBuffer;buffer.length()>0;){var fn=buffer.shift(),receiver=buffer.shift(),arg=buffer.shift(),res=tryCatch1(fn,receiver,arg);if(res===errorObj){if(this._queueTick(),null==fn.domain)throw res.e;fn.domain.emit("error",res.e)}}},Async.prototype._queueTick=function(){this._isTickUsed||(this._schedule(this.consumeFunctionBuffer),this._isTickUsed=!0)},Async.prototype._reset=function(){this._isTickUsed=!1,this._length=0},module.exports=new Async},{"./queue.js":15,"./schedule.js":16,"./util.js":19}],2:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise.js")();module.exports=Promise},{"./promise.js":12}],3:[function(_dereq_,module,exports){"use strict";module.exports=function(){function formatNonError(obj){var str;if("function"==typeof obj)str="[function "+(obj.name||"anonymous")+"]";else{str=obj.toString();var ruselessToString=/\[object [a-zA-Z0-9$_]+\]/;if(ruselessToString.test(str))try{var newStr=JSON.stringify(obj);str=newStr}catch(e){}0===str.length&&(str="(empty array)")}return"(<"+snip(str)+">, no stack trace)"}function snip(str){var maxChars=41;return str.length=0;--i){var line=prev[i];if(current[curLast]!==line)break;current.pop(),curLast--}current.push("From previous event:");for(var lines=current.concat(prev),ret=[],i=0,len=lines.length;len>i;++i)rignore.test(lines[i])&&rtraceline.test(lines[i])||i>0&&!rtraceline.test(lines[i])&&"From previous event:"!==lines[i]||ret.push(lines[i]);return ret},CapturedTrace.protectErrorMessageNewlines=function(stack){for(var i=0;i=i)){for(var errorMessageLines=[],j=0;i>j;++j)errorMessageLines.push(stack.shift());stack.unshift(errorMessageLines.join("\x00"))}},CapturedTrace.isSupported=function(){return"function"==typeof captureStackTrace};var captureStackTrace=function stackDetection(){if("number"==typeof Error.stackTraceLimit&&"function"==typeof Error.captureStackTrace){rtraceline=/^\s*at\s*/,formatStack=function(stack,error){return"string"==typeof stack?stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)};var captureStackTrace=Error.captureStackTrace;return function(receiver,ignoreUntil){captureStackTrace(receiver,ignoreUntil)}}var err=new Error;if("string"==typeof err.stack&&"function"==typeof"".startsWith&&err.stack.startsWith("stackDetection@")&&"stackDetection"===stackDetection.name){defineProperty(Error,"stackTraceLimit",{writable:!0,enumerable:!1,configurable:!1,value:25}),rtraceline=/@/;var rline=/[@\n]/;return formatStack=function(stack,error){return"string"==typeof stack?error.name+". "+error.message+"\n"+stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)},function(o){for(var stack=(new Error).stack,split=stack.split(rline),len=split.length,ret="",i=0;len>i;i+=2)ret+=split[i],ret+="@",ret+=split[i+1],ret+="\n";o.stack=ret}}return formatStack=function(stack,error){return"string"==typeof stack?stack:"object"!=typeof error&&"function"!=typeof error||void 0===error.name||void 0===error.message?formatNonError(error):error.name+". "+error.message},null}();return CapturedTrace}},{"./es5.js":8,"./util.js":19}],4:[function(_dereq_,module,exports){"use strict";module.exports=function(NEXT_FILTER){function CatchFilter(instances,callback,promise){this._instances=instances,this._callback=callback,this._promise=promise}function CatchFilter$_safePredicate(predicate,e){var safeObject={},retfilter=tryCatch1(predicate,safeObject,e);if(retfilter===errorObj)return retfilter;var safeKeys=keys(safeObject);return safeKeys.length?(errorObj.e=new TypeError("Catch filter must inherit from Error or be a simple predicate function"),errorObj):retfilter}var util=_dereq_("./util.js"),errors=_dereq_("./errors.js"),tryCatch1=util.tryCatch1,errorObj=util.errorObj,keys=_dereq_("./es5.js").keys,TypeError=errors.TypeError;return CatchFilter.prototype.doFilter=function(e){for(var cb=this._callback,promise=this._promise,boundTo=promise._boundTo,i=0,len=this._instances.length;len>i;++i){var item=this._instances[i],itemIsErrorType=item===Error||null!=item&&item.prototype instanceof Error;if(itemIsErrorType&&e instanceof item){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}if("function"==typeof item&&!itemIsErrorType){var shouldHandle=CatchFilter$_safePredicate(item,e);if(shouldHandle===errorObj){var trace=errors.canAttach(errorObj.e)?errorObj.e:new Error(errorObj.e+"");this._promise._attachExtraTrace(trace),e=errorObj.e;break}if(shouldHandle){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}}}return NEXT_FILTER.e=e,NEXT_FILTER},CatchFilter}},{"./errors.js":6,"./es5.js":8,"./util.js":19}],5:[function(_dereq_,module,exports){"use strict";var util=_dereq_("./util.js"),isPrimitive=util.isPrimitive,wrapsPrimitiveReceiver=util.wrapsPrimitiveReceiver;module.exports=function(Promise){var returner=function(){return this},thrower=function(){throw this},wrapper=function(value,action){return 1===action?function(){throw value}:2===action?function(){return value}:void 0};Promise.prototype["return"]=Promise.prototype.thenReturn=function(value){return wrapsPrimitiveReceiver&&isPrimitive(value)?this._then(wrapper(value,2),void 0,void 0,void 0,void 0):this._then(returner,void 0,void 0,value,void 0)},Promise.prototype["throw"]=Promise.prototype.thenThrow=function(reason){return wrapsPrimitiveReceiver&&isPrimitive(reason)?this._then(wrapper(reason,1),void 0,void 0,void 0,void 0):this._then(thrower,void 0,void 0,reason,void 0)}}},{"./util.js":19}],6:[function(_dereq_,module,exports){"use strict";function markAsOriginatingFromRejection(e){try{notEnumerableProp(e,"isOperational",!0)}catch(ignore){}}function originatesFromRejection(e){return null==e?!1:e instanceof OperationalError||e.isOperational===!0}function isError(obj){return obj instanceof Error}function canAttach(obj){return isError(obj)}function subError(nameProperty,defaultMessage){function SubError(message){return this instanceof SubError?(this.message="string"==typeof message?message:defaultMessage,this.name=nameProperty,void(Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor))):new SubError(message)}return inherits(SubError,Error),SubError}function OperationalError(message){this.name="OperationalError",this.message=message,this.cause=message,this.isOperational=!0,message instanceof Error?(this.message=message.message,this.stack=message.stack):Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}var _TypeError,_RangeError,Objectfreeze=_dereq_("./es5.js").freeze,util=_dereq_("./util.js"),inherits=util.inherits,notEnumerableProp=util.notEnumerableProp,CancellationError=subError("CancellationError","cancellation error"),TimeoutError=subError("TimeoutError","timeout error"),AggregateError=subError("AggregateError","aggregate error");try{_TypeError=TypeError,_RangeError=RangeError}catch(e){_TypeError=subError("TypeError","type error"),_RangeError=subError("RangeError","range error")}for(var methods="join pop push shift unshift slice filter forEach some every map indexOf lastIndexOf reduce reduceRight sort reverse".split(" "),i=0;i=i;++i)values.push("holder.p"+i);return new Function("holder"," \n 'use strict'; \n var callback = holder.fn; \n return callback(values); \n ".replace(/values/g,values.join(", ")))},thenCallbacks=[],callers=[void 0],i=1;5>=i;++i)thenCallbacks.push(thenCallback(i)),callers.push(caller(i));var Holder=function(total,fn){this.p1=this.p2=this.p3=this.p4=this.p5=null,this.fn=fn,this.total=total,this.now=0};Holder.prototype.callers=callers,Holder.prototype.checkFulfillment=function(promise){var now=this.now;now++;var total=this.total;if(now>=total){var handler=this.callers[total],ret=tryCatch1(handler,void 0,this);ret===errorObj?promise._rejectUnchecked(ret.e):promise._tryFollow(ret)||promise._fulfillUnchecked(ret)}else this.now=now}}Promise.join=function(){var fn,last=arguments.length-1;if(last>0&&"function"==typeof arguments[last]&&(fn=arguments[last],6>last&&canEvaluate)){var ret=new Promise(INTERNAL);ret._setTrace(void 0);for(var holder=new Holder(last,fn),reject=ret._reject,callbacks=thenCallbacks,i=0;last>i;++i){var maybePromise=cast(arguments[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._then(callbacks[i],reject,void 0,ret,holder):maybePromise.isFulfilled()?callbacks[i].call(ret,maybePromise._settledValue,holder):(ret._reject(maybePromise._settledValue),maybePromise._unsetRejectionIsUnhandled()):callbacks[i].call(ret,maybePromise,holder)}return ret}for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];var ret=new PromiseArray(args).promise();return void 0!==fn?ret.spread(fn):ret}}},{"./util.js":19}],11:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function thrower(r){throw r}function Promise$_spreadAdapter(val,receiver){if(!util.isArray(val))return Promise$_successAdapter(val,receiver);var ret=util.tryCatchApply(this,[null].concat(val),receiver);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_successAdapter(val,receiver){var nodeback=this,ret=void 0===val?tryCatch1(nodeback,receiver,null):tryCatch2(nodeback,receiver,null,val);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_errorAdapter(reason,receiver){var nodeback=this,ret=tryCatch1(nodeback,receiver,reason);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),tryCatch2=util.tryCatch2,tryCatch1=util.tryCatch1,errorObj=util.errorObj;Promise.prototype.nodeify=function(nodeback,options){if("function"==typeof nodeback){var adapter=Promise$_successAdapter;void 0!==options&&Object(options).spread&&(adapter=Promise$_spreadAdapter),this._then(adapter,Promise$_errorAdapter,void 0,nodeback,this._boundTo)}return this}}},{"./async.js":1,"./util.js":19}],12:[function(_dereq_,module,exports){"use strict";function noConflict(bluebird){try{Promise===bluebird&&(Promise=old)}catch(e){}return bluebird}var old;"undefined"!=typeof Promise&&(old=Promise),module.exports=function(){function Promise(resolver){if("function"!=typeof resolver)throw new TypeError("the promise constructor requires a resolver function");if(this.constructor!==Promise)throw new TypeError("the promise constructor cannot be invoked directly");this._bitField=0,this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0,this._settledValue=void 0,this._boundTo=void 0,resolver!==INTERNAL&&this._resolveFromResolver(resolver)}function returnFirstElement(elements){return elements[0]}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),errors=_dereq_("./errors.js"),INTERNAL=function(){},APPLY={},NEXT_FILTER={e:null},cast=_dereq_("./thenables.js")(Promise,INTERNAL),PromiseArray=_dereq_("./promise_array.js")(Promise,INTERNAL,cast),CapturedTrace=_dereq_("./captured_trace.js")(),CatchFilter=_dereq_("./catch_filter.js")(NEXT_FILTER),PromiseResolver=_dereq_("./promise_resolver.js"),isArray=util.isArray,errorObj=util.errorObj,tryCatch1=util.tryCatch1,tryCatch2=util.tryCatch2,tryCatchApply=util.tryCatchApply,RangeError=errors.RangeError,TypeError=errors.TypeError,CancellationError=errors.CancellationError,TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,originatesFromRejection=errors.originatesFromRejection,markAsOriginatingFromRejection=errors.markAsOriginatingFromRejection,canAttach=errors.canAttach,thrower=util.thrower,apiRejection=_dereq_("./errors_api_rejection")(Promise),makeSelfResolutionError=function(){return new TypeError("circular promise resolution chain")};Promise.prototype.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(maybePromise instanceof Promise){var binder=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)}),p=Promise.all([this,binder]).then(returnFirstElement);ret._follow(p)}else ret._follow(this),ret._setBoundTo(thisArg);return ret._propagateFrom(this,3),ret},Promise.prototype.toString=function(){return"[object Promise]"},Promise.prototype.caught=Promise.prototype["catch"]=function(fn){var len=arguments.length;if(len>1){var i,catchInstances=new Array(len-1),j=0;for(i=0;len-1>i;++i){var item=arguments[i];if("function"!=typeof item){var catchFilterTypeError=new TypeError("A catch filter must be an error constructor or a filter function");return this._attachExtraTrace(catchFilterTypeError),Promise.reject(catchFilterTypeError)}catchInstances[j++]=item}catchInstances.length=j,fn=arguments[i],this._resetTrace();var catchFilter=new CatchFilter(catchInstances,fn,this);return this._then(void 0,catchFilter.doFilter,void 0,catchFilter,void 0)}return this._then(void 0,fn,void 0,void 0,void 0)},Promise.prototype.then=function(didFulfill,didReject,didProgress){return this._then(didFulfill,didReject,didProgress,void 0,void 0)},Promise.prototype.done=function(didFulfill,didReject,didProgress){var promise=this._then(didFulfill,didReject,didProgress,void 0,void 0);promise._setIsFinal()},Promise.prototype.spread=function(didFulfill,didReject){return this._then(didFulfill,didReject,void 0,APPLY,void 0)},Promise.prototype.isCancellable=function(){return!this.isResolved()&&this._cancellable()},Promise.prototype.toJSON=function(){var ret={isFulfilled:!1,isRejected:!1,fulfillmentValue:void 0,rejectionReason:void 0};return this.isFulfilled()?(ret.fulfillmentValue=this._settledValue,ret.isFulfilled=!0):this.isRejected()&&(ret.rejectionReason=this._settledValue,ret.isRejected=!0),ret},Promise.prototype.all=function(){return new PromiseArray(this).promise()},Promise.is=function(val){return val instanceof Promise},Promise.all=function(promises){return new PromiseArray(promises).promise()},Promise.prototype.error=function(fn){return this.caught(originatesFromRejection,fn)},Promise.prototype._resolveFromSyncValue=function(value){if(value===errorObj)this._cleanValues(),this._setRejected(),this._settledValue=value.e,this._ensurePossibleRejectionHandled();else{var maybePromise=cast(value,void 0);maybePromise instanceof Promise?this._follow(maybePromise):(this._cleanValues(),this._setFulfilled(),this._settledValue=value)}},Promise.method=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");return function(){var value;switch(arguments.length){case 0:value=tryCatch1(fn,this,void 0);break;case 1:value=tryCatch1(fn,this,arguments[0]);break;case 2:value=tryCatch2(fn,this,arguments[0],arguments[1]);break;default:for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];value=tryCatchApply(fn,args,this)}var ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret}},Promise.attempt=Promise["try"]=function(fn,args,ctx){if("function"!=typeof fn)return apiRejection("fn must be a function");var value=isArray(args)?tryCatchApply(fn,args,ctx):tryCatch1(fn,ctx,args),ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret},Promise.defer=Promise.pending=function(){var promise=new Promise(INTERNAL);return promise._setTrace(void 0),new PromiseResolver(promise)},Promise.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(ret._setTrace(void 0),maybePromise instanceof Promise){var p=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)});ret._follow(p)}else ret._setBoundTo(thisArg),ret._setFulfilled();return ret},Promise.cast=function(obj){var ret=cast(obj,void 0);if(!(ret instanceof Promise)){var val=ret;ret=new Promise(INTERNAL),ret._setTrace(void 0),ret._setFulfilled(),ret._cleanValues(),ret._settledValue=val}return ret},Promise.resolve=Promise.fulfilled=Promise.cast,Promise.reject=Promise.rejected=function(reason){var ret=new Promise(INTERNAL);if(ret._setTrace(void 0),markAsOriginatingFromRejection(reason),ret._cleanValues(),ret._setRejected(),ret._settledValue=reason,!canAttach(reason)){var trace=new Error(reason+"");ret._setCarriedStackTrace(trace)}return ret._ensurePossibleRejectionHandled(),ret},Promise.onPossiblyUnhandledRejection=function(fn){CapturedTrace.possiblyUnhandledRejection="function"==typeof fn?fn:void 0};var unhandledRejectionHandled;Promise.onUnhandledRejectionHandled=function(fn){unhandledRejectionHandled="function"==typeof fn?fn:void 0};var debugging=!("undefined"==typeof process||"string"!=typeof process.execPath||"object"!=typeof process.env||!process.env.BLUEBIRD_DEBUG&&"development"!==process.env.NODE_ENV);Promise.longStackTraces=function(){if(async.haveItemsQueued()&&debugging===!1)throw new Error("cannot enable long stack traces after promises have been created");debugging=CapturedTrace.isSupported()},Promise.hasLongStackTraces=function(){return debugging&&CapturedTrace.isSupported()},Promise.prototype._then=function(didFulfill,didReject,didProgress,receiver,internalData){var haveInternalData=void 0!==internalData,ret=haveInternalData?internalData:new Promise(INTERNAL);if(!haveInternalData){if(debugging){var haveSameContext=this._peekContext()===this._traceParent;ret._traceParent=haveSameContext?this._traceParent:this}ret._propagateFrom(this,7)}var callbackIndex=this._addCallbacks(didFulfill,didReject,didProgress,ret,receiver);return this.isResolved()&&async.invoke(this._queueSettleAt,this,callbackIndex),ret},Promise.prototype._length=function(){return 262143&this._bitField},Promise.prototype._isFollowingOrFulfilledOrRejected=function(){return(939524096&this._bitField)>0},Promise.prototype._isFollowing=function(){return 536870912===(536870912&this._bitField)},Promise.prototype._setLength=function(len){this._bitField=-262144&this._bitField|262143&len},Promise.prototype._setFulfilled=function(){this._bitField=268435456|this._bitField},Promise.prototype._setRejected=function(){this._bitField=134217728|this._bitField},Promise.prototype._setFollowing=function(){this._bitField=536870912|this._bitField},Promise.prototype._setIsFinal=function(){this._bitField=33554432|this._bitField},Promise.prototype._isFinal=function(){return(33554432&this._bitField)>0},Promise.prototype._cancellable=function(){return(67108864&this._bitField)>0},Promise.prototype._setCancellable=function(){this._bitField=67108864|this._bitField},Promise.prototype._unsetCancellable=function(){this._bitField=-67108865&this._bitField},Promise.prototype._setRejectionIsUnhandled=function(){this._bitField=2097152|this._bitField},Promise.prototype._unsetRejectionIsUnhandled=function(){this._bitField=-2097153&this._bitField,this._isUnhandledRejectionNotified()&&(this._unsetUnhandledRejectionIsNotified(),this._notifyUnhandledRejectionIsHandled())},Promise.prototype._isRejectionUnhandled=function(){return(2097152&this._bitField)>0},Promise.prototype._setUnhandledRejectionIsNotified=function(){this._bitField=524288|this._bitField},Promise.prototype._unsetUnhandledRejectionIsNotified=function(){this._bitField=-524289&this._bitField},Promise.prototype._isUnhandledRejectionNotified=function(){return(524288&this._bitField)>0},Promise.prototype._setCarriedStackTrace=function(capturedTrace){this._bitField=1048576|this._bitField,this._fulfillmentHandler0=capturedTrace},Promise.prototype._unsetCarriedStackTrace=function(){this._bitField=-1048577&this._bitField,this._fulfillmentHandler0=void 0},Promise.prototype._isCarryingStackTrace=function(){return(1048576&this._bitField)>0},Promise.prototype._getCarriedStackTrace=function(){return this._isCarryingStackTrace()?this._fulfillmentHandler0:void 0},Promise.prototype._receiverAt=function(index){var ret=0===index?this._receiver0:this[(index<<2)+index-5+4];return this._isBound()&&void 0===ret?this._boundTo:ret},Promise.prototype._promiseAt=function(index){return 0===index?this._promise0:this[(index<<2)+index-5+3]},Promise.prototype._fulfillmentHandlerAt=function(index){return 0===index?this._fulfillmentHandler0:this[(index<<2)+index-5+0]},Promise.prototype._rejectionHandlerAt=function(index){return 0===index?this._rejectionHandler0:this[(index<<2)+index-5+1]},Promise.prototype._addCallbacks=function(fulfill,reject,progress,promise,receiver){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promise,void 0!==receiver&&(this._receiver0=receiver),"function"!=typeof fulfill||this._isCarryingStackTrace()||(this._fulfillmentHandler0=fulfill),"function"==typeof reject&&(this._rejectionHandler0=reject),"function"==typeof progress&&(this._progressHandler0=progress);else{var base=(index<<2)+index-5;this[base+3]=promise,this[base+4]=receiver,this[base+0]="function"==typeof fulfill?fulfill:void 0,this[base+1]="function"==typeof reject?reject:void 0,this[base+2]="function"==typeof progress?progress:void 0}return this._setLength(index+1),index},Promise.prototype._setProxyHandlers=function(receiver,promiseSlotValue){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promiseSlotValue,this._receiver0=receiver;else{var base=(index<<2)+index-5;this[base+3]=promiseSlotValue,this[base+4]=receiver,this[base+0]=this[base+1]=this[base+2]=void 0}this._setLength(index+1)},Promise.prototype._proxyPromiseArray=function(promiseArray,index){this._setProxyHandlers(promiseArray,index)},Promise.prototype._proxyPromise=function(promise){promise._setProxied(),this._setProxyHandlers(promise,-15)},Promise.prototype._setBoundTo=function(obj){void 0!==obj?(this._bitField=8388608|this._bitField,this._boundTo=obj):this._bitField=-8388609&this._bitField},Promise.prototype._isBound=function(){return 8388608===(8388608&this._bitField)},Promise.prototype._resolveFromResolver=function(resolver){function Promise$_resolver(val){promise._tryFollow(val)||promise._fulfill(val)}function Promise$_rejecter(val){var trace=canAttach(val)?val:new Error(val+"");promise._attachExtraTrace(trace),markAsOriginatingFromRejection(val),promise._reject(val,trace===val?void 0:trace)}var promise=this;this._setTrace(void 0),this._pushContext();var r=tryCatch2(resolver,void 0,Promise$_resolver,Promise$_rejecter);if(this._popContext(),void 0!==r&&r===errorObj){var e=r.e,trace=canAttach(e)?e:new Error(e+"");promise._reject(e,trace)}},Promise.prototype._spreadSlowCase=function(targetFn,promise,values,boundTo){var promiseForAll=new PromiseArray(values).promise(),promise2=promiseForAll._then(function(){return targetFn.apply(boundTo,arguments)},void 0,void 0,APPLY,void 0);promise._follow(promise2)},Promise.prototype._callSpread=function(handler,promise,value){var boundTo=this._boundTo;if(isArray(value))for(var i=0,len=value.length;len>i;++i)if(cast(value[i],void 0)instanceof Promise)return void this._spreadSlowCase(handler,promise,value,boundTo);return promise._pushContext(),tryCatchApply(handler,value,boundTo)},Promise.prototype._callHandler=function(handler,receiver,promise,value){var x;return receiver!==APPLY||this.isRejected()?(promise._pushContext(),x=tryCatch1(handler,receiver,value)):x=this._callSpread(handler,promise,value),promise._popContext(),x},Promise.prototype._settlePromiseFromHandler=function(handler,receiver,value,promise){if(!(promise instanceof Promise))return void handler.call(receiver,value,promise);var x=this._callHandler(handler,receiver,promise,value);if(!promise._isFollowing())if(x===errorObj||x===promise||x===NEXT_FILTER){var err=x===promise?makeSelfResolutionError():x.e,trace=canAttach(err)?err:new Error(err+""); -x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string");RemoteStorage.config.cordovaRedirectUri=uri; -},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.connected=!1,RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),self.online=!0,isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err.message);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(_url,errorHandler,sucessHandler){function __makeRequest(url){var xhr=new XMLHttpRequest;xhr.onreadystatechange=function(){if(4===xhr.readyState){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"endpoint unreachable",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this;return __makeRequest(_url)},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error}):generateErrorObject({message:"unknown response from server"}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){return protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource=acct:"+address}function __fallbackChecks(err){return self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1?(uri_index+=1,__call()):self.config.tls_only||"https"!==protocol?self.config.webfist_fallback&&"webfist.org"!==host?(uri_index=0,protocol="http",host="webfist.org",self.__fetchJRD(__buildURL(),cb,function(data){self.__processJRD(data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(JRD,cb,function(result){return cb(null,cb)})})})}),void 0):cb(err):(uri_index=0,protocol="http",__call())}function __call(){self.__fetchJRD(__buildURL(),__fallbackChecks,function(JRD){self.__processJRD(JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,parts=address.replace(/ /g,"").split("@"),host=parts[1],uri_index=0,protocol="https";return 2!==parts.length?cb(generateErrorObject({message:"invalid user address "+address+" ( expected format: user@host.com )"})):(self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0))},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId),!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href, -storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' -},function(window){function stateSetter(widget,state){return RemoteStorage.log("[Widget] Producing stateSetter for",state),function(){RemoteStorage.log("[Widget] Setting state",state,arguments),hasLocalStorage&&(localStorage[LS_STATE_KEY]=state),widget.view?(widget.rs.remote&&widget.view.setUserAddress(widget.rs.remote.userAddress),widget.view.setState(state,arguments)):widget._rememberedState=state}}function errorsHandler(widget){return function(error){var s;error instanceof RemoteStorage.DiscoveryError?(console.error("Discovery failed",error,'"'+error.message+'"'),s=stateSetter(widget,"initial",[error.message])):error instanceof RemoteStorage.SyncError?s=stateSetter(widget,"offline",[]):error instanceof RemoteStorage.Unauthorized?s=stateSetter(widget,"unauthorized"):(RemoteStorage.log("[Widget] Unknown error"),s=stateSetter(widget,"error",[error])),s.apply()}}function flashFor(evt){return"GET"!==evt.method||!evt.isFolder}var hasLocalStorage,LS_STATE_KEY="remotestorage:widget:state",VALID_ENTRY_STATES={initial:!0,connected:!0,offline:!0};RemoteStorage.Widget=function(remoteStorage){var self=this,requestsToFlashFor=0;if(this.rs=remoteStorage,this.rs.remote.on("connected",stateSetter(this,"connected")),this.rs.on("disconnected",stateSetter(this,"initial")),this.rs.on("connecting",stateSetter(this,"authing")),this.rs.on("authing",stateSetter(this,"authing")),this.rs.on("error",errorsHandler(this)),this.rs.remote&&(this.rs.remote.on("wire-busy",function(evt){flashFor(evt)&&(requestsToFlashFor++,stateSetter(self,"busy")())}),this.rs.remote.on("wire-done",function(evt){flashFor(evt)&&requestsToFlashFor--,0>=requestsToFlashFor&&evt.success&&stateSetter(self,"connected")()})),hasLocalStorage){var state=localStorage[LS_STATE_KEY];state&&VALID_ENTRY_STATES[state]&&(this._rememberedState=state)}},RemoteStorage.Widget.prototype={display:function(options){return"string"==typeof options?options={domID:options}:"undefined"==typeof options&&(options={}),this.view||this.setView(new RemoteStorage.Widget.View(this.rs)),this.view.display(options),this},linkWidgetToSync:function(){"object"==typeof this.rs.sync&&"function"==typeof this.rs.sync.sync?this.view.on("sync",this.rs.sync.sync.bind(this.rs.sync)):(RemoteStorage.log("[Widget] typeof this.rs.sync check fail",this.rs.sync),setTimeout(this.linkWidgetToSync.bind(this),1e3))},setView:function(view){this.view=view,this.view.on("connect",function(options){"string"==typeof options?this.rs.connect(options):options.special&&this.rs[options.special].connect(options)}.bind(this)),this.view.on("secret-entered",function(secretKey){this.view.setUserSecretKey(secretKey),stateSetter(this,"ciphered")()}.bind(this)),this.view.on("secret-cancelled",function(){stateSetter(this,"notciphered")()}.bind(this)),this.view.on("disconnect",this.rs.disconnect.bind(this.rs)),this.linkWidgetToSync();try{this.view.on("reset",function(){var location=RemoteStorage.Authorize.getLocation();this.rs.on("disconnected",location.reload.bind(location)),this.rs.disconnect()}.bind(this))}catch(e){if(!e.message||!e.message.match(/Unknown event/))throw e}this._rememberedState&&(setTimeout(stateSetter(this,this._rememberedState),0),delete this._rememberedState)}},RemoteStorage.prototype.displayWidget=function(options){return this.widget.display(options)},RemoteStorage.Widget._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.widget||(remoteStorage.widget=new RemoteStorage.Widget(remoteStorage))},RemoteStorage.Widget._rs_supported=function(remoteStorage){return"undefined"!=typeof document}}("undefined"!=typeof window?window:global),function(window){function removeClass(el,className){return el.classList.remove(className)}function addClass(el,className){return el.classList.add(className)}function stopPropagation(event){"function"==typeof event.stopPropagation?event.stopPropagation():event.cancelBubble=!0}function setupButton(parent,className,iconName,eventListener){var element=parent.querySelector("."+className);if("undefined"!=typeof iconName){var img=element.querySelector("img");(img||element).src=RemoteStorage.Assets[iconName]}return element.addEventListener("click",eventListener),element}function handleButtonState(event){event.target.value?event.target.nextElementSibling.removeAttribute("disabled"):event.target.nextElementSibling.setAttribute("disabled","disabled")}var t=RemoteStorage.I18n.translate;RemoteStorage.Widget.View=function(remoteStorage){if(this.rs=remoteStorage,"undefined"==typeof document)throw"Widget not supported";RemoteStorage.eventHandling(this,"connect","secret-entered","secret-cancelled","disconnect","sync","display","reset");for(var event in this.events)this.events[event]=this.events[event].bind(this);this.hideBubbleOnBodyClick=function(event){for(var p=event.target;p!==document.body;p=p.parentElement)if("remotestorage-widget"===p.id)return;this.hideBubble()}.bind(this)},RemoteStorage.Widget.View.prototype={connectGdrive:function(){this._emit("connect",{special:"googledrive"})},connectDropbox:function(){this._emit("connect",{special:"dropbox"})},setState:function(state,args){RemoteStorage.log("[View] widget.view.setState(",state,",",args,");");var s=this.states[state];if("undefined"==typeof s)throw new Error("Bad State assigned to view: "+state);s.apply(this,args)},setUserAddress:function(addr){this.userAddress=addr||"";var el;this.div&&(el=this.div.querySelector("form.remotestorage-initial").userAddress)&&(el.value=this.userAddress)},setUserSecretKey:function(secretKey){this.userSecretKey=secretKey},toggleBubble:function(event){this.bubble.className.search("rs-hidden")<0?this.hideBubble(event):this.showBubble(event)},hideBubble:function(){addClass(this.bubble,"rs-hidden"),document.body.removeEventListener("click",this.hideBubbleOnBodyClick)},showBubble:function(event){removeClass(this.bubble,"rs-hidden"),"undefined"!=typeof event&&stopPropagation(event),document.body.addEventListener("click",this.hideBubbleOnBodyClick),this.div.querySelector(".remotestorage-connected").classList.contains("remotestorage-cipher")&&!this.userSecretKey?this.bubble.querySelector("form.remotestorage-cipher-form").userSecretKey.focus():this.bubble.querySelector("form.remotestorage-initial").userAddress.focus()},display:function(options){if("undefined"!=typeof this.div)return this.div;var element=document.createElement("div"),style=document.createElement("style");if(style.innerHTML=RemoteStorage.Assets.widgetCss,element.id="remotestorage-widget",element.innerHTML=RemoteStorage.Assets.widget,element.appendChild(style),options.domID){var parent=document.getElementById(options.domID);if(!parent)throw'Failed to find target DOM element with id="'+options.domID+'"';parent.appendChild(element)}else document.body.appendChild(element);setupButton(element,"rs-sync","syncIcon",this.events.sync),setupButton(element,"rs-disconnect","disconnectIcon",this.events.disconnect),setupButton(element,"remotestorage-reset",void 0,this.events.reset);setupButton(element,"connect","connectIcon",this.events.connect);this.form=element.querySelector("form.remotestorage-initial");var el=this.form.userAddress;if(el.addEventListener("load",handleButtonState),el.addEventListener("keyup",handleButtonState),this.userAddress&&(el.value=this.userAddress),options.encryption){this.cipher=!0;var secretKeyInput=element.querySelector("form.remotestorage-cipher-form").userSecretKey;secretKeyInput.type="password";setupButton(element,"rs-cipher","cipherIcon",this.events["secret-entered"]);secretKeyInput.addEventListener("load",handleButtonState),secretKeyInput.addEventListener("keyup",handleButtonState),setupButton(element,"rs-nocipher","nocipherIcon",this.events["secret-cancelled"])}this.cube=setupButton(element,"rs-cube","remoteStorageIcon",this.toggleBubble.bind(this)),setupButton(element,"rs-dropbox","dropbox",this.connectDropbox.bind(this)),setupButton(element,"rs-googledrive","googledrive",this.connectGdrive.bind(this));var bubbleDontCatch={INPUT:!0,BUTTON:!0,IMG:!0},eventListener=function(event){bubbleDontCatch[event.target.tagName]||this.div.classList.contains("remotestorage-state-unauthorized")||this.showBubble(event)}.bind(this);return this.bubble=setupButton(element,"rs-bubble",void 0,eventListener),this.hideBubble(),this.div=element,this.states.initial.call(this),this.events.display.call(this),this.div},states:{initial:function(message){var cube=this.cube,info=message||t("view_info");cube.src=RemoteStorage.Assets.remoteStorageIcon,this._renderTranslatedInitialContent(),message?(cube.src=RemoteStorage.Assets.remoteStorageIconError,removeClass(this.cube,"remotestorage-loading"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},2e3)):this.hideBubble(),this.div.className="remotestorage-state-initial",this.userSecretKey&&delete this.userSecretKey;var backends=1;this._activateBackend("dropbox")&&(backends+=1),this._activateBackend("googledrive")&&(backends+=1),this.div.querySelector(".rs-bubble-text").style.paddingRight=32*backends+8+"px";var cb=this.div.querySelector(".connect");this.form.userAddress.value&&cb.removeAttribute("disabled");var infoEl=this.div.querySelector(".rs-info-msg");infoEl.innerHTML=info,message?infoEl.classList.add("remotestorage-error-info"):infoEl.classList.remove("remotestorage-error-info")},authing:function(){this.div.removeEventListener("click",this.events.connect),this.div.className="remotestorage-state-authing",this.div.querySelector(".rs-status-text").innerHTML=t("view_connecting",this.userAddress),addClass(this.cube,"remotestorage-loading")},connected:function(){var cube=this.cube;this.div.className="remotestorage-state-connected",this.div.querySelector(".userAddress").innerHTML=this.userAddress,cube.src=RemoteStorage.Assets.remoteStorageIcon,removeClass(cube,"remotestorage-loading"),this.cipher&&(this.userSecretKey?this.userSecretKeyError?(cube.src=RemoteStorage.Assets.remoteStorageIconError,addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),addClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},5e3)):(removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),cube.src=RemoteStorage.Assets.remoteStorageIconCiphered):(addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.showBubble()));var icons={googledrive:this.div.querySelector(".rs-googledrive"),dropbox:this.div.querySelector(".rs-dropbox")};icons.googledrive.style.display=icons.dropbox.style.display="none",icons[this.rs.backend]?(icons[this.rs.backend].style.display="inline-block",this.div.querySelector(".rs-bubble-text").style.paddingRight="72px"):this.div.querySelector(".rs-bubble-text").style.paddingRight="40px"},ciphered:function(){this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value="",removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.cube.src=RemoteStorage.Assets.remoteStorageIconCiphered,this.hideBubble()},notciphered:function(){this.cipher=!1,removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.hideBubble()},busy:function(){this.div.className="remotestorage-state-busy",addClass(this.cube,"remotestorage-loading")},offline:function(){this.div.className="remotestorage-state-offline",this.cube.src=RemoteStorage.Assets.remoteStorageIconOffline,this.div.querySelector(".rs-status-text").innerHTML=t("view_offline")},error:function(err){var errorMsg=err;this.div.className="remotestorage-state-error",this.div.querySelector(".rs-bubble-text").innerHTML=""+t("view_error_occured")+"",err instanceof Error&&(errorMsg=err.message+"\n\n"+err.stack),this.div.querySelector(".rs-error-msg").textContent=errorMsg,this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble()},unauthorized:function(){this.div.className="remotestorage-state-unauthorized",this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble(),this.div.addEventListener("click",this.events.connect)}},events:{connect:function(event){stopPropagation(event),event.preventDefault(),this._emit("connect",this.div.querySelector("form.remotestorage-initial").userAddress.value)},"secret-entered":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-entered",this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value)},"secret-cancelled":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-cancelled")},sync:function(event){stopPropagation(event),event.preventDefault(),this._emit("sync")},disconnect:function(event){stopPropagation(event),event.preventDefault(),this._emit("disconnect")},reset:function(event){event.preventDefault();var result=window.confirm(t("view_confirm_reset"));result&&this._emit("reset")},display:function(event){event&&event.preventDefault(),this._emit("display")}},_renderTranslatedInitialContent:function(){this.div.querySelector(".rs-status-text").innerHTML=t("view_connect"),this.div.querySelector(".remotestorage-reset").innerHTML=t("view_get_me_out"),this.div.querySelector(".rs-error-plz-report").innerHTML=t("view_error_plz_report"),this.div.querySelector(".remotestorage-unauthorized").innerHTML=t("view_unauthorized"),this.div.querySelector(".remotestorage-invalid-key").innerHTML=t("view_invalid_key")},_activateBackend:function(backendName){var className="rs-"+backendName;return this.rs.apiKeys[backendName]?(this.div.querySelector("."+className).style.display="inline-block",!0):(this.div.querySelector("."+className).style.display="none",!1)}}}("undefined"!=typeof window?window:global),function(global,factory){"function"==typeof define&&define.amd?define([],factory):"undefined"!=typeof module&&module.exports?module.exports=factory():global.tv4=factory()}(this,function(){function notReallyPercentEncode(string){return encodeURI(string).replace(/%25[0-9][0-9]/g,function(doubleEncoded){return"%"+doubleEncoded.substring(3)})}function uriTemplateSubstitution(spec){var modifier="";uriTemplateGlobalModifiers[spec.charAt(0)]&&(modifier=spec.charAt(0),spec=spec.substring(1));var separator="",prefix="",shouldEscape=!0,showVariables=!1,trimEmptyString=!1;"+"===modifier?shouldEscape=!1:"."===modifier?(prefix=".",separator="."):"/"===modifier?(prefix="/",separator="/"):"#"===modifier?(prefix="#",shouldEscape=!1):";"===modifier?(prefix=";",separator=";",showVariables=!0,trimEmptyString=!0):"?"===modifier?(prefix="?",separator="&",showVariables=!0):"&"===modifier&&(prefix="&",separator="&",showVariables=!0);for(var varNames=[],varList=spec.split(","),varSpecs=[],varSpecMap={},i=0;i0&&(result+=varSpec.suffices["*"]?separator||",":",",varSpec.suffices["*"]&&showVariables&&(result+=varSpec.name+"=")),result+=shouldEscape?encodeURIComponent(value[j]).replace(/!/g,"%21"):notReallyPercentEncode(value[j])}else if("object"==typeof value){showVariables&&!varSpec.suffices["*"]&&(result+=varSpec.name+"=");var first=!0;for(var key in value)first||(result+=varSpec.suffices["*"]?separator||",":","),first=!1,result+=shouldEscape?encodeURIComponent(key).replace(/!/g,"%21"):notReallyPercentEncode(key),result+=varSpec.suffices["*"]?"=":",",result+=shouldEscape?encodeURIComponent(value[key]).replace(/!/g,"%21"):notReallyPercentEncode(value[key])}else showVariables&&(result+=varSpec.name,trimEmptyString&&""===value||(result+="=")),null!=varSpec.truncate&&(value=value.substring(0,varSpec.truncate)),result+=shouldEscape?encodeURIComponent(value).replace(/!/g,"%21"):notReallyPercentEncode(value)}return result};return subFunction.varNames=varNames,{prefix:prefix,substitution:subFunction}}function UriTemplate(template){if(!(this instanceof UriTemplate))return new UriTemplate(template);for(var parts=template.split("{"),textParts=[parts.shift()],prefixes=[],substitutions=[],varNames=[];parts.length>0;){var part=parts.shift(),spec=part.split("}")[0],remainder=part.substring(spec.length+1),funcs=uriTemplateSubstitution(spec);substitutions.push(funcs.substitution),prefixes.push(funcs.prefix),textParts.push(remainder),varNames=varNames.concat(funcs.substitution.varNames)}this.fill=function(valueFunction){for(var result=textParts[0],i=0;i0&&"/"===testUrl.charAt(baseUrl.length-1)||"#"===remainder.charAt(0)||"?"===remainder.charAt(0))return!0}return!1}function createApi(language){var currentLanguage,customErrorReporter,globalContext=new ValidatorContext,api={setErrorReporter:function(reporter){return"string"==typeof reporter?this.language(reporter):(customErrorReporter=reporter,!0)},addFormat:function(){globalContext.addFormat.apply(globalContext,arguments)},language:function(code){return code?(languages[code]||(code=code.split("-")[0]),languages[code]?(currentLanguage=code,code):!1):currentLanguage},addLanguage:function(code,messageMap){var key;for(key in ErrorCodes)messageMap[key]&&!messageMap[ErrorCodes[key]]&&(messageMap[ErrorCodes[key]]=messageMap[key]);var rootCode=code.split("-")[0];if(languages[rootCode]){languages[code]=Object.create(languages[rootCode]);for(key in messageMap)"undefined"==typeof languages[rootCode][key]&&(languages[rootCode][key]=messageMap[key]),languages[code][key]=messageMap[key]}else languages[code]=messageMap,languages[rootCode]=messageMap;return this},freshApi:function(language){var result=createApi();return language&&result.language(language),result},validate:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!1,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema);var error=context.validateAll(data,schema,null,null,"");return!error&&banUnknownProperties&&(error=context.banUnknownProperties(data,schema)),this.error=error,this.missing=context.missing,this.valid=null===error,this.valid},validateResult:function(){var result={};return this.validate.apply(result,arguments),result},validateMultiple:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!0,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema),context.validateAll(data,schema,null,null,""),banUnknownProperties&&context.banUnknownProperties(data,schema);var result={};return result.errors=context.errors,result.missing=context.missing,result.valid=0===result.errors.length,result},addSchema:function(){return globalContext.addSchema.apply(globalContext,arguments)},getSchema:function(){return globalContext.getSchema.apply(globalContext,arguments)},getSchemaMap:function(){return globalContext.getSchemaMap.apply(globalContext,arguments)},getSchemaUris:function(){return globalContext.getSchemaUris.apply(globalContext,arguments)},getMissingUris:function(){return globalContext.getMissingUris.apply(globalContext,arguments)},dropSchemas:function(){globalContext.dropSchemas.apply(globalContext,arguments)},defineKeyword:function(){globalContext.defineKeyword.apply(globalContext,arguments)},defineError:function(codeName,codeNumber,defaultMessage){if("string"!=typeof codeName||!/^[A-Z]+(_[A-Z]+)*$/.test(codeName))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof codeNumber||codeNumber%1!==0||1e4>codeNumber)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof ErrorCodes[codeName])throw new Error("Error already defined: "+codeName+" as "+ErrorCodes[codeName]);if("undefined"!=typeof ErrorCodeLookup[codeNumber])throw new Error("Error code already used: "+ErrorCodeLookup[codeNumber]+" as "+codeNumber);ErrorCodes[codeName]=codeNumber,ErrorCodeLookup[codeNumber]=codeName,ErrorMessagesDefault[codeName]=ErrorMessagesDefault[codeNumber]=defaultMessage;for(var langCode in languages){var language=languages[langCode];language[codeName]&&(language[codeNumber]=language[codeNumber]||language[codeName])}},reset:function(){globalContext.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:normSchema,resolveUrl:resolveUrl,getDocumentUri:getDocumentUri,errorCodes:ErrorCodes};return api.language(language||"en"),api}Object.keys||(Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if("object"!=typeof obj&&"function"!=typeof obj||null===obj)throw new TypeError("Object.keys called on non-object");var result=[];for(var prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(var i=0;dontEnumsLength>i;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result}}()),Object.create||(Object.create=function(){function F(){}return function(o){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Array.isArray||(Array.isArray=function(vArg){return"[object Array]"===Object.prototype.toString.call(vArg)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(searchElement){if(null===this)throw new TypeError;var t=Object(this),len=t.length>>>0;if(0===len)return-1;var n=0;if(arguments.length>1&&(n=Number(arguments[1]),n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=len)return-1;for(var k=n>=0?n:Math.max(len-Math.abs(n),0);len>k;k++)if(k in t&&t[k]===searchElement)return k;return-1}),Object.isFrozen||(Object.isFrozen=function(obj){for(var key="tv4_test_frozen_key";obj.hasOwnProperty(key);)key+=Math.random();try{return obj[key]=!0,delete obj[key],!1}catch(e){return!0}});var uriTemplateGlobalModifiers={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},uriTemplateSuffices={"*":!0};UriTemplate.prototype={toString:function(){return this.template},fillFromObject:function(obj){return this.fill(function(varName){return obj[varName]})}};var ValidatorContext=function(parent,collectMultiple,errorReporter,checkRecursive,trackUnknownProperties){if(this.missing=[],this.missingMap={},this.formatValidators=parent?Object.create(parent.formatValidators):{},this.schemas=parent?Object.create(parent.schemas):{},this.collectMultiple=collectMultiple,this.errors=[],this.handleError=collectMultiple?this.collectError:this.returnError,checkRecursive&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),trackUnknownProperties&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=errorReporter||defaultErrorReporter("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},parent)for(var key in parent.definedKeywords)this.definedKeywords[key]=parent.definedKeywords[key].slice(0)};ValidatorContext.prototype.defineKeyword=function(keyword,keywordFunction){this.definedKeywords[keyword]=this.definedKeywords[keyword]||[],this.definedKeywords[keyword].push(keywordFunction)},ValidatorContext.prototype.createError=function(code,messageParams,dataPath,schemaPath,subErrors,data,schema){var error=new ValidationError(code,messageParams,dataPath,schemaPath,subErrors);return error.message=this.errorReporter(error,data,schema),error},ValidatorContext.prototype.returnError=function(error){return error},ValidatorContext.prototype.collectError=function(error){return error&&this.errors.push(error),null},ValidatorContext.prototype.prefixErrors=function(startIndex,dataPath,schemaPath){for(var i=startIndex;i0},Async.prototype.invokeLater=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn)),this._lateBuffer.push(fn,receiver,arg),this._queueTick()},Async.prototype.invoke=function(fn,receiver,arg){void 0===_process||null==_process.domain||fn.domain||(fn=_process.domain.bind(fn));var functionBuffer=this._functionBuffer;functionBuffer.push(fn,receiver,arg),this._length=functionBuffer.length(),this._queueTick()},Async.prototype._consumeFunctionBuffer=function(){for(var functionBuffer=this._functionBuffer;functionBuffer.length()>0;){var fn=functionBuffer.shift(),receiver=functionBuffer.shift(),arg=functionBuffer.shift();fn.call(receiver,arg)}this._reset(),this._consumeLateBuffer()},Async.prototype._consumeLateBuffer=function(){for(var buffer=this._lateBuffer;buffer.length()>0;){var fn=buffer.shift(),receiver=buffer.shift(),arg=buffer.shift(),res=tryCatch1(fn,receiver,arg);if(res===errorObj){if(this._queueTick(),null==fn.domain)throw res.e;fn.domain.emit("error",res.e)}}},Async.prototype._queueTick=function(){this._isTickUsed||(this._schedule(this.consumeFunctionBuffer),this._isTickUsed=!0)},Async.prototype._reset=function(){this._isTickUsed=!1,this._length=0},module.exports=new Async},{"./queue.js":15,"./schedule.js":16,"./util.js":19}],2:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise.js")();module.exports=Promise},{"./promise.js":12}],3:[function(_dereq_,module,exports){"use strict";module.exports=function(){function formatNonError(obj){var str;if("function"==typeof obj)str="[function "+(obj.name||"anonymous")+"]";else{str=obj.toString();var ruselessToString=/\[object [a-zA-Z0-9$_]+\]/;if(ruselessToString.test(str))try{var newStr=JSON.stringify(obj);str=newStr}catch(e){}0===str.length&&(str="(empty array)")}return"(<"+snip(str)+">, no stack trace)"}function snip(str){var maxChars=41;return str.length=0;--i){var line=prev[i];if(current[curLast]!==line)break;current.pop(),curLast--}current.push("From previous event:");for(var lines=current.concat(prev),ret=[],i=0,len=lines.length;len>i;++i)rignore.test(lines[i])&&rtraceline.test(lines[i])||i>0&&!rtraceline.test(lines[i])&&"From previous event:"!==lines[i]||ret.push(lines[i]);return ret},CapturedTrace.protectErrorMessageNewlines=function(stack){for(var i=0;i=i)){for(var errorMessageLines=[],j=0;i>j;++j)errorMessageLines.push(stack.shift());stack.unshift(errorMessageLines.join("\x00"))}},CapturedTrace.isSupported=function(){return"function"==typeof captureStackTrace};var captureStackTrace=function stackDetection(){if("number"==typeof Error.stackTraceLimit&&"function"==typeof Error.captureStackTrace){rtraceline=/^\s*at\s*/,formatStack=function(stack,error){return"string"==typeof stack?stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)};var captureStackTrace=Error.captureStackTrace;return function(receiver,ignoreUntil){captureStackTrace(receiver,ignoreUntil)}}var err=new Error;if("string"==typeof err.stack&&"function"==typeof"".startsWith&&err.stack.startsWith("stackDetection@")&&"stackDetection"===stackDetection.name){defineProperty(Error,"stackTraceLimit",{writable:!0,enumerable:!1,configurable:!1,value:25}),rtraceline=/@/;var rline=/[@\n]/;return formatStack=function(stack,error){return"string"==typeof stack?error.name+". "+error.message+"\n"+stack:void 0!==error.name&&void 0!==error.message?error.name+". "+error.message:formatNonError(error)},function(o){for(var stack=(new Error).stack,split=stack.split(rline),len=split.length,ret="",i=0;len>i;i+=2)ret+=split[i],ret+="@",ret+=split[i+1],ret+="\n";o.stack=ret}}return formatStack=function(stack,error){return"string"==typeof stack?stack:"object"!=typeof error&&"function"!=typeof error||void 0===error.name||void 0===error.message?formatNonError(error):error.name+". "+error.message},null}();return CapturedTrace}},{"./es5.js":8,"./util.js":19}],4:[function(_dereq_,module,exports){"use strict";module.exports=function(NEXT_FILTER){function CatchFilter(instances,callback,promise){this._instances=instances,this._callback=callback,this._promise=promise}function CatchFilter$_safePredicate(predicate,e){var safeObject={},retfilter=tryCatch1(predicate,safeObject,e);if(retfilter===errorObj)return retfilter;var safeKeys=keys(safeObject);return safeKeys.length?(errorObj.e=new TypeError("Catch filter must inherit from Error or be a simple predicate function"),errorObj):retfilter}var util=_dereq_("./util.js"),errors=_dereq_("./errors.js"),tryCatch1=util.tryCatch1,errorObj=util.errorObj,keys=_dereq_("./es5.js").keys,TypeError=errors.TypeError;return CatchFilter.prototype.doFilter=function(e){for(var cb=this._callback,promise=this._promise,boundTo=promise._boundTo,i=0,len=this._instances.length;len>i;++i){var item=this._instances[i],itemIsErrorType=item===Error||null!=item&&item.prototype instanceof Error;if(itemIsErrorType&&e instanceof item){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}if("function"==typeof item&&!itemIsErrorType){var shouldHandle=CatchFilter$_safePredicate(item,e);if(shouldHandle===errorObj){var trace=errors.canAttach(errorObj.e)?errorObj.e:new Error(errorObj.e+"");this._promise._attachExtraTrace(trace),e=errorObj.e;break}if(shouldHandle){var ret=tryCatch1(cb,boundTo,e);return ret===errorObj?(NEXT_FILTER.e=ret.e,NEXT_FILTER):ret}}}return NEXT_FILTER.e=e,NEXT_FILTER},CatchFilter}},{"./errors.js":6,"./es5.js":8,"./util.js":19}],5:[function(_dereq_,module,exports){"use strict";var util=_dereq_("./util.js"),isPrimitive=util.isPrimitive,wrapsPrimitiveReceiver=util.wrapsPrimitiveReceiver;module.exports=function(Promise){var returner=function(){return this},thrower=function(){throw this},wrapper=function(value,action){return 1===action?function(){throw value}:2===action?function(){return value}:void 0};Promise.prototype["return"]=Promise.prototype.thenReturn=function(value){return wrapsPrimitiveReceiver&&isPrimitive(value)?this._then(wrapper(value,2),void 0,void 0,void 0,void 0):this._then(returner,void 0,void 0,value,void 0)},Promise.prototype["throw"]=Promise.prototype.thenThrow=function(reason){return wrapsPrimitiveReceiver&&isPrimitive(reason)?this._then(wrapper(reason,1),void 0,void 0,void 0,void 0):this._then(thrower,void 0,void 0,reason,void 0)}}},{"./util.js":19}],6:[function(_dereq_,module,exports){"use strict";function markAsOriginatingFromRejection(e){try{notEnumerableProp(e,"isOperational",!0)}catch(ignore){}}function originatesFromRejection(e){return null==e?!1:e instanceof OperationalError||e.isOperational===!0}function isError(obj){return obj instanceof Error}function canAttach(obj){return isError(obj)}function subError(nameProperty,defaultMessage){function SubError(message){return this instanceof SubError?(this.message="string"==typeof message?message:defaultMessage,this.name=nameProperty,void(Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor))):new SubError(message)}return inherits(SubError,Error),SubError}function OperationalError(message){this.name="OperationalError",this.message=message,this.cause=message,this.isOperational=!0,message instanceof Error?(this.message=message.message,this.stack=message.stack):Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}var _TypeError,_RangeError,Objectfreeze=_dereq_("./es5.js").freeze,util=_dereq_("./util.js"),inherits=util.inherits,notEnumerableProp=util.notEnumerableProp,CancellationError=subError("CancellationError","cancellation error"),TimeoutError=subError("TimeoutError","timeout error"),AggregateError=subError("AggregateError","aggregate error");try{_TypeError=TypeError,_RangeError=RangeError}catch(e){_TypeError=subError("TypeError","type error"),_RangeError=subError("RangeError","range error")}for(var methods="join pop push shift unshift slice filter forEach some every map indexOf lastIndexOf reduce reduceRight sort reverse".split(" "),i=0;i=i;++i)values.push("holder.p"+i);return new Function("holder"," \n 'use strict'; \n var callback = holder.fn; \n return callback(values); \n ".replace(/values/g,values.join(", ")))},thenCallbacks=[],callers=[void 0],i=1;5>=i;++i)thenCallbacks.push(thenCallback(i)),callers.push(caller(i));var Holder=function(total,fn){this.p1=this.p2=this.p3=this.p4=this.p5=null,this.fn=fn,this.total=total,this.now=0};Holder.prototype.callers=callers,Holder.prototype.checkFulfillment=function(promise){var now=this.now;now++;var total=this.total;if(now>=total){var handler=this.callers[total],ret=tryCatch1(handler,void 0,this);ret===errorObj?promise._rejectUnchecked(ret.e):promise._tryFollow(ret)||promise._fulfillUnchecked(ret)}else this.now=now}}Promise.join=function(){var fn,last=arguments.length-1;if(last>0&&"function"==typeof arguments[last]&&(fn=arguments[last],6>last&&canEvaluate)){var ret=new Promise(INTERNAL);ret._setTrace(void 0);for(var holder=new Holder(last,fn),reject=ret._reject,callbacks=thenCallbacks,i=0;last>i;++i){var maybePromise=cast(arguments[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._then(callbacks[i],reject,void 0,ret,holder):maybePromise.isFulfilled()?callbacks[i].call(ret,maybePromise._settledValue,holder):(ret._reject(maybePromise._settledValue),maybePromise._unsetRejectionIsUnhandled()):callbacks[i].call(ret,maybePromise,holder)}return ret}for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];var ret=new PromiseArray(args).promise();return void 0!==fn?ret.spread(fn):ret}}},{"./util.js":19}],11:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function thrower(r){throw r}function Promise$_spreadAdapter(val,receiver){if(!util.isArray(val))return Promise$_successAdapter(val,receiver);var ret=util.tryCatchApply(this,[null].concat(val),receiver);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_successAdapter(val,receiver){var nodeback=this,ret=void 0===val?tryCatch1(nodeback,receiver,null):tryCatch2(nodeback,receiver,null,val);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}function Promise$_errorAdapter(reason,receiver){var nodeback=this,ret=tryCatch1(nodeback,receiver,reason);ret===errorObj&&async.invokeLater(thrower,void 0,ret.e)}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),tryCatch2=util.tryCatch2,tryCatch1=util.tryCatch1,errorObj=util.errorObj;Promise.prototype.nodeify=function(nodeback,options){if("function"==typeof nodeback){var adapter=Promise$_successAdapter;void 0!==options&&Object(options).spread&&(adapter=Promise$_spreadAdapter),this._then(adapter,Promise$_errorAdapter,void 0,nodeback,this._boundTo)}return this}}},{"./async.js":1,"./util.js":19}],12:[function(_dereq_,module,exports){"use strict";function noConflict(bluebird){try{Promise===bluebird&&(Promise=old)}catch(e){}return bluebird}var old;"undefined"!=typeof Promise&&(old=Promise),module.exports=function(){function Promise(resolver){if("function"!=typeof resolver)throw new TypeError("the promise constructor requires a resolver function");if(this.constructor!==Promise)throw new TypeError("the promise constructor cannot be invoked directly");this._bitField=0,this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0,this._settledValue=void 0,this._boundTo=void 0,resolver!==INTERNAL&&this._resolveFromResolver(resolver)}function returnFirstElement(elements){return elements[0]}var util=_dereq_("./util.js"),async=_dereq_("./async.js"),errors=_dereq_("./errors.js"),INTERNAL=function(){},APPLY={},NEXT_FILTER={e:null},cast=_dereq_("./thenables.js")(Promise,INTERNAL),PromiseArray=_dereq_("./promise_array.js")(Promise,INTERNAL,cast),CapturedTrace=_dereq_("./captured_trace.js")(),CatchFilter=_dereq_("./catch_filter.js")(NEXT_FILTER),PromiseResolver=_dereq_("./promise_resolver.js"),isArray=util.isArray,errorObj=util.errorObj,tryCatch1=util.tryCatch1,tryCatch2=util.tryCatch2,tryCatchApply=util.tryCatchApply,RangeError=errors.RangeError,TypeError=errors.TypeError,CancellationError=errors.CancellationError,TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,originatesFromRejection=errors.originatesFromRejection,markAsOriginatingFromRejection=errors.markAsOriginatingFromRejection,canAttach=errors.canAttach,thrower=util.thrower,apiRejection=_dereq_("./errors_api_rejection")(Promise),makeSelfResolutionError=function(){return new TypeError("circular promise resolution chain")};Promise.prototype.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(maybePromise instanceof Promise){var binder=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)}),p=Promise.all([this,binder]).then(returnFirstElement);ret._follow(p)}else ret._follow(this),ret._setBoundTo(thisArg);return ret._propagateFrom(this,3),ret},Promise.prototype.toString=function(){return"[object Promise]"},Promise.prototype.caught=Promise.prototype["catch"]=function(fn){var len=arguments.length;if(len>1){var i,catchInstances=new Array(len-1),j=0;for(i=0;len-1>i;++i){var item=arguments[i];if("function"!=typeof item){var catchFilterTypeError=new TypeError("A catch filter must be an error constructor or a filter function");return this._attachExtraTrace(catchFilterTypeError),Promise.reject(catchFilterTypeError)}catchInstances[j++]=item}catchInstances.length=j,fn=arguments[i],this._resetTrace();var catchFilter=new CatchFilter(catchInstances,fn,this);return this._then(void 0,catchFilter.doFilter,void 0,catchFilter,void 0)}return this._then(void 0,fn,void 0,void 0,void 0)},Promise.prototype.then=function(didFulfill,didReject,didProgress){return this._then(didFulfill,didReject,didProgress,void 0,void 0)},Promise.prototype.done=function(didFulfill,didReject,didProgress){var promise=this._then(didFulfill,didReject,didProgress,void 0,void 0);promise._setIsFinal()},Promise.prototype.spread=function(didFulfill,didReject){return this._then(didFulfill,didReject,void 0,APPLY,void 0)},Promise.prototype.isCancellable=function(){return!this.isResolved()&&this._cancellable()},Promise.prototype.toJSON=function(){var ret={isFulfilled:!1,isRejected:!1,fulfillmentValue:void 0,rejectionReason:void 0};return this.isFulfilled()?(ret.fulfillmentValue=this._settledValue,ret.isFulfilled=!0):this.isRejected()&&(ret.rejectionReason=this._settledValue,ret.isRejected=!0),ret},Promise.prototype.all=function(){return new PromiseArray(this).promise()},Promise.is=function(val){return val instanceof Promise},Promise.all=function(promises){return new PromiseArray(promises).promise()},Promise.prototype.error=function(fn){return this.caught(originatesFromRejection,fn)},Promise.prototype._resolveFromSyncValue=function(value){if(value===errorObj)this._cleanValues(),this._setRejected(),this._settledValue=value.e,this._ensurePossibleRejectionHandled();else{var maybePromise=cast(value,void 0);maybePromise instanceof Promise?this._follow(maybePromise):(this._cleanValues(),this._setFulfilled(),this._settledValue=value)}},Promise.method=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");return function(){var value;switch(arguments.length){case 0:value=tryCatch1(fn,this,void 0);break;case 1:value=tryCatch1(fn,this,arguments[0]);break;case 2:value=tryCatch2(fn,this,arguments[0],arguments[1]);break;default:for(var $_len=arguments.length,args=new Array($_len),$_i=0;$_len>$_i;++$_i)args[$_i]=arguments[$_i];value=tryCatchApply(fn,args,this)}var ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret}},Promise.attempt=Promise["try"]=function(fn,args,ctx){if("function"!=typeof fn)return apiRejection("fn must be a function");var value=isArray(args)?tryCatchApply(fn,args,ctx):tryCatch1(fn,ctx,args),ret=new Promise(INTERNAL);return ret._setTrace(void 0),ret._resolveFromSyncValue(value),ret},Promise.defer=Promise.pending=function(){var promise=new Promise(INTERNAL);return promise._setTrace(void 0),new PromiseResolver(promise)},Promise.bind=function(thisArg){var maybePromise=cast(thisArg,void 0),ret=new Promise(INTERNAL);if(ret._setTrace(void 0),maybePromise instanceof Promise){var p=maybePromise.then(function(thisArg){ret._setBoundTo(thisArg)});ret._follow(p)}else ret._setBoundTo(thisArg),ret._setFulfilled();return ret},Promise.cast=function(obj){var ret=cast(obj,void 0);if(!(ret instanceof Promise)){var val=ret;ret=new Promise(INTERNAL),ret._setTrace(void 0),ret._setFulfilled(),ret._cleanValues(),ret._settledValue=val}return ret},Promise.resolve=Promise.fulfilled=Promise.cast,Promise.reject=Promise.rejected=function(reason){var ret=new Promise(INTERNAL);if(ret._setTrace(void 0),markAsOriginatingFromRejection(reason),ret._cleanValues(),ret._setRejected(),ret._settledValue=reason,!canAttach(reason)){var trace=new Error(reason+"");ret._setCarriedStackTrace(trace)}return ret._ensurePossibleRejectionHandled(),ret},Promise.onPossiblyUnhandledRejection=function(fn){CapturedTrace.possiblyUnhandledRejection="function"==typeof fn?fn:void 0};var unhandledRejectionHandled;Promise.onUnhandledRejectionHandled=function(fn){unhandledRejectionHandled="function"==typeof fn?fn:void 0};var debugging=!("undefined"==typeof process||"string"!=typeof process.execPath||"object"!=typeof process.env||!process.env.BLUEBIRD_DEBUG&&"development"!==process.env.NODE_ENV);Promise.longStackTraces=function(){if(async.haveItemsQueued()&&debugging===!1)throw new Error("cannot enable long stack traces after promises have been created");debugging=CapturedTrace.isSupported()},Promise.hasLongStackTraces=function(){return debugging&&CapturedTrace.isSupported()},Promise.prototype._then=function(didFulfill,didReject,didProgress,receiver,internalData){var haveInternalData=void 0!==internalData,ret=haveInternalData?internalData:new Promise(INTERNAL);if(!haveInternalData){if(debugging){var haveSameContext=this._peekContext()===this._traceParent;ret._traceParent=haveSameContext?this._traceParent:this}ret._propagateFrom(this,7)}var callbackIndex=this._addCallbacks(didFulfill,didReject,didProgress,ret,receiver);return this.isResolved()&&async.invoke(this._queueSettleAt,this,callbackIndex),ret},Promise.prototype._length=function(){return 262143&this._bitField},Promise.prototype._isFollowingOrFulfilledOrRejected=function(){return(939524096&this._bitField)>0},Promise.prototype._isFollowing=function(){return 536870912===(536870912&this._bitField)},Promise.prototype._setLength=function(len){this._bitField=-262144&this._bitField|262143&len},Promise.prototype._setFulfilled=function(){this._bitField=268435456|this._bitField},Promise.prototype._setRejected=function(){this._bitField=134217728|this._bitField},Promise.prototype._setFollowing=function(){this._bitField=536870912|this._bitField},Promise.prototype._setIsFinal=function(){this._bitField=33554432|this._bitField},Promise.prototype._isFinal=function(){return(33554432&this._bitField)>0},Promise.prototype._cancellable=function(){return(67108864&this._bitField)>0},Promise.prototype._setCancellable=function(){this._bitField=67108864|this._bitField},Promise.prototype._unsetCancellable=function(){this._bitField=-67108865&this._bitField},Promise.prototype._setRejectionIsUnhandled=function(){this._bitField=2097152|this._bitField},Promise.prototype._unsetRejectionIsUnhandled=function(){this._bitField=-2097153&this._bitField,this._isUnhandledRejectionNotified()&&(this._unsetUnhandledRejectionIsNotified(),this._notifyUnhandledRejectionIsHandled())},Promise.prototype._isRejectionUnhandled=function(){return(2097152&this._bitField)>0},Promise.prototype._setUnhandledRejectionIsNotified=function(){this._bitField=524288|this._bitField},Promise.prototype._unsetUnhandledRejectionIsNotified=function(){this._bitField=-524289&this._bitField},Promise.prototype._isUnhandledRejectionNotified=function(){return(524288&this._bitField)>0},Promise.prototype._setCarriedStackTrace=function(capturedTrace){this._bitField=1048576|this._bitField,this._fulfillmentHandler0=capturedTrace},Promise.prototype._unsetCarriedStackTrace=function(){this._bitField=-1048577&this._bitField,this._fulfillmentHandler0=void 0},Promise.prototype._isCarryingStackTrace=function(){return(1048576&this._bitField)>0},Promise.prototype._getCarriedStackTrace=function(){return this._isCarryingStackTrace()?this._fulfillmentHandler0:void 0},Promise.prototype._receiverAt=function(index){var ret=0===index?this._receiver0:this[(index<<2)+index-5+4];return this._isBound()&&void 0===ret?this._boundTo:ret},Promise.prototype._promiseAt=function(index){return 0===index?this._promise0:this[(index<<2)+index-5+3]},Promise.prototype._fulfillmentHandlerAt=function(index){return 0===index?this._fulfillmentHandler0:this[(index<<2)+index-5+0]},Promise.prototype._rejectionHandlerAt=function(index){return 0===index?this._rejectionHandler0:this[(index<<2)+index-5+1]},Promise.prototype._addCallbacks=function(fulfill,reject,progress,promise,receiver){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promise,void 0!==receiver&&(this._receiver0=receiver),"function"!=typeof fulfill||this._isCarryingStackTrace()||(this._fulfillmentHandler0=fulfill),"function"==typeof reject&&(this._rejectionHandler0=reject),"function"==typeof progress&&(this._progressHandler0=progress);else{var base=(index<<2)+index-5;this[base+3]=promise,this[base+4]=receiver,this[base+0]="function"==typeof fulfill?fulfill:void 0,this[base+1]="function"==typeof reject?reject:void 0,this[base+2]="function"==typeof progress?progress:void 0}return this._setLength(index+1),index},Promise.prototype._setProxyHandlers=function(receiver,promiseSlotValue){var index=this._length();if(index>=262138&&(index=0,this._setLength(0)),0===index)this._promise0=promiseSlotValue,this._receiver0=receiver;else{var base=(index<<2)+index-5;this[base+3]=promiseSlotValue,this[base+4]=receiver,this[base+0]=this[base+1]=this[base+2]=void 0}this._setLength(index+1)},Promise.prototype._proxyPromiseArray=function(promiseArray,index){this._setProxyHandlers(promiseArray,index)},Promise.prototype._proxyPromise=function(promise){promise._setProxied(),this._setProxyHandlers(promise,-15)},Promise.prototype._setBoundTo=function(obj){void 0!==obj?(this._bitField=8388608|this._bitField,this._boundTo=obj):this._bitField=-8388609&this._bitField},Promise.prototype._isBound=function(){return 8388608===(8388608&this._bitField)},Promise.prototype._resolveFromResolver=function(resolver){function Promise$_resolver(val){promise._tryFollow(val)||promise._fulfill(val)}function Promise$_rejecter(val){var trace=canAttach(val)?val:new Error(val+"");promise._attachExtraTrace(trace),markAsOriginatingFromRejection(val),promise._reject(val,trace===val?void 0:trace)}var promise=this;this._setTrace(void 0),this._pushContext();var r=tryCatch2(resolver,void 0,Promise$_resolver,Promise$_rejecter);if(this._popContext(),void 0!==r&&r===errorObj){var e=r.e,trace=canAttach(e)?e:new Error(e+"");promise._reject(e,trace)}},Promise.prototype._spreadSlowCase=function(targetFn,promise,values,boundTo){var promiseForAll=new PromiseArray(values).promise(),promise2=promiseForAll._then(function(){return targetFn.apply(boundTo,arguments)},void 0,void 0,APPLY,void 0);promise._follow(promise2)},Promise.prototype._callSpread=function(handler,promise,value){var boundTo=this._boundTo;if(isArray(value))for(var i=0,len=value.length;len>i;++i)if(cast(value[i],void 0)instanceof Promise)return void this._spreadSlowCase(handler,promise,value,boundTo);return promise._pushContext(),tryCatchApply(handler,value,boundTo)},Promise.prototype._callHandler=function(handler,receiver,promise,value){var x;return receiver!==APPLY||this.isRejected()?(promise._pushContext(),x=tryCatch1(handler,receiver,value)):x=this._callSpread(handler,promise,value),promise._popContext(),x},Promise.prototype._settlePromiseFromHandler=function(handler,receiver,value,promise){if(!(promise instanceof Promise))return void handler.call(receiver,value,promise);var x=this._callHandler(handler,receiver,promise,value);if(!promise._isFollowing())if(x===errorObj||x===promise||x===NEXT_FILTER){var err=x===promise?makeSelfResolutionError():x.e,trace=canAttach(err)?err:new Error(err+""); +x!==NEXT_FILTER&&promise._attachExtraTrace(trace),promise._rejectUnchecked(err,trace)}else{var castValue=cast(x,promise);if(castValue instanceof Promise){if(castValue.isRejected()&&!castValue._isCarryingStackTrace()&&!canAttach(castValue._settledValue)){var trace=new Error(castValue._settledValue+"");promise._attachExtraTrace(trace),castValue._setCarriedStackTrace(trace)}promise._follow(castValue),promise._propagateFrom(castValue,1)}else promise._fulfillUnchecked(x)}},Promise.prototype._follow=function(promise){this._setFollowing(),promise.isPending()?(this._propagateFrom(promise,1),promise._proxyPromise(this)):promise.isFulfilled()?this._fulfillUnchecked(promise._settledValue):this._rejectUnchecked(promise._settledValue,promise._getCarriedStackTrace()),promise._isRejectionUnhandled()&&promise._unsetRejectionIsUnhandled(),debugging&&null==promise._traceParent&&(promise._traceParent=this)},Promise.prototype._tryFollow=function(value){if(this._isFollowingOrFulfilledOrRejected()||value===this)return!1;var maybePromise=cast(value,void 0);return maybePromise instanceof Promise?(this._follow(maybePromise),!0):!1},Promise.prototype._resetTrace=function(){debugging&&(this._trace=new CapturedTrace(void 0===this._peekContext()))},Promise.prototype._setTrace=function(parent){if(debugging){var context=this._peekContext();this._traceParent=context;var isTopLevel=void 0===context;void 0!==parent&&parent._traceParent===context?this._trace=parent._trace:this._trace=new CapturedTrace(isTopLevel)}return this},Promise.prototype._attachExtraTrace=function(error){if(debugging){var promise=this,stack=error.stack;stack="string"==typeof stack?stack.split("\n"):[],CapturedTrace.protectErrorMessageNewlines(stack);for(var headerLineCount=1,combinedTraces=1;null!=promise&&null!=promise._trace;)stack=CapturedTrace.combine(stack,promise._trace.stack.split("\n")),promise=promise._traceParent,combinedTraces++;var stackTraceLimit=Error.stackTraceLimit||10,max=(stackTraceLimit+headerLineCount)*combinedTraces,len=stack.length;len>max&&(stack.length=max),len>0&&(stack[0]=stack[0].split("\x00").join("\n")),stack.length<=headerLineCount?error.stack="(No stack trace)":error.stack=stack.join("\n")}},Promise.prototype._cleanValues=function(){this._cancellable()&&(this._cancellationParent=void 0)},Promise.prototype._propagateFrom=function(parent,flags){(1&flags)>0&&parent._cancellable()&&(this._setCancellable(),this._cancellationParent=parent),(4&flags)>0&&this._setBoundTo(parent._boundTo),(2&flags)>0&&this._setTrace(parent)},Promise.prototype._fulfill=function(value){this._isFollowingOrFulfilledOrRejected()||this._fulfillUnchecked(value)},Promise.prototype._reject=function(reason,carriedStackTrace){this._isFollowingOrFulfilledOrRejected()||this._rejectUnchecked(reason,carriedStackTrace)},Promise.prototype._settlePromiseAt=function(index){var handler=this.isFulfilled()?this._fulfillmentHandlerAt(index):this._rejectionHandlerAt(index),value=this._settledValue,receiver=this._receiverAt(index),promise=this._promiseAt(index);if("function"==typeof handler)this._settlePromiseFromHandler(handler,receiver,value,promise);else{var done=!1,isFulfilled=this.isFulfilled();void 0!==receiver&&(receiver instanceof Promise&&receiver._isProxied()?(receiver._unsetProxied(),isFulfilled?receiver._fulfillUnchecked(value):receiver._rejectUnchecked(value,this._getCarriedStackTrace()),done=!0):receiver instanceof PromiseArray&&(isFulfilled?receiver._promiseFulfilled(value,promise):receiver._promiseRejected(value,promise),done=!0)),done||(isFulfilled?promise._fulfill(value):promise._reject(value,this._getCarriedStackTrace()))}index>=4&&this._queueGC()},Promise.prototype._isProxied=function(){return 4194304===(4194304&this._bitField)},Promise.prototype._setProxied=function(){this._bitField=4194304|this._bitField},Promise.prototype._unsetProxied=function(){this._bitField=-4194305&this._bitField},Promise.prototype._isGcQueued=function(){return-1073741824===(-1073741824&this._bitField)},Promise.prototype._setGcQueued=function(){this._bitField=-1073741824|this._bitField},Promise.prototype._unsetGcQueued=function(){this._bitField=1073741823&this._bitField},Promise.prototype._queueGC=function(){this._isGcQueued()||(this._setGcQueued(),async.invokeLater(this._gc,this,void 0))},Promise.prototype._gc=function(){for(var len=5*this._length()-5,i=0;len>i;i++)delete this[i];this._clearFirstHandlerData(),this._setLength(0),this._unsetGcQueued()},Promise.prototype._clearFirstHandlerData=function(){this._fulfillmentHandler0=void 0,this._rejectionHandler0=void 0,this._promise0=void 0,this._receiver0=void 0},Promise.prototype._queueSettleAt=function(index){this._isRejectionUnhandled()&&this._unsetRejectionIsUnhandled(),async.invoke(this._settlePromiseAt,this,index)},Promise.prototype._fulfillUnchecked=function(value){if(this.isPending()){if(value===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err,void 0)}this._cleanValues(),this._setFulfilled(),this._settledValue=value;var len=this._length();len>0&&async.invoke(this._settlePromises,this,len)}},Promise.prototype._rejectUncheckedCheckError=function(reason){var trace=canAttach(reason)?reason:new Error(reason+"");this._rejectUnchecked(reason,trace===reason?void 0:trace)},Promise.prototype._rejectUnchecked=function(reason,trace){if(this.isPending()){if(reason===this){var err=makeSelfResolutionError();return this._attachExtraTrace(err),this._rejectUnchecked(err)}if(this._cleanValues(),this._setRejected(),this._settledValue=reason,this._isFinal())return void async.invokeLater(thrower,void 0,void 0===trace?reason:trace);var len=this._length();void 0!==trace&&this._setCarriedStackTrace(trace),len>0?async.invoke(this._rejectPromises,this,null):this._ensurePossibleRejectionHandled()}},Promise.prototype._rejectPromises=function(){this._settlePromises(),this._unsetCarriedStackTrace()},Promise.prototype._settlePromises=function(){for(var len=this._length(),i=0;len>i;i++)this._settlePromiseAt(i)},Promise.prototype._ensurePossibleRejectionHandled=function(){this._setRejectionIsUnhandled(),void 0!==CapturedTrace.possiblyUnhandledRejection&&async.invokeLater(this._notifyUnhandledRejection,this,void 0)},Promise.prototype._notifyUnhandledRejectionIsHandled=function(){"function"==typeof unhandledRejectionHandled&&async.invokeLater(unhandledRejectionHandled,void 0,this)},Promise.prototype._notifyUnhandledRejection=function(){if(this._isRejectionUnhandled()){var reason=this._settledValue,trace=this._getCarriedStackTrace();this._setUnhandledRejectionIsNotified(),void 0!==trace&&(this._unsetCarriedStackTrace(),reason=trace),"function"==typeof CapturedTrace.possiblyUnhandledRejection&&CapturedTrace.possiblyUnhandledRejection(reason,this)}};var contextStack=[];return Promise.prototype._peekContext=function(){var lastIndex=contextStack.length-1;return lastIndex>=0?contextStack[lastIndex]:void 0},Promise.prototype._pushContext=function(){debugging&&contextStack.push(this)},Promise.prototype._popContext=function(){debugging&&contextStack.pop()},Promise.noConflict=function(){return noConflict(Promise)},Promise.setScheduler=function(fn){if("function"!=typeof fn)throw new TypeError("fn must be a function");async._schedule=fn},CapturedTrace.isSupported()||(Promise.longStackTraces=function(){},debugging=!1),Promise._makeSelfResolutionError=makeSelfResolutionError,_dereq_("./finally.js")(Promise,NEXT_FILTER,cast),_dereq_("./direct_resolve.js")(Promise),_dereq_("./synchronous_inspection.js")(Promise),_dereq_("./join.js")(Promise,PromiseArray,cast,INTERNAL),Promise.RangeError=RangeError,Promise.CancellationError=CancellationError,Promise.TimeoutError=TimeoutError,Promise.TypeError=TypeError,Promise.OperationalError=OperationalError,Promise.RejectionError=OperationalError,Promise.AggregateError=errors.AggregateError,util.toFastProperties(Promise),util.toFastProperties(Promise.prototype),Promise.Promise=Promise,_dereq_("./nodeify.js")(Promise),Promise.prototype=Promise.prototype,Promise}},{"./async.js":1,"./captured_trace.js":3,"./catch_filter.js":4,"./direct_resolve.js":5,"./errors.js":6,"./errors_api_rejection":7,"./finally.js":9,"./join.js":10,"./nodeify.js":11,"./promise_array.js":13,"./promise_resolver.js":14,"./synchronous_inspection.js":17,"./thenables.js":18,"./util.js":19}],13:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL,cast){function toResolutionValue(val){switch(val){case-1:return;case-2:return[];case-3:return{}}}function PromiseArray(values){var promise=this._promise=new Promise(INTERNAL),parent=void 0;values instanceof Promise&&(parent=values,promise._propagateFrom(parent,5)),promise._setTrace(parent),this._values=values,this._length=0,this._totalResolved=0,this._init(void 0,-2)}var canAttach=_dereq_("./errors.js").canAttach,util=_dereq_("./util.js"),isArray=util.isArray;return PromiseArray.prototype.length=function(){return this._length},PromiseArray.prototype.promise=function(){return this._promise},PromiseArray.prototype._init=function PromiseArray$_init(_,resolveValueIfEmpty){var values=cast(this._values,void 0);if(values instanceof Promise){if(this._values=values,values._setBoundTo(this._promise._boundTo),!values.isFulfilled())return values.isPending()?void values._then(PromiseArray$_init,this._reject,void 0,this,resolveValueIfEmpty):(values._unsetRejectionIsUnhandled(),void this._reject(values._settledValue));if(values=values._settledValue,!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}}else if(!isArray(values)){var err=new Promise.TypeError("expecting an array, a promise or a thenable");return void this.__hardReject__(err)}if(0===values.length)return void(-5===resolveValueIfEmpty?this._resolveEmptyArray():this._resolve(toResolutionValue(resolveValueIfEmpty)));for(var len=this.getActualLength(values.length),newLen=len,newValues=this.shouldCopyValues()?new Array(len):this._values,isDirectScanNeeded=!1,i=0;len>i;++i){var maybePromise=cast(values[i],void 0);maybePromise instanceof Promise?maybePromise.isPending()?maybePromise._proxyPromiseArray(this,i):(maybePromise._unsetRejectionIsUnhandled(),isDirectScanNeeded=!0):isDirectScanNeeded=!0,newValues[i]=maybePromise}this._values=newValues,this._length=newLen,isDirectScanNeeded&&this._scanDirectValues(len)},PromiseArray.prototype._settlePromiseAt=function(index){var value=this._values[index];value instanceof Promise?value.isFulfilled()?this._promiseFulfilled(value._settledValue,index):value.isRejected()&&this._promiseRejected(value._settledValue,index):this._promiseFulfilled(value,index)},PromiseArray.prototype._scanDirectValues=function(len){for(var i=0;len>i&&!this._isResolved();++i)this._settlePromiseAt(i)},PromiseArray.prototype._isResolved=function(){return null===this._values},PromiseArray.prototype._resolve=function(value){this._values=null,this._promise._fulfill(value)},PromiseArray.prototype.__hardReject__=PromiseArray.prototype._reject=function(reason){this._values=null;var trace=canAttach(reason)?reason:new Error(reason+"");this._promise._attachExtraTrace(trace),this._promise._reject(reason,trace)},PromiseArray.prototype._promiseProgressed=function(progressValue,index){this._isResolved()||this._promise._progress({index:index,value:progressValue})},PromiseArray.prototype._promiseFulfilled=function(value,index){if(!this._isResolved()){this._values[index]=value;var totalResolved=++this._totalResolved;totalResolved>=this._length&&this._resolve(this._values)}},PromiseArray.prototype._promiseRejected=function(reason,index){this._isResolved()||(this._totalResolved++,this._reject(reason))},PromiseArray.prototype.shouldCopyValues=function(){return!0},PromiseArray.prototype.getActualLength=function(len){return len},PromiseArray}},{"./errors.js":6,"./util.js":19}],14:[function(_dereq_,module,exports){"use strict";function isUntypedError(obj){return obj instanceof Error&&es5.getPrototypeOf(obj)===Error.prototype}function wrapAsOperationalError(obj){var ret;return ret=isUntypedError(obj)?new OperationalError(obj):obj,errors.markAsOriginatingFromRejection(ret),ret}function nodebackForPromise(promise){function PromiseResolver$_callback(err,value){if(null!==promise){if(err){var wrapped=wrapAsOperationalError(maybeWrapAsError(err));promise._attachExtraTrace(wrapped),promise._reject(wrapped)}else if(arguments.length>2){for(var $_len=arguments.length,args=new Array($_len-1),$_i=1;$_len>$_i;++$_i)args[$_i-1]=arguments[$_i];promise._fulfill(args)}else promise._fulfill(value);promise=null}}return PromiseResolver$_callback}var PromiseResolver,util=_dereq_("./util.js"),maybeWrapAsError=util.maybeWrapAsError,errors=_dereq_("./errors.js"),TimeoutError=errors.TimeoutError,OperationalError=errors.OperationalError,async=_dereq_("./async.js"),haveGetters=util.haveGetters,es5=_dereq_("./es5.js");if(PromiseResolver=haveGetters?function(promise){this.promise=promise}:function(promise){this.promise=promise,this.asCallback=nodebackForPromise(promise),this.callback=this.asCallback},haveGetters){var prop={get:function(){return nodebackForPromise(this.promise)}};es5.defineProperty(PromiseResolver.prototype,"asCallback",prop),es5.defineProperty(PromiseResolver.prototype,"callback",prop)}PromiseResolver._nodebackForPromise=nodebackForPromise,PromiseResolver.prototype.toString=function(){return"[object PromiseResolver]"},PromiseResolver.prototype.resolve=PromiseResolver.prototype.fulfill=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;promise._tryFollow(value)||async.invoke(promise._fulfill,promise,value)},PromiseResolver.prototype.reject=function(reason){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");var promise=this.promise;errors.markAsOriginatingFromRejection(reason);var trace=errors.canAttach(reason)?reason:new Error(reason+"");promise._attachExtraTrace(trace),async.invoke(promise._reject,promise,reason),trace!==reason&&async.invoke(this._setCarriedStackTrace,this,trace)},PromiseResolver.prototype.progress=function(value){if(!(this instanceof PromiseResolver))throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.");async.invoke(this.promise._progress,this.promise,value)},PromiseResolver.prototype.cancel=function(){async.invoke(this.promise.cancel,this.promise,void 0)},PromiseResolver.prototype.timeout=function(){this.reject(new TimeoutError("timeout"))},PromiseResolver.prototype.isResolved=function(){return this.promise.isResolved()},PromiseResolver.prototype.toJSON=function(){return this.promise.toJSON()},PromiseResolver.prototype._setCarriedStackTrace=function(trace){this.promise.isRejected()&&this.promise._setCarriedStackTrace(trace)},module.exports=PromiseResolver},{"./async.js":1,"./errors.js":6,"./es5.js":8,"./util.js":19}],15:[function(_dereq_,module,exports){"use strict";function arrayCopy(src,srcIndex,dst,dstIndex,len){for(var j=0;len>j;++j)dst[j+dstIndex]=src[j+srcIndex]}function Queue(capacity){this._capacity=capacity,this._length=0,this._front=0,this._makeCapacity()}Queue.prototype._willBeOverCapacity=function(size){return this._capacityi;++i)this[i]=void 0},Queue.prototype._checkCapacity=function(size){this._capacity=oldFront+length)arrayCopy(oldQueue,oldFront,this,0,length);else{var lengthBeforeWrapping=length-(oldFront+length&oldCapacity-1);arrayCopy(oldQueue,oldFront,this,0,lengthBeforeWrapping),arrayCopy(oldQueue,0,this,lengthBeforeWrapping,length-lengthBeforeWrapping)}},module.exports=Queue},{}],16:[function(_dereq_,module,exports){"use strict";var schedule,_MutationObserver;if("object"==typeof process&&"string"==typeof process.version)schedule=function(fn){process.nextTick(fn)};else if("undefined"!=typeof MutationObserver&&(_MutationObserver=MutationObserver)||"undefined"!=typeof WebKitMutationObserver&&(_MutationObserver=WebKitMutationObserver))schedule=function(){var div=document.createElement("div"),queuedFn=void 0,observer=new _MutationObserver(function(){var fn=queuedFn;queuedFn=void 0,fn()});return observer.observe(div,{attributes:!0}),function(fn){queuedFn=fn,div.classList.toggle("foo")}}();else{if("undefined"==typeof setTimeout)throw new Error("no async scheduler available");schedule=function(fn){setTimeout(fn,0)}}module.exports=schedule},{}],17:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise){function PromiseInspection(promise){void 0!==promise?(this._bitField=promise._bitField,this._settledValue=promise.isResolved()?promise._settledValue:void 0):(this._bitField=0,this._settledValue=void 0)}PromiseInspection.prototype.isFulfilled=Promise.prototype.isFulfilled=function(){return(268435456&this._bitField)>0},PromiseInspection.prototype.isRejected=Promise.prototype.isRejected=function(){return(134217728&this._bitField)>0},PromiseInspection.prototype.isPending=Promise.prototype.isPending=function(){return 0===(402653184&this._bitField)},PromiseInspection.prototype.value=Promise.prototype.value=function(){if(!this.isFulfilled())throw new TypeError("cannot get fulfillment value of a non-fulfilled promise");return this._settledValue},PromiseInspection.prototype.error=PromiseInspection.prototype.reason=Promise.prototype.reason=function(){if(!this.isRejected())throw new TypeError("cannot get rejection reason of a non-rejected promise");return this._settledValue},PromiseInspection.prototype.isResolved=Promise.prototype.isResolved=function(){return(402653184&this._bitField)>0},Promise.PromiseInspection=PromiseInspection}},{}],18:[function(_dereq_,module,exports){"use strict";module.exports=function(Promise,INTERNAL){function getThen(obj){try{return obj.then}catch(e){return errorObj.e=e,errorObj}}function Promise$_Cast(obj,originalPromise){if(isObject(obj)){if(obj instanceof Promise)return obj;if(isAnyBluebirdPromise(obj)){var ret=new Promise(INTERNAL);return ret._setTrace(void 0),obj._then(ret._fulfillUnchecked,ret._rejectUncheckedCheckError,ret._progressUnchecked,ret,null),ret._setFollowing(),ret}var then=getThen(obj);if(then===errorObj)return void 0!==originalPromise&&canAttach(then.e)&&originalPromise._attachExtraTrace(then.e),Promise.reject(then.e);if("function"==typeof then)return Promise$_doThenable(obj,then,originalPromise)}return obj}function isAnyBluebirdPromise(obj){return hasProp.call(obj,"_promise0")}function Promise$_doThenable(x,then,originalPromise){function Promise$_resolveFromThenable(y){if(!called){if(called=!0,x===y){var e=Promise._makeSelfResolutionError();return void 0!==originalPromise&&originalPromise._attachExtraTrace(e),void resolver.promise._reject(e,void 0)}resolver.resolve(y)}}function Promise$_rejectFromThenable(r){if(!called){called=!0;var trace=canAttach(r)?r:new Error(r+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(r,trace)}}function Promise$_progressFromThenable(v){if(!called){var promise=resolver.promise;"function"==typeof promise._progress&&promise._progress(v)}}var resolver=Promise.defer(),called=!1;try{then.call(x,Promise$_resolveFromThenable,Promise$_rejectFromThenable,Promise$_progressFromThenable)}catch(e){if(!called){called=!0;var trace=canAttach(e)?e:new Error(e+"");void 0!==originalPromise&&originalPromise._attachExtraTrace(trace),resolver.promise._reject(e,trace)}}return resolver.promise}var util=_dereq_("./util.js"),canAttach=_dereq_("./errors.js").canAttach,errorObj=util.errorObj,isObject=util.isObject,hasProp={}.hasOwnProperty;return Promise$_Cast}},{"./errors.js":6,"./util.js":19}],19:[function(_dereq_,module,exports){"use strict";function tryCatch1(fn,receiver,arg){try{return fn.call(receiver,arg)}catch(e){return errorObj.e=e,errorObj}}function tryCatch2(fn,receiver,arg,arg2){try{return fn.call(receiver,arg,arg2)}catch(e){return errorObj.e=e,errorObj}}function tryCatch3(fn,receiver,arg,arg2,arg3){try{return fn.call(receiver,arg,arg2,arg3)}catch(e){return errorObj.e=e,errorObj}}function tryCatch4(fn,receiver,arg,arg2,arg3,arg4){try{return fn.call(receiver,arg,arg2,arg3,arg4)}catch(e){return errorObj.e=e,errorObj}}function tryCatchApply(fn,args,receiver){try{return fn.apply(receiver,args)}catch(e){return errorObj.e=e,errorObj}}function asString(val){return"string"==typeof val?val:""+val}function isPrimitive(val){return null==val||val===!0||val===!1||"string"==typeof val||"number"==typeof val}function isObject(value){return!isPrimitive(value)}function maybeWrapAsError(maybeError){return isPrimitive(maybeError)?new Error(asString(maybeError)):maybeError}function withAppended(target,appendee){var i,len=target.length,ret=new Array(len+1);for(i=0;len>i;++i)ret[i]=target[i];return ret[i]=appendee,ret}function getDataPropertyOrDefault(obj,key,defaultValue){if(!es5.isES5)return{}.hasOwnProperty.call(obj,key)?obj[key]:void 0;var desc=Object.getOwnPropertyDescriptor(obj,key);return null!=desc?null==desc.get&&null==desc.set?desc.value:defaultValue:void 0}function notEnumerableProp(obj,name,value){if(isPrimitive(obj))return obj;var descriptor={value:value,configurable:!0,enumerable:!1,writable:!0};return es5.defineProperty(obj,name,descriptor),obj}function thrower(r){throw r}function isClass(fn){try{if("function"==typeof fn){var keys=es5.keys(fn.prototype);return keys.length>0&&!(1===keys.length&&"constructor"===keys[0])}return!1}catch(e){return!1}}function toFastProperties(obj){function f(){}return f.prototype=obj,f}function isIdentifier(str){return rident.test(str)}function filledRange(count,prefix,suffix){for(var ret=new Array(count),i=0;count>i;++i)ret[i]=prefix+i+suffix;return ret}var es5=_dereq_("./es5.js"),haveGetters=function(){try{var o={};return es5.defineProperty(o,"f",{get:function(){return 3}}),3===o.f}catch(e){return!1}}(),canEvaluate="undefined"==typeof navigator,errorObj={e:{}},inherits=function(Child,Parent){function T(){this.constructor=Child,this.constructor$=Parent;for(var propertyName in Parent.prototype)hasProp.call(Parent.prototype,propertyName)&&"$"!==propertyName.charAt(propertyName.length-1)&&(this[propertyName+"$"]=Parent.prototype[propertyName])}var hasProp={}.hasOwnProperty;return T.prototype=Parent.prototype,Child.prototype=new T,Child.prototype},wrapsPrimitiveReceiver=function(){return"string"!==this}.call("string"),inheritedDataKeys=function(){return es5.isES5?function(obj,opts){for(var ret=[],visitedKeys=Object.create(null),getKeys=Object(opts).includeHidden?Object.getOwnPropertyNames:Object.keys;null!=obj;){var keys;try{keys=getKeys(obj)}catch(e){return ret}for(var i=0;i=n&&(this._init(),RemoteStorage.log("Done cleaning up, emitting disconnected and disconnect events"),this._emit("disconnected"))}.bind(this);n>0?this._cleanups.forEach(function(cleanup){var cleanupResult=cleanup(this);"object"==typeof cleanupResult&&"function"==typeof cleanupResult.then?cleanupResult.then(oneDone):oneDone()}.bind(this)):oneDone()},setBackend:function(what){this.backend=what,hasLocalStorage&&(what?localStorage.setItem("remotestorage:backend",what):localStorage.removeItem("remotestorage:backend"))},onChange:function(path,handler){this._pathHandlers.change[path]||(this._pathHandlers.change[path]=[]),this._pathHandlers.change[path].push(handler)},enableLog:function(){RemoteStorage.config.logging=!0},disableLog:function(){RemoteStorage.config.logging=!1},log:function(){RemoteStorage.log.apply(RemoteStorage,arguments)},setApiKeys:function(type,keys){keys?(this.apiKeys[type]=keys,"dropbox"!==type||"undefined"!=typeof this.dropbox&&this.dropbox.clientId===keys.appKey?"googledrive"!==type||"undefined"!=typeof this.googledrive&&this.googledrive.clientId===keys.clientId||RemoteStorage.GoogleDrive._rs_init(this):RemoteStorage.Dropbox._rs_init(this)):delete this.apiKeys[type],hasLocalStorage&&localStorage.setItem("remotestorage:api-keys",JSON.stringify(this.apiKeys))},setCordovaRedirectUri:function(uri){if("string"!=typeof uri||!uri.match(/http(s)?\:\/\//))throw new Error("Cordova redirect URI must be a URI string"); +RemoteStorage.config.cordovaRedirectUri=uri},_init:function(){function fireReady(){try{readyFired||(self._emit("ready"),readyFired=!0)}catch(e){console.error("'ready' failed: ",e,e.stack),self._emit("error",e)}}var self=this,readyFired=!1;this._loadFeatures(function(features){this.log("[RemoteStorage] All features loaded"),this.local=features.local&&new features.local,this.local&&this.remote?(this._setGPD(SyncedGetPutDelete,this),this._bindChange(this.local)):this.remote&&this._setGPD(this.remote,this.remote),this.remote&&(this.remote.on("connected",function(){fireReady(),self._emit("connected")}),this.remote.on("not-connected",function(){fireReady(),self._emit("not-connected")}),this.remote.connected&&(fireReady(),self._emit("connected")),this.hasFeature("Authorize")||this.remote.stopWaitingForToken()),this._collectCleanupFunctions();try{this._allLoaded=!0,this._emit("features-loaded")}catch(exc){logError(exc),this._emit("error",exc)}this._processPending()}.bind(this))},_collectCleanupFunctions:function(){this._cleanups=[];for(var i=0;i=0;i--)if(this.features[i].name===feature)return this.features[i].supported;return!1},_setGPD:function(impl,context){function wrap(func){return function(){return func.apply(context,arguments).then(emitUnauthorized.bind(this))}}this.get=wrap(impl.get),this.put=wrap(impl.put),this["delete"]=wrap(impl["delete"])},_pendingGPD:function(methodName){return function(){var pending=Promise.defer();return this._pending.push({method:methodName,args:Array.prototype.slice.call(arguments),promise:pending}),pending.promise}.bind(this)},_processPending:function(){this._pending.forEach(function(pending){try{this[pending.method].apply(this,pending.args).then(pending.promise.resolve,pending.promise.reject)}catch(e){pending.promise.reject(e)}}.bind(this)),this._pending=[]},_bindChange:function(object){object.on("change",this._dispatchEvent.bind(this,"change"))},_dispatchEvent:function(eventName,event){var self=this;Object.keys(this._pathHandlers[eventName]).forEach(function(path){var pl=path.length;event.path.substr(0,pl)===path&&self._pathHandlers[eventName][path].forEach(function(handler){var ev={};for(var key in event)ev[key]=event[key];ev.relativePath=event.path.replace(new RegExp("^"+path),"");try{handler(ev)}catch(e){console.error("'change' handler failed: ",e,e.stack),self._emit("error",e)}})})}},Object.defineProperty(RemoteStorage.prototype,"connected",{get:function(){return this.remote.connected}}),global.RemoteStorage=RemoteStorage,"object"==typeof module&&"undefined"!=typeof module.exports&&(module.exports=RemoteStorage)}("undefined"!=typeof window?window:global),function(global){function fixArrayBuffers(srcObj,dstObj){var field,srcArr,dstArr;if("object"==typeof srcObj&&!Array.isArray(srcObj)&&null!==srcObj)for(field in srcObj)"object"==typeof srcObj[field]&&null!==srcObj[field]&&("[object ArrayBuffer]"===srcObj[field].toString()?(dstObj[field]=new ArrayBuffer(srcObj[field].byteLength),srcArr=new Int8Array(srcObj[field]),dstArr=new Int8Array(dstObj[field]),dstArr.set(srcArr)):fixArrayBuffers(srcObj[field],dstObj[field]))}RemoteStorage.util={getEventEmitter:function(){var object={},args=Array.prototype.slice.call(arguments);return args.unshift(object),RemoteStorage.eventHandling.apply(RemoteStorage,args),object.emit=object._emit,object},extend:function(target){var sources=Array.prototype.slice.call(arguments,1);return sources.forEach(function(source){for(var key in source)target[key]=source[key]}),target},asyncEach:function(array,callback){return this.asyncMap(array,callback).then(function(){return array})},asyncMap:function(array,callback){function oneDone(){i++,i===n&&pending.resolve(results,errors)}var pending=Promise.defer(),n=array.length,i=0,results=[],errors=[];return array.forEach(function(item,index){var result;try{result=callback(item)}catch(exc){oneDone(),errors[index]=exc}"object"==typeof result&&"function"==typeof result.then?result.then(function(res){results[index]=res,oneDone()},function(error){errors[index]=error,oneDone()}):(oneDone(),results[index]=result)}),pending.promise},containingFolder:function(path){if(""===path)return"/";if(!path)throw"Path not given!";return path.replace(/\/+/g,"/").replace(/[^\/]+\/?$/,"")},isFolder:function(path){return"/"===path.substr(-1)},isDocument:function(path){return!RemoteStorage.util.isFolder(path)},baseName:function(path){var parts=path.split("/");return this.isFolder(path)?parts[parts.length-2]+"/":parts[parts.length-1]},cleanPath:function(path){return path.replace(/\/+/g,"/").split("/").map(encodeURIComponent).join("/").replace(/'/g,"%27")},bindAll:function(object){for(var key in this)"function"==typeof object[key]&&(object[key]=object[key].bind(object))},equal:function(a,b,seen){var key;if(seen=seen||[],typeof a!=typeof b)return!1;if("number"==typeof a||"boolean"==typeof a||"string"==typeof a)return a===b;if("function"==typeof a)return a.toString()===b.toString();if(a instanceof ArrayBuffer&&b instanceof ArrayBuffer&&(a=new Uint8Array(a),b=new Uint8Array(b)),a instanceof Array){if(a.length!==b.length)return!1;for(var i=0,c=a.length;c>i;i++)if(!RemoteStorage.util.equal(a[i],b[i],seen))return!1}else{for(key in a)if(a.hasOwnProperty(key)&&!(key in b))return!1;for(key in b)if(b.hasOwnProperty(key)){if(!(key in a))return!1;var seenArg;if("object"==typeof b[key]){if(seen.indexOf(b[key])>=0)continue;seenArg=seen.slice(),seenArg.push(b[key])}if(!RemoteStorage.util.equal(a[key],b[key],seenArg))return!1}}return!0},equalObj:function(obj1,obj2){return console.warn("DEPRECATION WARNING: RemoteStorage.util.equalObj has been replaced by RemoteStorage.util.equal."),RemoteStorage.util.equal(obj1,obj2)},deepClone:function(obj){var clone;return void 0===obj?void 0:(clone=JSON.parse(JSON.stringify(obj)),fixArrayBuffers(obj,clone),clone)},pathsFromRoot:function(path){for(var paths=[path],parts=path.replace(/\/$/,"").split("/");parts.length>1;)parts.pop(),paths.push(parts.join("/")+"/");return paths},md5sum:function(str){function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),b=ff(b,c,d,a,k[15],22,1236535329),a=gg(a,b,c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),b=gg(b,c,d,a,k[12],20,-1926607734),a=hh(a,b,c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),b=hh(b,c,d,a,k[2],23,-995338651),a=ii(a,b,c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){txt="";var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;16>i;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;64>i;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}function rhex(n){for(var s="",j=0;4>j;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function hex(x){for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}),md5(str)},localStorageAvailable:function(){if(!("localStorage"in global))return!1;try{return global.localStorage.setItem("rs-check",1),global.localStorage.removeItem("rs-check"),!0}catch(error){return!1}}},RemoteStorage.prototype.util||Object.defineProperty(RemoteStorage.prototype,"util",{get:function(){return console.log("DEPRECATION WARNING: remoteStorage.util was moved to RemoteStorage.util"),RemoteStorage.util}})}("undefined"!=typeof window?window:global),function(global){var methods={addEventListener:function(eventName,handler){if("string"!=typeof eventName)throw new Error("Argument eventName should be a string");if("function"!=typeof handler)throw new Error("Argument handler should be a function");RemoteStorage.log("[Eventhandling] Adding event listener",eventName,handler),this._validateEvent(eventName),this._handlers[eventName].push(handler)},removeEventListener:function(eventName,handler){this._validateEvent(eventName);for(var hl=this._handlers[eventName].length,i=0;hl>i;i++)if(this._handlers[eventName][i]===handler)return void this._handlers[eventName].splice(i,1)},_emit:function(eventName){this._validateEvent(eventName);var args=Array.prototype.slice.call(arguments,1);this._handlers[eventName].slice().forEach(function(handler){handler.apply(this,args)})},_validateEvent:function(eventName){if(!(eventName in this._handlers))throw new Error("Unknown event: "+eventName)},_delegateEvent:function(eventName,target){target.on(eventName,function(event){this._emit(eventName,event)}.bind(this))},_addEvent:function(eventName){this._handlers[eventName]=[]}};methods.on=methods.addEventListener,RemoteStorage.eventHandling=function(object){var eventNames=Array.prototype.slice.call(arguments,1);for(var key in methods)object[key]=methods[key];object._handlers={},eventNames.forEach(function(eventName){object._addEvent(eventName)})}}("undefined"!=typeof window?window:global),function(global){function addQuotes(str){return"string"!=typeof str?str:"*"===str?"*":'"'+str+'"'}function stripQuotes(str){return"string"!=typeof str?str:str.replace(/^["']|["']$/g,"")}function readBinaryData(content,mimeType,callback){var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(content),blob=bb.getBlob(mimeType)}else blob=new Blob([content],{type:mimeType});var reader=new FileReader;"function"==typeof reader.addEventListener?reader.addEventListener("loadend",function(){callback(reader.result)}):reader.onloadend=function(){callback(reader.result)},reader.readAsArrayBuffer(blob)}function getTextFromArrayBuffer(arrayBuffer,encoding){var pending=Promise.defer();if("undefined"==typeof Blob){var buffer=new Buffer(new Uint8Array(arrayBuffer));pending.resolve(buffer.toString(encoding))}else{var blob;if(global.BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder,"undefined"!=typeof global.BlobBuilder){var bb=new global.BlobBuilder;bb.append(arrayBuffer),blob=bb.getBlob()}else blob=new Blob([arrayBuffer]);var fileReader=new FileReader;"function"==typeof fileReader.addEventListener?fileReader.addEventListener("loadend",function(evt){pending.resolve(evt.target.result)}):fileReader.onloadend=function(evt){pending.resolve(evt.target.result)},fileReader.readAsText(blob,encoding)}return pending.promise}function determineCharset(mimeType){var charsetMatch,charset="UTF-8";return mimeType&&(charsetMatch=mimeType.match(/charset=(.+)$/),charsetMatch&&(charset=charsetMatch[1])),charset}function isFolderDescription(body){return"http://remotestorage.io/spec/folder-description"===body["@context"]&&"object"==typeof body.items}function isSuccessStatus(status){return[201,204,304].indexOf(status)>=0}function isErrorStatus(status){return[401,403,404,412].indexOf(status)>=0}var hasLocalStorage,isArrayBufferView,RS=RemoteStorage,SETTINGS_KEY="remotestorage:wireclient",API_2012=1,API_00=2,API_01=3,API_02=4,API_HEAD=5,STORAGE_APIS={"draft-dejong-remotestorage-00":API_00,"draft-dejong-remotestorage-01":API_01,"draft-dejong-remotestorage-02":API_02,"https://www.w3.org/community/rww/wiki/read-write-web-00#simple":API_2012};if("function"==typeof ArrayBufferView)isArrayBufferView=function(object){return object&&object instanceof ArrayBufferView};else{var arrayBufferViews=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];isArrayBufferView=function(object){for(var i=0;8>i;i++)if(object instanceof arrayBufferViews[i])return!0;return!1}}var onErrorCb,isFolder=RemoteStorage.util.isFolder,cleanPath=RemoteStorage.util.cleanPath;RS.WireClient=function(rs){if(this.rs=rs,this.connected=!1,RS.eventHandling(this,"change","connected","not-connected","wire-busy","wire-done"),onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&this.configure({token:null})}.bind(this),rs.on("error",onErrorCb),hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&setTimeout(function(){this.configure(settings)}.bind(this),0)}this._revisionCache={},this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.WireClient.REQUEST_TIMEOUT=3e4,RS.WireClient.prototype={_request:function(method,uri,token,headers,body,getEtag,fakeRevision){if(("PUT"===method||"DELETE"===method)&&"/"===uri[uri.length-1])return Promise.reject("Don't "+method+" on directories!");var revision,self=this;return token!==RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN&&(headers.Authorization="Bearer "+token),this._emit("wire-busy",{method:method,isFolder:isFolder(uri)}),RS.WireClient.request(method,uri,{body:body,headers:headers,responseType:"arraybuffer"}).then(function(response){if(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!0}),isErrorStatus(response.status))return RemoteStorage.log("[WireClient] Error response status",response.status),revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):void 0,Promise.resolve({statusCode:response.status,revision:revision});if(isSuccessStatus(response.status)||200===response.status&&"GET"!==method)return revision=stripQuotes(response.getResponseHeader("ETag")),RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,revision:revision});var mimeType=response.getResponseHeader("Content-Type");revision=getEtag?stripQuotes(response.getResponseHeader("ETag")):200===response.status?fakeRevision:void 0;var charset=determineCharset(mimeType);return mimeType&&"binary"!==charset?getTextFromArrayBuffer(response.response,charset).then(function(body){return RemoteStorage.log("[WireClient] Successful request",revision),Promise.resolve({statusCode:response.status,body:body,contentType:mimeType,revision:revision})}):(RemoteStorage.log("[WireClient] Successful request with unknown or binary mime-type",revision),Promise.resolve({statusCode:response.status,body:response.response,contentType:mimeType,revision:revision}))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(uri),success:!1}),Promise.reject(error)})},configure:function(settings){if("object"!=typeof settings)throw new Error("WireClient configure settings parameter should be an object");"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.href&&(this.href=settings.href),"undefined"!=typeof settings.storageApi&&(this.storageApi=settings.storageApi),"undefined"!=typeof settings.token&&(this.token=settings.token),"undefined"!=typeof settings.properties&&(this.properties=settings.properties),"undefined"!=typeof this.storageApi&&(this._storageApi=STORAGE_APIS[this.storageApi]||API_HEAD,this.supportsRevs=this._storageApi>=API_00),this.href&&this.token?(this.connected=!0,this.online=!0,this._emit("connected")):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,href:this.href,storageApi:this.storageApi,token:this.token,properties:this.properties}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){var self=this;if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={});var headers={};if(this.supportsRevs)options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch));else if(options.ifNoneMatch){this._revisionCache[path]}return this._request("GET",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs,this._revisionCache[path]).then(function(r){if(!isFolder(path))return Promise.resolve(r);var itemsMap={};if("undefined"!=typeof r.body)try{r.body=JSON.parse(r.body)}catch(e){return Promise.reject("Folder description at "+self.href+cleanPath(path)+" is not JSON")}if(200===r.statusCode&&"object"==typeof r.body){if(0===Object.keys(r.body).length)r.statusCode=404;else if(isFolderDescription(r.body)){for(var item in r.body.items)self._revisionCache[path+item]=r.body.items[item].ETag;itemsMap=r.body.items}else Object.keys(r.body).forEach(function(key){self._revisionCache[path+key]=r.body[key],itemsMap[key]={ETag:r.body[key]}});return r.body=itemsMap,Promise.resolve(r)}return Promise.resolve(r)})},put:function(path,body,contentType,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");options||(options={}),!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||isArrayBufferView(body))&&(contentType+="; charset=binary");var headers={"Content-Type":contentType};return this.supportsRevs&&(options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),options.ifNoneMatch&&(headers["If-None-Match"]=addQuotes(options.ifNoneMatch))),this._request("PUT",this.href+cleanPath(path),this.token,headers,body,this.supportsRevs)},"delete":function(path,options){if(!this.connected)throw new Error("not connected (path: "+path+")");options||(options={});var headers={};return this.supportsRevs&&options.ifMatch&&(headers["If-Match"]=addQuotes(options.ifMatch)),this._request("DELETE",this.href+cleanPath(path),this.token,headers,void 0,this.supportsRevs)}},RS.WireClient.cleanPath=cleanPath,RS.WireClient.isArrayBufferView=isArrayBufferView,RS.WireClient.readBinaryData=readBinaryData,RS.WireClient.request=function(method,url,options){var pending=Promise.defer();RemoteStorage.log("[WireClient]",method,url);var timedOut=!1,timer=setTimeout(function(){timedOut=!0,pending.reject("timeout")},RS.WireClient.REQUEST_TIMEOUT),xhr=new XMLHttpRequest;if(xhr.open(method,url,!0),options.responseType&&(xhr.responseType=options.responseType),options.headers)for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key]);xhr.onload=function(){timedOut||(clearTimeout(timer),pending.resolve(xhr))},xhr.onerror=function(error){timedOut||(clearTimeout(timer),pending.reject(error))};var body=options.body;return"object"==typeof body&&!isArrayBufferView(body)&&body instanceof ArrayBuffer&&(body=new Uint8Array(body)),xhr.send(body),pending.promise},Object.defineProperty(RemoteStorage.WireClient.prototype,"storageType",{get:function(){if(this.storageApi){var spec=this.storageApi.match(/draft-dejong-(remotestorage-\d\d)/);return spec?spec[1]:"2012.04"}}}),RS.WireClient._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.remote=new RS.WireClient(remoteStorage),this.online=!0},RS.WireClient._rs_supported=function(){return!!global.XMLHttpRequest},RS.WireClient._rs_cleanup=function(remoteStorage){hasLocalStorage&&delete localStorage[SETTINGS_KEY],remoteStorage.removeEventListener("error",onErrorCb)}}("undefined"!=typeof window?window:global),function(global){var haveXMLHttpRequest,hasLocalStorage,SETTINGS_KEY="remotestorage:discover",cachedInfo={};RemoteStorage.Discover=function(userAddress){if(userAddress in cachedInfo)return Promise.resolve(cachedInfo[userAddress]);var webFinger=new WebFinger({tls_only:!1,uri_fallback:!0,request_timeout:5e3}),pending=Promise.defer();return webFinger.lookup(userAddress,function(err,response){if(err)return pending.reject(err);if("object"!=typeof response.idx.links.remotestorage||"number"!=typeof response.idx.links.remotestorage.length||response.idx.links.remotestorage.length<=0)return RemoteStorage.log("[Discover] WebFinger record for "+userAddress+" does not have remotestorage defined in the links section ",JSON.stringify(response.json)),pending.reject("WebFinger record for "+userAddress+" does not have remotestorage defined in the links section.");var rs=response.idx.links.remotestorage[0],authURL=rs.properties["http://tools.ietf.org/html/rfc6749#section-4.2"]||rs.properties["auth-endpoint"],storageType=rs.properties["http://remotestorage.io/spec/version"]||rs.type;return cachedInfo[userAddress]={href:rs.href,storageType:storageType,authURL:authURL,properties:rs.properties},hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({cache:cachedInfo})),pending.resolve(cachedInfo[userAddress])}),pending.promise},RemoteStorage.Discover._rs_init=function(remoteStorage){if(hasLocalStorage=RemoteStorage.util.localStorageAvailable()){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&(cachedInfo=settings.cache)}},RemoteStorage.Discover._rs_supported=function(){return haveXMLHttpRequest=!!global.XMLHttpRequest},RemoteStorage.Discover._rs_cleanup=function(){hasLocalStorage&&delete localStorage[SETTINGS_KEY]}}("undefined"!=typeof window?window:global),"undefined"==typeof XMLHttpRequest&&(XMLHttpRequest=require("xmlhttprequest").XMLHttpRequest),function(undefined){function generateErrorObject(obj){return obj.toString=function(){return this.message},obj}function isSecure(url){if("string"!=typeof url)return!1;var parts=url.split("://");return"https"===parts[0]?!0:!1}function WebFinger(config){"object"!=typeof config&&(config={}),this.config={tls_only:"undefined"!=typeof config.tls_only?config.tls_only:!0,webfist_fallback:"undefined"!=typeof config.webfist_fallback?config.webfist_fallback:!1,uri_fallback:"undefined"!=typeof config.uri_fallback?config.uri_fallback:!1,request_timeout:"undefined"!=typeof config.request_timeout?config.request_timeout:1e4}}var LINK_URI_MAPS={"http://webfist.org/spec/rel":"webfist","http://webfinger.net/rel/avatar":"avatar",remotestorage:"remotestorage","http://tools.ietf.org/id/draft-dejong-remotestorage":"remotestorage",remoteStorage:"remotestorage","http://www.packetizer.com/rel/share":"share","http://webfinger.net/rel/profile-page":"profile",me:"profile",vcard:"vcard",blog:"blog","http://packetizer.com/rel/blog":"blog","http://schemas.google.com/g/2010#updates-from":"updates","https://camlistore.org/rel/server":"camilstore"},LINK_PROPERTIES={avatar:[],remotestorage:[],blog:[],vcard:[],updates:[],share:[],profile:[],webfist:[],camlistore:[]},URIS=["webfinger","host-meta","host-meta.json"];if(WebFinger.prototype.__fetchJRD=function(url,errorHandler,sucessHandler){function __processState(){if(200===xhr.status)return self.__isValidJSON(xhr.responseText)?sucessHandler(xhr.responseText):errorHandler(generateErrorObject({message:"invalid json",url:url,status:xhr.status}));if(404===xhr.status)return errorHandler(generateErrorObject({message:"resource not found",url:url,status:xhr.status}));if(xhr.status>=301&&xhr.status<=302){var location=xhr.getResponseHeader("Location");return isSecure(location)?__makeRequest(location):errorHandler(generateErrorObject({message:"no redirect URL found",url:url,status:xhr.status}))}return errorHandler(generateErrorObject({message:"error during request",url:url,status:xhr.status}))}function __makeRequest(){xhr.onreadystatechange=function(){4===xhr.readyState&&__processState()},xhr.onload=function(a,b){__processState()},xhr.open("GET",url,!0),xhr.setRequestHeader("Accept","application/jrd+json, application/json"),xhr.send()}var self=this,xhr=new XMLHttpRequest;return __makeRequest()},WebFinger.prototype.__isValidJSON=function(str){try{JSON.parse(str)}catch(e){return!1}return!0},WebFinger.prototype.__isLocalhost=function(host){var local=/^localhost(\.localdomain)?(\:[0-9]+)?$/;return local.test(host)},WebFinger.prototype.__processJRD=function(URL,JRD,errorHandler,successHandler){var parsedJRD=JSON.parse(JRD);if("object"!=typeof parsedJRD||"object"!=typeof parsedJRD.links)return errorHandler("undefined"!=typeof parsedJRD.error?generateErrorObject({message:parsedJRD.error,request:URL}):generateErrorObject({message:"unknown response from server",request:URL}));var links=parsedJRD.links,result={object:parsedJRD,json:JRD,idx:{}};result.idx.properties={name:undefined},result.idx.links=JSON.parse(JSON.stringify(LINK_PROPERTIES)),links.map(function(link,i){if(LINK_URI_MAPS.hasOwnProperty(link.rel)&&result.idx.links[LINK_URI_MAPS[link.rel]]){var entry={};Object.keys(link).map(function(item,n){entry[item]=link[item]}),result.idx.links[LINK_URI_MAPS[link.rel]].push(entry)}});var props=JSON.parse(JRD).properties;for(var key in props)props.hasOwnProperty(key)&&"http://packetizer.com/ns/name"===key&&(result.idx.properties.name=props[key]);return successHandler(result)},WebFinger.prototype.lookup=function(address,cb){function __buildURL(){var uri="";return address.split("://")[1]||(uri="acct:"),protocol+"://"+host+"/.well-known/"+URIS[uri_index]+"?resource="+uri+address}function __fallbackChecks(err){if(self.config.uri_fallback&&"webfist.org"!==host&&uri_index!==URIS.length-1)return uri_index+=1,__call();if(!self.config.tls_only&&"https"===protocol)return uri_index=0,protocol="http",__call();if(!self.config.webfist_fallback||"webfist.org"===host)return cb(err);uri_index=0,protocol="http",host="webfist.org";var URL=__buildURL();self.__fetchJRD(URL,cb,function(data){self.__processJRD(URL,data,cb,function(result){"object"==typeof result.idx.links.webfist&&"string"==typeof result.idx.links.webfist[0].href&&self.__fetchJRD(result.idx.links.webfist[0].href,cb,function(JRD){self.__processJRD(URL,JRD,cb,function(result){return cb(null,cb)})})})})}function __call(){var URL=__buildURL();self.__fetchJRD(URL,__fallbackChecks,function(JRD){self.__processJRD(URL,JRD,cb,function(result){cb(null,result)})})}if("string"!=typeof address)throw new Error("first parameter must be a user address");if("function"!=typeof cb)throw new Error("second parameter must be a callback");var self=this,host="";host=address.indexOf("://")>-1?address.replace(/ /g,"").split("://")[1]:address.replace(/ /g,"").split("@")[1];var uri_index=0,protocol="https";return self.__isLocalhost(host)&&(protocol="http"),setTimeout(__call,0)},WebFinger.prototype.lookupLink=function(address,rel,cb){return LINK_PROPERTIES.hasOwnProperty(rel)?void this.lookup(address,function(err,p){var links=p.idx.links[rel];return err?cb(err):0===links.length?cb('no links found with rel="'+rel+'"'):cb(null,links[0])}):cb("unsupported rel "+rel)},"object"==typeof window)window.WebFinger=WebFinger;else if("function"==typeof define&&define.amd)define([],function(){return WebFinger});else try{module.exports=WebFinger}catch(e){}}(),function(global){function extractParams(url){var hash,location=url||RemoteStorage.Authorize.getLocation().href,hashPos=location.indexOf("#");if(-1!==hashPos&&(hash=location.substring(hashPos+1),-1!==hash.indexOf("=")))return hash.split("&").reduce(function(params,kvs){var kv=kvs.split("=");if("state"===kv[0]&&kv[1].match(/rsDiscovery/)){var stateValue=decodeURIComponent(kv[1]),encodedData=stateValue.substr(stateValue.indexOf("rsDiscovery=")).split("&")[0].split("=")[1];params.rsDiscovery=JSON.parse(atob(encodedData)),stateValue=stateValue.replace(new RegExp("&?rsDiscovery="+encodedData),""),stateValue.length>0&&(params.state=stateValue)}else params[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]);return params},{})}RemoteStorage.ImpliedAuth=function(storageApi,redirectUri){RemoteStorage.log("ImpliedAuth proceeding due to absent authURL; storageApi = "+storageApi+" redirectUri = "+redirectUri),remoteStorage.remote.configure({token:RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN}),document.location=redirectUri},RemoteStorage.Authorize=function(remoteStorage,authURL,scope,redirectUri,clientId){if(RemoteStorage.log("[Authorize] authURL = ",authURL,"scope = ",scope,"redirectUri = ",redirectUri,"clientId = ",clientId), +!RemoteStorage.util.localStorageAvailable()&&"remotestorage"===remoteStorage.backend){redirectUri+=redirectUri.indexOf("#")>0?"&":"#";var discoveryData={userAddress:remoteStorage.remote.userAddress,href:remoteStorage.remote.href,storageApi:remoteStorage.remote.storageApi,properties:remoteStorage.remote.properties};redirectUri+="rsDiscovery="+btoa(JSON.stringify(discoveryData))}var url=authURL,hashPos=redirectUri.indexOf("#");return url+=authURL.indexOf("?")>0?"&":"?",url+="redirect_uri="+encodeURIComponent(redirectUri.replace(/#.*$/,"")),url+="&scope="+encodeURIComponent(scope),url+="&client_id="+encodeURIComponent(clientId),-1!==hashPos&&hashPos+1!==redirectUri.length&&(url+="&state="+encodeURIComponent(redirectUri.substring(hashPos+1))),url+="&response_type=token",global.cordova?RemoteStorage.Authorize.openWindow(url,redirectUri,"location=yes,clearsessioncache=yes,clearcache=yes").then(function(authResult){remoteStorage.remote.configure({token:authResult.access_token})}).then(null,function(error){console.error(error),remoteStorage.widget.view.setState("initial")}):void RemoteStorage.Authorize.setLocation(url)},RemoteStorage.Authorize.IMPLIED_FAKE_TOKEN=!1,RemoteStorage.prototype.authorize=function(authURL,cordovaRedirectUri){this.access.setStorageType(this.remote.storageType);var scope=this.access.scopeParameter,redirectUri=global.cordova?cordovaRedirectUri:String(RemoteStorage.Authorize.getLocation()),clientId=redirectUri.match(/^(https?:\/\/[^\/]+)/)[0];RemoteStorage.Authorize(this,authURL,scope,redirectUri,clientId)},RemoteStorage.Authorize.getLocation=function(){return global.document.location},RemoteStorage.Authorize.setLocation=function(location){if("string"==typeof location)global.document.location.href=location;else{if("object"!=typeof location)throw"Invalid location "+location;global.document.location=location}},RemoteStorage.Authorize.openWindow=function(url,redirectUri,options){var pending=Promise.defer(),newWindow=global.open(url,"_blank",options);if(!newWindow||newWindow.closed)return pending.reject("Authorization popup was blocked"),pending.promise;var handleExit=function(){pending.reject("Authorization was canceled")},handleLoadstart=function(event){if(0===event.url.indexOf(redirectUri)){newWindow.removeEventListener("exit",handleExit),newWindow.close();var authResult=extractParams(event.url);return authResult?pending.resolve(authResult):pending.reject("Authorization error")}};return newWindow.addEventListener("loadstart",handleLoadstart),newWindow.addEventListener("exit",handleExit),pending.promise},RemoteStorage.prototype.impliedauth=function(){RemoteStorage.ImpliedAuth(this.remote.storageApi,String(document.location))},RemoteStorage.Authorize._rs_supported=function(){return"undefined"!=typeof document};var onFeaturesLoaded;RemoteStorage.Authorize._rs_init=function(remoteStorage){onFeaturesLoaded=function(){var authParamsUsed=!1;if(params){if(params.error)throw"Authorization server errored: "+params.error;params.rsDiscovery&&remoteStorage.remote.configure(params.rsDiscovery),params.access_token&&(remoteStorage.remote.configure({token:params.access_token}),authParamsUsed=!0),params.remotestorage&&(remoteStorage.connect(params.remotestorage),authParamsUsed=!0),params.state&&(location=RemoteStorage.Authorize.getLocation(),RemoteStorage.Authorize.setLocation(location.href.split("#")[0]+"#"+params.state))}authParamsUsed||remoteStorage.remote.stopWaitingForToken()};var location,params=extractParams();params&&(location=RemoteStorage.Authorize.getLocation(),location.hash=""),remoteStorage.on("features-loaded",onFeaturesLoaded)},RemoteStorage.Authorize._rs_cleanup=function(remoteStorage){remoteStorage.removeEventListener("features-loaded",onFeaturesLoaded)}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.Access=function(){this.reset()},RemoteStorage.Access.prototype={claim:function(scope,mode){if("string"!=typeof scope||-1!==scope.indexOf("/")||0===scope.length)throw new Error("Scope should be a non-empty string without forward slashes");if(!mode.match(/^rw?$/))throw new Error("Mode should be either 'r' or 'rw'");this._adjustRootPaths(scope),this.scopeModeMap[scope]=mode},get:function(scope){return this.scopeModeMap[scope]},remove:function(scope){var name,savedMap={};for(name in this.scopeModeMap)savedMap[name]=this.scopeModeMap[name];this.reset(),delete savedMap[scope];for(name in savedMap)this.set(name,savedMap[name])},checkPermission:function(scope,mode){var actualMode=this.get(scope);return actualMode&&("r"===mode||"rw"===actualMode)},checkPathPermission:function(path,mode){return this.checkPermission("*",mode)?!0:!!this.checkPermission(this._getModuleName(path),mode)},reset:function(){this.rootPaths=[],this.scopeModeMap={}},_getModuleName:function(path){if("/"!==path[0])throw new Error("Path should start with a slash");var moduleMatch=path.replace(/^\/public/,"").match(/^\/([^\/]*)\//);return moduleMatch?moduleMatch[1]:"*"},_adjustRootPaths:function(newScope){"*"in this.scopeModeMap||"*"===newScope?this.rootPaths=["/"]:newScope in this.scopeModeMap||(this.rootPaths.push("/"+newScope+"/"),this.rootPaths.push("/public/"+newScope+"/"))},_scopeNameForParameter:function(scope){if("*"===scope.name&&this.storageType){if("2012.04"===this.storageType)return"";if(this.storageType.match(/remotestorage-0[01]/))return"root"}return scope.name},setStorageType:function(type){this.storageType=type}},Object.defineProperty(RemoteStorage.Access.prototype,"scopes",{get:function(){return Object.keys(this.scopeModeMap).map(function(key){return{name:key,mode:this.scopeModeMap[key]}}.bind(this))}}),Object.defineProperty(RemoteStorage.Access.prototype,"scopeParameter",{get:function(){return this.scopes.map(function(scope){return this._scopeNameForParameter(scope)+":"+scope.mode}.bind(this)).join(" ")}}),Object.defineProperty(RemoteStorage.prototype,"access",{get:function(){var access=new RemoteStorage.Access;return Object.defineProperty(this,"access",{value:access}),access},configurable:!0}),RemoteStorage.Access._rs_init=function(){}}("undefined"!=typeof window?window:global),function(pMode){var mode=pMode,env={},isBackground=!1;RemoteStorage.Env=function(){return env},RemoteStorage.Env.isBrowser=function(){return"browser"===mode},RemoteStorage.Env.isNode=function(){return"node"===mode},RemoteStorage.Env.goBackground=function(){isBackground=!0,RemoteStorage.Env._emit("background")},RemoteStorage.Env.goForeground=function(){isBackground=!1,RemoteStorage.Env._emit("foreground")},RemoteStorage.Env._rs_init=function(remoteStorage){function visibility(){document[env.hiddenProperty]?RemoteStorage.Env.goBackground():RemoteStorage.Env.goForeground()}RemoteStorage.eventHandling(RemoteStorage.Env,"background","foreground"),"browser"===mode&&("undefined"!=typeof document.hidden?(env.hiddenProperty="hidden",env.visibilityChangeEvent="visibilitychange"):"undefined"!=typeof document.mozHidden?(env.hiddenProperty="mozHidden",env.visibilityChangeEvent="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(env.hiddenProperty="msHidden",env.visibilityChangeEvent="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(env.hiddenProperty="webkitHidden",env.visibilityChangeEvent="webkitvisibilitychange"),document.addEventListener(env.visibilityChangeEvent,visibility,!1),visibility())},RemoteStorage.Env._rs_cleanup=function(remoteStorage){}}("undefined"!=typeof window?"browser":"node"),function(){"use strict";var dictionary={view_info:'This app allows you to use your own storage. Learn more!',view_connect:"Connect remote storage",view_connecting:"Connecting %s",view_offline:"Offline",view_error_occured:"Sorry! An error occured.",view_invalid_key:"Wrong key!",view_confirm_reset:"Are you sure you want to reset everything? This will clear your local data and reload the page.",view_get_me_out:"Get me out of here!",view_error_plz_report:'If this problem persists, please let us know!',view_unauthorized:"Unauthorized! Click here to reconnect."};RemoteStorage.I18n={translate:function(){var str=arguments[0],params=Array.prototype.splice.call(arguments,1);if("string"!=typeof dictionary[str])throw"Unknown translation string: "+str;return str=dictionary[str],str.replace(/%s/g,function(){return params.shift()})},getDictionary:function(){return dictionary},setDictionary:function(newDictionary){dictionary=newDictionary},_rs_init:function(){}}}(),RemoteStorage.Assets={cipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIyNS4xNzciIHZlcnNpb249IjEuMSIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIGQ9Im0yNS4xNzcgNS41MzIzYy0wLjA1NjQtMC4xMTI5MS0wLjA1NjQtMC4yMjU4MS0wLjE2OTM2LTAuMzM4NzEtMC4xMTI5LTAuMTEyOS0wLjI4MjI1LTAuMTY5MzYtMC4zOTUxNi0wLjE2OTM2aC0xMS40MDNjLTAuNzMzLTIuODc5LTMuMzg2NC01LjAyNDItNi40OTEzLTUuMDI0Mi0zLjY2OTMgMC02LjcxNzcgMy4wNDg0LTYuNzE3NyA2LjcxNzcgMCAzLjcyNjMgMy4wNDg0IDYuNzE3MyA2LjcxNzcgNi43MTczIDMuMzMwNyAwIDYuMDQwMy0yLjQyNzQgNi42MDQ4LTUuNTg4N2gyLjU0MDN2My42Njk0YzAgMC4yODIyNiAwLjI4MjI2IDAuNTA4MDYgMC41NjQ1MiAwLjUwODA2aDEuNzVjMC4yODIyNiAwIDAuNTY0NTItMC4yMjU4IDAuNTY0NTItMC41MDgwNnYtMy42Njk0aDEuNDY3N3Y1LjY0NTJjMCAwLjI4MjI1IDAuMjI1OCAwLjUwODA2IDAuNTA4MDYgMC41MDgwNmgxLjgwNjRjMC4yODIyNiAwIDAuNTA4MDctMC4yMjU4MSAwLjU2NDUyLTAuNTA4MDZ2LTUuNjQ1MmgxLjUyNDJjMC4xMTI5MSAwIDAuMjgyMjYgMCAwLjM5NTE2LTAuMTEyOSAwLjExMjkxLTAuMTEyOSAwLjE2OTM2LTAuMjgyMjYgMC4xNjkzNi0wLjM5NTE2di0xLjgwNjR6bS0xOC40NTkgNS4wODA3Yy0yLjA4ODcgMC0zLjgzODctMS42OTM2LTMuODM4Ny0zLjgzODcgMC0yLjE0NTIgMS43NS0zLjgzODcgMy44Mzg3LTMuODM4NyAyLjE0NTIgMCAzLjgzODcgMS42OTM2IDMuODM4NyAzLjgzODcgMCAyLjE0NTItMS42OTM2IDMuODM4Ny0zLjgzODcgMy44Mzg3eiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",connectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTAzNi40KSI+CiAgPHBhdGggZD0ibTEgMTA0Ny40di02aDd2LTRsNyA3LTcgN3YtNHoiIGZpbGw9IiNmZmYiLz4KIDwvZz4KPC9zdmc+Cg==",disconnectIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4wIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxwYXRoIHN0eWxlPSJibG9jay1wcm9ncmVzc2lvbjp0Yjt0ZXh0LWluZGVudDowO2NvbG9yOiMwMDAwMDA7dGV4dC10cmFuc2Zvcm06bm9uZSIgZD0ibTguMDAwMSAwYy0wLjQ3MTQgMC0wLjk2MTAzIDAuNTQxOS0wLjk1IDF2NmMtMC4wMDc0NyAwLjUyODMxIDAuNDIxNjMgMSAwLjk1IDFzMC45NTc0Ny0wLjQ3MTY5IDAuOTUtMXYtNmMwLjAxNDYyMi0wLjYwNTEtMC40Nzg2LTEtMC45NS0xem0tMy4zNDM4IDIuNWMtMC4wODcxODYgMC4wMTkyOTQtMC4xNzE2MyAwLjA1MDk1OS0wLjI1IDAuMDkzNzUtMi45OTk1IDEuNTcxNS0zLjkxODQgNC43OTc5LTMuMTI1IDcuNDY4OCAwLjc5MzQgMi42NyAzLjI3OTkgNC45MzcgNi42ODc1IDQuOTM3IDMuMzU5MiAwIDUuODc3Mi0yLjE0OSA2LjcxOTItNC43ODEgMC44NDEtMi42MzIxLTAuMDU4LTUuODIzNC0zLjEyNS03LjU5NC0wLjQzNC0wLjI1MzYtMS4wNTktMC4wODk5LTEuMzEzIDAuMzQzNy0wLjI1MzYgMC40MzM2LTAuMDkgMS4wNTg5IDAuMzQ0IDEuMzEyNSAyLjM5MDggMS4zNzk4IDIuODgyNSAzLjQ5NDQgMi4yODEyIDUuMzc1LTAuNjAxMiAxLjg4MDYtMi4zNDQgMy40Mzc1LTQuOTA2MiAzLjQzNzUtMi41NzU5IDAtNC4yOTc2LTEuNjUwMi00Ljg3NS0zLjU5MzgtMC41Nzc2LTEuOTQzNS0wLjA0Ny00LjA0OCAyLjE4NzMtNS4yMTg3IDAuMzc4Ny0wLjIwNjMgMC41NzkxLTAuNjkyNSAwLjQ1NTgtMS4xMDU3LTAuMTIzMi0wLjQxMzMtMC41NTcyLTAuNzEwMy0wLjk4Ny0wLjY3NTUtMC4wMzEzLTAuMDAxNS0wLjA2MjYtMC4wMDE1LTAuMDkzOCAweiIgZmlsbD0iI2ZmZiIvPgo8L3N2Zz4K",dropbox:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEBAhEOpfuQAABhZJREFUWMPVl31snVUdxz+/5/2577e3b7QbHaOD0nXshW4ZZkpGQmJYZkJUDAaZzCBGAxGd+pdZQsJIjCaKgFu09GWybIggm8yhMCsY92rcOkPHunbdtKOUbX36svX23uc+xz+eDsrWlztiNJzk5D7JPS+fc8739/2dA5+EsqJtyK18ZlCKbX9Lk6fd1uo5xbTVZmtwa4v35Np5Mry4TLYXCzAnyhsry2SwrmnokdnaTruq6i3e0lXl0tqQlkURCxwdDp9Th5p3+p9iS8afqk/VZq9kaZoDN8apdU3B1KFnmLde7AkezH0n3V0UQOJpz2hIsqEhLU+WOeAagmtCxISYBe1nVf4vfWrByYdSpyf3W9ziLapy6JgbAduAiBn2S1rCQBYODAQP7H01/zxby4JpAW5s8mproxypiRKNGIJrQNT8EMA1wTGEU8MBP/q7umPw0dSbAA3N3n3zI2yLG2oScPgbNYWICY4Be86o/le6g0W576bPXQWwcqvXdJ2t1idMsA1hJoCoCRfGYdOhwsa4TUWFrr7pGmDrzAiQCHfD//Xxwk/33Z/6HoA0tnhLXZ3XMoYqsy4PYs4M4Ohg6pB2ddqO+vR6BWL27AARXbBNiBjwh9Oqs+O8ukcT4eaopjLqGsJSCdSX29SX23x/lctXlzgE1zBAANxWIQuGxlWNACxr8WozJp0lljKsGXbA0qGu1GRBxsTUQRAGLgboIuQVvHI8S+f7eeK2TLsDSQd296rhPaeDm09+PdX/gQYqN3uZ+jh7ro+oRusKDdgmVEY1GqstSiOhdegCmoQAIoImIWTPYIHdXVlyBYhaVwLA70+rPz7fllvLi2W5KcPw9q3eS/VJ7kmYgm1A3BIWV5osq7IIlMLUQJOrAXQBXQtr1BR2d2XpOu8TtULR+gq2nQh+vv8rqUdnNaKGZm/9qnJpmp/U+fxCB5lYsaGFdTYAY9L3jmNj9F9S7OgKVh9/KNVelBVf8untv8TYSS8gbsrHyh8C2LqQtGE0z9CJYfVuUblgRZv3WGOJvJG0cF8/lWPNdo+O93xsHYoVuqkL/xzIs/HPHt2DPg0Zko+v0I8vbfHun9aKE5sH9YaobJsf5V4mRLXv33kSlmAYwspqgw23R7A1EJlahKYOSsHTB0cZHQ9IOBA3NSrjGo4hWAY82xH8rH1b/jF2laoPAOb80jPqYtKTMdRcTQNd+xAgbgmuJbiGELfh3lsc7q41KQSTABBcC1qPjLH/XzniNqScsP1kgMsm9nJ34e2mNcmFAMby1qFPZyz1WlxXrprhuEUgUPDbd8Y59n6edbe61KZ1TF14vSfPLw5dYjhXIOMIM6lGAV+u0+tv+ttI/2+6/LsMQVXpUFCAqJkS9MT5anB2NGDjWxf5Yp3DvjN5th/LUhETolaRTqigxMGIWVKtHVyX2tGTJd2X5agUIfi8CmvUFOKGT++gT8wqLlKUgnwATxwq7P32m35Z+32pPQZA54MpH1iSb/XWZmx2VthTD1AATCBlCZ+dpwNg6EJjlUH3hQIKRaCujhZFaOPtfUH+8HvBnQceSP11yjA8vC616+A5FevL8jt/YiCR0HiQcAUVrnDHHO0jHTUNllXrpC0NRXiefjAxM4rhHLzQpZqf+eFFd/LkM17JGlu9p+xC8IgPhGlaqE1rNJZrxOzQok0dnjviY+nhbSntCH3DAWN+QMIWEhYsqTD4wYHChrPfSP9kqnmM6QAMkYtz4xqmDqeGA+rLNObGZVozkglx1ZfqZAvC2ZGAz9RYlEbAlsLoNd+Kx5RqO5/njKXDsnKdhCXFOaFAZUzjznlhyt5xIjiSLbBz2oVO98fRdalOoGZ5m/dUQ4pvJZ3Zr/CXlS5A74gabzlYePztr6U2faxr+eRy/RYvtjgjHauvkxvi9oTDXaGBuAUJWyh1hb3vqsOvfiG5/L/yMAE483BqdNeuXO3LvcGX3vEUhsZVsaYL9IzACz3BXcVOXvQOfKRsupBZv8R4bnW19rmqGPzqHz4BcMGn5U/Hgod5oiT3P3kvVj7rrfnx/pHBu7d7Azc1eY3/l0drzWbPXNjsGXySy38AbtMqneWU7BkAAAAASUVORK5CYII=",googledrive:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QgPEA85ztzJcQAABZVJREFUWMPtl1uoXVcVhr8x5tprn7M1NG1i0pQqSG2jLcXipYJXjPogqFgpaHMSFUkpIjU+leKbDxIQSiHgjZgmrfXgQ6SKj5Ji7YVS05aUUqKQlNLQeDnN5Zzk9Jy99xy/D3OttU/StDlV33TBZM3FXmuMf/5jjv+fG/7XL1vti9tnv3Dtnnf+87JY8YmZNxEMM1sZ7tWpjz764mriVqvKvmfb1ONLy3+dGyWu6EWbvQwoydv5BMSqFuereakmfnls1GP25IDaBGYYjplhljDz5tk7YMtPfurAf6UE9Z6tNwDPAPXwtcxL1x9n4zRgDjjm1gCyC6JpCLoW/OX65of1nzCwG6gNo3aYeXF981mTvK2/WWFiMmoj7X+z5JcE0N87c4e7b3EvyTwZT5/r8ezZHu6GuWGpSegJ8/ZeBu6fHv35s1/7t0rQv29mjWF/ATZ1L4bQwohrpkYc/sBpwhJYAVdKYECzYAESIk4Am3sf+sPCW2LAzb9jbpvMDXfD3fEqkRIcGdbsevlt9LylPYG1K6/K3QzK75uAr78lBgb3b7sc2cl2Uaa21sDiGMvB2iQeu/EMm6bKHjD3SUsCEChnpEAKiLisd/PB+UsyMPjZNwzzh1ixcnOfsFCX51NU/PTvA6pkTUdYw4R3zyu1ArMDqyvBQB82+FiJUQJ4C8YgVT1SSvSTs+vEmkcwe7qEsUnt233Aij0BW4ZPbfngKpRQs7hXpYQNvRiuEtATWOW4bLi+z04pJbCnBAkBJggBQlIBIZCUJM0Cm9+QgcED2+/G7BprdMZaAFZExm1FWcz+NLdj32G/6XfPCB5GoJKp7H5FARHRtgRI1y0/+cm7Lwpg+v7t64DvNd5S2mqirKXHy6RoArp1Ykrc2hKtKCtXlNEyoQ6Ydi498fF1F2FAdwEbV9UnZne+8q19Z7o63vTb+TPnRneeWxwxHGdyziii6wApQNEydKUUd5wHYGrftvci7tKKLSME5bvCaruynI9rNL7vdZgiHhiP898Wl8bMnxty+uyIhcURo1FgjSg1DCDph4uPfuR9AFbvvS25p2cxbiyKVuh2o1O44n2lLLacb5v75v5fX6yl5h753IwUD+YcRAQ5B6FMMhj0jboSRhnAE258wvp7Z7aYcbCYCeCGt97ubfICLDP/q4WZ32x7M20fPfb+hxbH9ZdjHOQIIoR74EDywA3coa6MqtJnrP+LmRmcB63ob8dA1wllRm95LVc//22S16TGeKqqpqoHk10ESGJj/zjjgIhAISKCyJmcY6Uu8Pbq7C0V6ABh35dzvYWQG0QAhmSYCaUlNhzdCrlX2jpE6tV4b9DYcGFKEgG8svQucoicC4CsII8zeTxutAEQzx1duPL3vrxjdlnou0SDLdTulxJQmalXNzN98jpEJiSo+qTeoEnsnWC5lVZNRhkOZiq0G8XCmz1gpp3j/ZYdYLhj9qCkn3fJQ4QKeh9OccWxz6O0hGKM9wakeoBEZ1BmqfOMyYFk4gXS+edG4J4ju6/644VK+AOJhSIYpVRBpn/qPVRL65A51dRavJoG2UQkOqf0hgVrGG7u6syoJDObB+55nRANb589Afy40W0UwkY91h39CiLweg1UU+W3ohLNvC2VurJ1htR6A3QaYPCjI7uvOvGGOlfv2XoSuBzEhmNfZXDqBrweUPVqUlWodneSG+6J1NTevThfDpEjmnsmzuuCPPfCvRvfcakT0S2Aeq9tYPr0ZryeBvOOlZBKUIEiCAVZwTgy41x6v6hm0LFZ4o7N7IuXPA+EDx+XjQ+tP/4lUrW2vCI1ydR0iYgmWdtu4yzG7bOiAdn8iYlA0iFJh1Z1JJv+ye2b3n1419XRH2riP0aqqlKClABIjUMW+rtSlw5qmCpgsynnl56/d+M/+P91wfUvQjDgTzx9h9AAAAAASUVORK5CYII=",nocipherIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogPHBhdGggZD0ibSAxMy4yMDMxMjQsMTEuNzczNDM4IGMgMC4yODEyNSwwLjI4MTI1IDAuNDIxODc1LDAuNjA5Mzc1IDAuNDIxODc1LDEuMDMxMjUgMCwwLjM3NSAtMC4xNDA2MjUsMC43NSAtMC40MjE4NzUsMS4wMzEyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42MDkzNzUsMC4zNzUgLTEuMDMxMjUsMC4zNzUgLTAuMzc1LDAgLTAuNzUsLTAuMTQwNjI1IC0xLjAzMTI1LC0wLjM3NSAwLDAgLTMuMTg3NDk4MSwtMy42NTYyNSAtMy4xODc0OTgxLC0zLjY1NjI1IDAsMCAtMy4xNDA2MjUsMy42NTYyNSAtMy4xNDA2MjUsMy42NTYyNSAtMC4yODEyNSwwLjIzNDM3NSAtMC42NTYyNSwwLjM3NSAtMS4wMzEyNSwwLjM3NSAtMC40MjE4NzUsMCAtMC43NSwtMC4xNDA2MjUgLTEuMDMxMjUsLTAuMzc1IC0wLjI4MTI1LC0wLjI4MTI1IC0wLjM3NSwtMC42NTYyNSAtMC4zNzUsLTEuMDMxMjUgMCwtMC40MjE4NzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLDAgMy4zMjgxMjUsLTMuNzUwMDAwNSAzLjMyODEyNSwtMy43NTAwMDA1IDAsMCAtMy4zMjgxMjUsLTMuNzk2ODc1IC0zLjMyODEyNSwtMy43OTY4NzUgLTAuMjgxMjUsLTAuMjgxMjUgLTAuMzc1LC0wLjYwOTM3NSAtMC4zNzUsLTEuMDMxMjUgMCwtMC4zNzUgMC4wOTM3NSwtMC43NSAwLjM3NSwtMS4wMzEyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjYwOTM3NSwtMC4zNzUgMS4wMzEyNSwtMC4zNzUgMC4zNzUsMCAwLjc1LDAuMTQwNjI1IDEuMDMxMjUsMC4zNzUgMCwwIDMuMTQwNjI1LDMuNjU2MjUgMy4xNDA2MjUsMy42NTYyNSAwLDAgMy4xODc0OTgxLC0zLjY1NjI1IDMuMTg3NDk4MSwtMy42NTYyNSAwLjI4MTI1LC0wLjIzNDM3NSAwLjY1NjI1LC0wLjM3NSAxLjAzMTI1LC0wLjM3NSAwLjQyMTg3NSwwIDAuNzUsMC4xNDA2MjUgMS4wMzEyNSwwLjM3NSAwLjI4MTI1LDAuMjgxMjUgMC40MjE4NzUsMC42NTYyNSAwLjQyMTg3NSwxLjAzMTI1IDAsMC40MjE4NzUgLTAuMTQwNjI1LDAuNzUgLTAuNDIxODc1LDEuMDMxMjUgMCwwIC0zLjMyODEyMzEsMy43OTY4NzUgLTMuMzI4MTIzMSwzLjc5Njg3NSAwLDAgMy4zMjgxMjMxLDMuNzUwMDAwNSAzLjMyODEyMzEsMy43NTAwMDA1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=",remoteStorageIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconCiphered:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZmNGEwNCIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZmY0YTA0IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xNiAwbDAuMTI1IDYuMzc1YzIuMDk4IDAuMDY3IDMuNzUgMS43NTk1IDMuNzUgMy44NzV2MS45NjloMS45MzcgMC4wMzJsOC00LjIxOS0xMy44NDQtOHpsLTEzLjg0NCA4IDggNC4yMTloMC4wMzIgMS45MDZ2LTEuOTY5YzAtMi4xMTU1IDEuNjgzLTMuODA4IDMuNzgxLTMuODc1bDAuMTI1LTYuMzc1em0tMTMuODQ0IDh2MTZsNy45OTk4LTQuODQ0di02LjA5NGwtNy45OTk4LTUuMDYyem0wIDE2bDEzLjg0NCA4LTAuMzc1LTEwLjA2MmgtNS40Njl2LTIuMzQ0bC03Ljk5OTggNC40MDZ6bTEzLjg0NCA4bDEzLjg0NC04LTgtNC40MDZ2Mi4zNDRoLTUuNDY5bC0wLjM3NSAxMC4wNjJ6bTEzLjg0NC04di0xNmwtOCA1LjA2MnY2LjA5NGw4IDQuODQ0em0tMTMuOTY5LTE3Yy0xLjczNSAwLjA2NjYtMy4xMjUgMS40OTg3LTMuMTI1IDMuMjV2MS45NjloMy4wMzFsMC4wOTQtNS4yMTl6bTAuMjUgMGwwLjA5NCA1LjIxOWgzLjAzMXYtMS45NjljMC0xLjc1MTMtMS4zOS0zLjE4MzQtMy4xMjUtMy4yNXptLTQuNzUgNS44NDRsNC4zNDQgMi4yODEgMC4wMzEtMi4yODFoLTQuMzc1em00Ljg3NSAwbDAuMDMxIDIuMjgxIDQuMzQ0LTIuMjgxaC00LjM3NXptLTUuNDM4IDAuNjI1djUuMzEybDQuMjgyLTIuNTkzLTQuMjgyLTIuNzE5em0xMC4zNzYgMGwtNC4yODIgMi43MTkgNC4yODIgMi41OTN2LTUuMzEyem0tNS43ODIgMy4yMTlsLTQuNTk0IDIuNTMxdjIuMDYyaDQuNzgybC0wLjE4OC00LjU5M3ptMS4xODggMGwtMC4xODggNC41OTNoNC43ODJ2LTIuMDYybC00LjU5NC0yLjUzMXoiIGZpbGw9InVybCgjYSkiLz4KPC9zdmc+Cg==",remoteStorageIconError:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iI2U5MDAwMCIgc3RvcC1vcGFjaXR5PSIuNzYwNzgiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjZTkwMDAwIiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",remoteStorageIconOffline:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzIiIHdpZHRoPSIzMiIgdmVyc2lvbj0iMS4xIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KIDxkZWZzPgogIDxyYWRpYWxHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI1NzEuNDIiIGN4PSIxMDQ2LjUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLjE0NDMzIDAgMCAuMTY2NjcgMTIwMS41IDg3Ny4xMSkiIHI9Ijk2Ij4KICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5Njk2OSIgc3RvcC1vcGFjaXR5PSIuNzYxNTQiIG9mZnNldD0iMCIvPgogICA8c3RvcCBzdG9wLWNvbG9yPSIjNjc2NzY3IiBvZmZzZXQ9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogPC9kZWZzPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMzYuNiAtOTU2LjM1KSI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDAiIGQ9Im0xMzUyLjYgOTU2LjM1IDAuMjg4NiAxNS4xMzYgMTMuNTY3LTcuMTM1Mi0xMy44NTUtOC4wMDExemwtMTMuODU1IDguMDAxMSAxMy41NjcgNy4xMzUyIDAuMjg4Ny0xNS4xMzZ6bS0xMy44NTUgOC4wMDExdjE1Ljk5OGwxMi45NTgtNy44MTYyLTEyLjk1OC04LjE4MTV6bTAgMTUuOTk4IDEzLjg1NSA4LjAwMTEtMC42MDg5LTE1LjMxNy0xMy4yNDYgNy4zMTU2em0xMy44NTUgOC4wMDExIDEzLjg1NS04LjAwMTEtMTMuMjUxLTcuMzE1Ni0wLjYwNDQgMTUuMzE3em0xMy44NTUtOC4wMDExdi0xNS45OThsLTEyLjk2MiA4LjE4MTUgMTIuOTYyIDcuODE2MnoiIGZpbGw9InVybCgjYSkiLz4KIDwvZz4KPC9zdmc+Cg==",syncIcon:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDg3LjUgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTUuOTk5OTk5IDE2IiB3aWR0aD0iMTYiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01LjUxMTIgLTc2LjUyNSkiIGRpc3BsYXk9Im5vbmUiPgoJPHBhdGggZGlzcGxheT0iaW5saW5lIiBkPSJtNTEuNDczIDQyLjI1NS0yLjIwNSAyLjIxMmMxLjQ3OCAxLjQ3NyAyLjI5NSAzLjQ0MiAyLjI5NSA1LjUzMyAwIDQuMzA5LTMuNTA0IDcuODEyLTcuODEyIDcuODEydi0xLjU2MmwtMy4xMjUgMy4xMjUgMy4xMjQgMy4xMjV2LTEuNTYyYzYuMDI5IDAgMTAuOTM4LTQuOTA2IDEwLjkzOC0xMC45MzggMC0yLjkyNy0xLjE0MS01LjY3Ni0zLjIxNS03Ljc0NXoiLz4KCTxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0ibTQ2Ljg3NSA0MC42MjUtMy4xMjUtMy4xMjV2MS41NjJjLTYuMDMgMC0xMC45MzggNC45MDctMTAuOTM4IDEwLjkzOCAwIDIuOTI3IDEuMTQxIDUuNjc2IDMuMjE3IDcuNzQ1bDIuMjAzLTIuMjEyYy0xLjQ3Ny0xLjQ3OS0yLjI5NC0zLjQ0Mi0yLjI5NC01LjUzMyAwLTQuMzA5IDMuNTA0LTcuODEyIDcuODEyLTcuODEydjEuNTYybDMuMTI1LTMuMTI1eiIvPgo8L2c+CjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0xMCAwbC0wLjc1IDEuOTA2MmMtMS4wMDc4LTAuMjk0Mi0zLjQ1ODYtMC43NzA4LTUuNjU2MiAwLjkzNzYgMC0wLjAwMDItMy45MzAyIDIuNTk0MS0yLjA5MzggNy41OTQybDEuNjU2Mi0wLjcxOTJzLTEuNTM5OS0zLjExMjIgMS42ODc2LTUuNTMxM2MwIDAgMS42OTU3LTEuMTMzOSAzLjY4NzQtMC41OTM3bC0wLjcxODcgMS44MTI0IDMuODEyNS0xLjYyNS0xLjYyNS0zLjc4MTJ6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDUuNTYyNWwtMS42NTYgMC43MTg3czEuNTQxIDMuMTEzNS0xLjY4OCA1LjUzMDhjMCAwLTEuNzI3MiAxLjEzNS0zLjcxODUgMC41OTRsMC43NS0xLjgxMi0zLjgxMjUgMS41OTQgMS41OTM4IDMuODEyIDAuNzgxMi0xLjkwNmMxLjAxMTMgMC4yOTUgMy40NjE1IDAuNzY2IDUuNjU2LTAuOTM4IDAgMCAzLjkyOC0yLjU5NCAyLjA5NC03LjU5MzV6Ii8+Cjwvc3ZnPgo=",widget:'
{{view_connect}}
{{ERROR_MSG}}

{{view_error_plz_report}}

{{USER_ADDRESS}}

{{view_unauthorized}}

{{view_invalid_key}}

{{view_info}}
Connect to Dropbox Connect to Google Drive ',widgetCss:'/** encoding:utf-8 **/ /* RESET */ #remotestorage-widget{text-align:left;}#remotestorage-widget input, #remotestorage-widget button{font-size:11px;}#remotestorage-widget form input[type=email]{margin-bottom:0;/* HTML5 Boilerplate */}#remotestorage-widget form input[type=submit]{margin-top:0;/* HTML5 Boilerplate */}/* /RESET */ #remotestorage-widget, #remotestorage-widget *{-moz-box-sizing:border-box;box-sizing:border-box;}#remotestorage-widget{position:absolute;right:10px;top:10px;font:normal 16px/100% sans-serif !important;user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:default;z-index:10000;}#remotestorage-widget .rs-bubble{background:rgba(80, 80, 80, .7);border-radius:5px 15px 5px 5px;color:white;font-size:0.8em;padding:5px;position:absolute;right:3px;top:9px;min-height:24px;white-space:nowrap;text-decoration:none;}.rs-bubble .rs-bubble-text{padding-right:32px;/* make sure the bubble doesn\'t "jump" when initially opening. */ min-width:182px;}#remotestorage-widget .rs-action{cursor:pointer;}/* less obtrusive cube when connected */ #remotestorage-widget.remotestorage-state-connected .rs-cube, #remotestorage-widget.remotestorage-state-busy .rs-cube{opacity:.3;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease;}#remotestorage-widget.remotestorage-state-connected:hover .rs-cube, #remotestorage-widget.remotestorage-state-busy:hover .rs-cube, #remotestorage-widget.remotestorage-state-connected .rs-bubble:not(.rs-hidden) + .rs-cube{opacity:1 !important;}#remotestorage-widget .rs-backends{position:relative;top:5px;right:0;}#remotestorage-widget .rs-cube{position:relative;top:5px;right:0;}/* pulsing animation for cube when loading */ #remotestorage-widget .rs-cube.remotestorage-loading{-webkit-animation:remotestorage-loading .5s ease-in-out infinite alternate;-moz-animation:remotestorage-loading .5s ease-in-out infinite alternate;-o-animation:remotestorage-loading .5s ease-in-out infinite alternate;-ms-animation:remotestorage-loading .5s ease-in-out infinite alternate;animation:remotestorage-loading .5s ease-in-out infinite alternate;}@-webkit-keyframes remotestorage-loading{to{opacity:.7}}@-moz-keyframes remotestorage-loading{to{opacity:.7}}@-o-keyframes remotestorage-loading{to{opacity:.7}}@-ms-keyframes remotestorage-loading{to{opacity:.7}}@keyframes remotestorage-loading{to{opacity:.7}}#remotestorage-widget a{text-decoration:underline;color:inherit;}#remotestorage-widget form{margin-top:.7em;position:relative;}#remotestorage-widget form input{display:table-cell;vertical-align:top;border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:2em;}#remotestorage-widget form input:disabled{color:#999;background:#444 !important;cursor:default !important;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget form input[type=email], #remotestorage-widget form input[type=password]{background:#000;width:100%;height:26px;padding:0 30px 0 5px;border-top:1px solid #111;border-bottom:1px solid #999;}#remotestorage-widget form input[type=email]:focus, #remotestorage-widget form input[type=password]:focus{background:#223;}#remotestorage-widget button:focus, #remotestorage-widget input:focus{box-shadow:0 0 4px #ccc;}#remotestorage-widget form input[type=email]::-webkit-input-placeholder, #remotestorage-widget form input[type=password]::-webkit-input-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-moz-placeholder, #remotestorage-widget form input[type=password]:-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]::-moz-placeholder, #remotestorage-widget form input[type=password]::-moz-placeholder{color:#999;}#remotestorage-widget form input[type=email]:-ms-input-placeholder, #remotestorage-widget form input[type=password]:-ms-input-placeholder{color:#999;}#remotestorage-widget form input[type=submit]{background:#000;cursor:pointer;padding:0 5px;}#remotestorage-widget form input[type=submit]:hover{background:#333;}#remotestorage-widget .rs-info-msg{font-size:10px;color:#eee;margin-top:0.7em;white-space:normal;}#remotestorage-widget .rs-info-msg.last-synced-message{display:inline;white-space:nowrap;margin-bottom:.7em}#remotestorage-widget .rs-info-msg a:hover, #remotestorage-widget .rs-info-msg a:active{color:#fff;}#remotestorage-widget button img{vertical-align:baseline;}#remotestorage-widget button{border:none;border-radius:6px;font-weight:bold;color:white;outline:none;line-height:1.5em;height:26px;width:26px;background:#000;cursor:pointer;margin:0;padding:5px;}#remotestorage-widget button:hover{background:#333;}#remotestorage-widget .rs-bubble button.connect, #remotestorage-widget .rs-bubble button.rs-cipher, #remotestorage-widget .rs-bubble button.rs-nocipher{display:block;background:none;position:absolute;right:0;top:0;opacity:1;/* increase clickable area of connect, rs-cipher & rs-nocipher buttons */ margin:-5px;padding:10px;width:36px;height:36px;}#remotestorage-widget .rs-bubble button.rs-cipher{width:46px;}#remotestorage-widget .rs-bubble button.rs-nocipher{height:26px;margin:0;padding:4px 5px 5px;right:-32px;width:26px;}#remotestorage-widget .rs-bubble button.connect:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-cipher:not([disabled]):hover, #remotestorage-widget .rs-bubble button.rs-nocipher:not([disabled]):hover{background:rgba(150,150,150,.5);}#remotestorage-widget .rs-bubble button.connect[disabled], #remotestorage-widget .rs-bubble button.rs-cipher[disabled]{opacity:.5;cursor:default !important;}#remotestorage-widget .rs-bubble button.rs-sync{position:relative;left:-5px;bottom:-5px;padding:4px 4px 0 4px;background:#555;}#remotestorage-widget .rs-bubble button.rs-sync:hover{background:#444;}#remotestorage-widget .rs-bubble button.rs-disconnect{background:#721;position:absolute;right:0;bottom:0;padding:4px 4px 0 4px;}#remotestorage-widget .rs-bubble button.rs-disconnect:hover{background:#921;}#remotestorage-widget .remotestorage-error-info{color:#f92;}#remotestorage-widget .remotestorage-reset{width:100%;background:#721;}#remotestorage-widget .remotestorage-reset:hover{background:#921;}#remotestorage-widget .rs-bubble .rs-content{margin-top:7px;}#remotestorage-widget pre{user-select:initial;-webkit-user-select:initial;-moz-user-select:text;max-width:27em;margin-top:1em;overflow:auto;}#remotestorage-widget .rs-centered-text{text-align:center;}#remotestorage-widget .rs-bubble.rs-hidden{padding-bottom:2px;border-radius:5px 15px 15px 5px;}#remotestorage-widget .rs-error-msg{min-height:5em;}.rs-bubble.rs-hidden .rs-bubble-expandable{display:none;}.remotestorage-state-connected .rs-bubble.rs-hidden{display:none;}.remotestorage-connected{display:none;}.remotestorage-state-connected .remotestorage-connected{display:block;}.remotestorage-cipher-form{display:none;}.remotestorage-cipher .remotestorage-cipher-form{display:block;}.remotestorage-invalid-key{display:none;}.remotestorage-invalid-key.remotestorage-cipher-error{display:block;}.remotestorage-initial{display:none;}.remotestorage-state-initial .remotestorage-initial{display:block;}.remotestorage-error{display:none;}.remotestorage-state-error .remotestorage-error{display:block;}.remotestorage-state-authing .remotestorage-authing{display:block;}.remotestorage-state-offline .remotestorage-connected, .remotestorage-state-offline .remotestorage-offline{display:block;}.remotestorage-unauthorized{display:none;}.remotestorage-state-unauthorized .rs-bubble.rs-hidden{display:none;}.remotestorage-state-unauthorized .remotestorage-connected, .remotestorage-state-unauthorized .remotestorage-unauthorized{display:block;}.remotestorage-state-unauthorized .rs-sync{display:none;}.remotestorage-state-busy .rs-bubble.rs-hidden{display:none;}.remotestorage-state-busy .rs-bubble{display:block;}.remotestorage-state-busy .remotestorage-connected{display:block;}.remotestorage-state-authing .rs-bubble-expandable{display:none;}' +},function(window){function stateSetter(widget,state,message){return RemoteStorage.log("[Widget] Producing stateSetter for",state),function(){RemoteStorage.log("[Widget] Setting state",state,message),hasLocalStorage&&(localStorage[LS_STATE_KEY]=state),widget.view?(widget.rs.remote&&widget.view.setUserAddress(widget.rs.remote.userAddress),widget.view.setState(state,message)):widget._rememberedState=state}}function errorsHandler(widget){return function(error){var s;error instanceof RemoteStorage.DiscoveryError?(console.error("Discovery failed",error,'"'+error.message+'"'),s=stateSetter(widget,"initial",error.message)):error instanceof RemoteStorage.SyncError?s=stateSetter(widget,"offline"):error instanceof RemoteStorage.Unauthorized?s=stateSetter(widget,"unauthorized"):(RemoteStorage.log("[Widget] Unknown error"),s=stateSetter(widget,"error",[error])),s.apply()}}function flashFor(evt){return"GET"===evt.method&&evt.isFolder?!1:!0}var hasLocalStorage,LS_STATE_KEY="remotestorage:widget:state",VALID_ENTRY_STATES={initial:!0,connected:!0,offline:!0};RemoteStorage.Widget=function(remoteStorage){var self=this,requestsToFlashFor=0;if(this.rs=remoteStorage,this.rs.remote.on("connected",stateSetter(this,"connected")),this.rs.on("disconnected",stateSetter(this,"initial")),this.rs.on("connecting",stateSetter(this,"authing")),this.rs.on("authing",stateSetter(this,"authing")),this.rs.on("error",errorsHandler(this)),this.rs.remote&&(this.rs.remote.on("wire-busy",function(evt){flashFor(evt)&&(requestsToFlashFor++,stateSetter(self,"busy")())}),this.rs.remote.on("wire-done",function(evt){flashFor(evt)&&requestsToFlashFor--,0>=requestsToFlashFor&&evt.success&&stateSetter(self,"connected")()})),hasLocalStorage){var state=localStorage[LS_STATE_KEY];state&&VALID_ENTRY_STATES[state]&&(this._rememberedState=state)}},RemoteStorage.Widget.prototype={display:function(options){return"string"==typeof options?options={domID:options}:"undefined"==typeof options&&(options={}),this.view||this.setView(new RemoteStorage.Widget.View(this.rs)),this.view.display(options),this},linkWidgetToSync:function(){"object"==typeof this.rs.sync&&"function"==typeof this.rs.sync.sync?this.view.on("sync",this.rs.sync.sync.bind(this.rs.sync)):(RemoteStorage.log("[Widget] typeof this.rs.sync check fail",this.rs.sync),setTimeout(this.linkWidgetToSync.bind(this),1e3))},setView:function(view){this.view=view,this.view.on("connect",function(options){"string"==typeof options?this.rs.connect(options):options.special&&this.rs[options.special].connect(options)}.bind(this)),this.view.on("secret-entered",function(secretKey){this.view.setUserSecretKey(secretKey),stateSetter(this,"ciphered")()}.bind(this)),this.view.on("secret-cancelled",function(){stateSetter(this,"notciphered")()}.bind(this)),this.view.on("disconnect",this.rs.disconnect.bind(this.rs)),this.linkWidgetToSync();try{this.view.on("reset",function(){var location=RemoteStorage.Authorize.getLocation();this.rs.on("disconnected",location.reload.bind(location)),this.rs.disconnect()}.bind(this))}catch(e){if(!e.message||!e.message.match(/Unknown event/))throw e}this._rememberedState&&(setTimeout(stateSetter(this,this._rememberedState),0),delete this._rememberedState)}},RemoteStorage.prototype.displayWidget=function(options){return this.widget.display(options)},RemoteStorage.Widget._rs_init=function(remoteStorage){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),remoteStorage.widget||(remoteStorage.widget=new RemoteStorage.Widget(remoteStorage))},RemoteStorage.Widget._rs_supported=function(remoteStorage){return"undefined"!=typeof document}}("undefined"!=typeof window?window:global),function(window){function removeClass(el,className){return el.classList.remove(className)}function addClass(el,className){return el.classList.add(className)}function stopPropagation(event){"function"==typeof event.stopPropagation?event.stopPropagation():event.cancelBubble=!0}function setupButton(parent,className,iconName,eventListener){var element=parent.querySelector("."+className);if("undefined"!=typeof iconName){var img=element.querySelector("img");(img||element).src=RemoteStorage.Assets[iconName]}return element.addEventListener("click",eventListener),element}function handleButtonState(event){event.target.value?event.target.nextElementSibling.removeAttribute("disabled"):event.target.nextElementSibling.setAttribute("disabled","disabled")}var t=RemoteStorage.I18n.translate;RemoteStorage.Widget.View=function(remoteStorage){if(this.rs=remoteStorage,"undefined"==typeof document)throw"Widget not supported";RemoteStorage.eventHandling(this,"connect","secret-entered","secret-cancelled","disconnect","sync","display","reset");for(var event in this.events)this.events[event]=this.events[event].bind(this);this.hideBubbleOnBodyClick=function(event){for(var p=event.target;p!==document.body;p=p.parentElement)if("remotestorage-widget"===p.id)return;this.hideBubble()}.bind(this)},RemoteStorage.Widget.View.prototype={connectGdrive:function(){this._emit("connect",{special:"googledrive"})},connectDropbox:function(){this._emit("connect",{special:"dropbox"})},setState:function(state,message){RemoteStorage.log("[View] widget.view.setState(",state,",",message,");");var s=this.states[state];if("undefined"==typeof s)throw new Error("Bad State assigned to view: "+state);s.apply(this,[message])},setUserAddress:function(addr){this.userAddress=addr||"";var el;this.div&&(el=this.div.querySelector("form.remotestorage-initial").userAddress)&&(el.value=this.userAddress)},setUserSecretKey:function(secretKey){this.userSecretKey=secretKey},toggleBubble:function(event){this.bubble.className.search("rs-hidden")<0?this.hideBubble(event):this.showBubble(event)},hideBubble:function(){addClass(this.bubble,"rs-hidden"),document.body.removeEventListener("click",this.hideBubbleOnBodyClick)},showBubble:function(event){removeClass(this.bubble,"rs-hidden"),"undefined"!=typeof event&&stopPropagation(event),document.body.addEventListener("click",this.hideBubbleOnBodyClick),this.div.querySelector(".remotestorage-connected").classList.contains("remotestorage-cipher")&&!this.userSecretKey?this.bubble.querySelector("form.remotestorage-cipher-form").userSecretKey.focus():this.bubble.querySelector("form.remotestorage-initial").userAddress.focus()},display:function(options){if("undefined"!=typeof this.div)return this.div;var element=document.createElement("div"),style=document.createElement("style");if(style.innerHTML=RemoteStorage.Assets.widgetCss,element.id="remotestorage-widget",element.innerHTML=RemoteStorage.Assets.widget,element.appendChild(style),options.domID){var parent=document.getElementById(options.domID);if(!parent)throw'Failed to find target DOM element with id="'+options.domID+'"';parent.appendChild(element)}else document.body.appendChild(element);setupButton(element,"rs-sync","syncIcon",this.events.sync),setupButton(element,"rs-disconnect","disconnectIcon",this.events.disconnect),setupButton(element,"remotestorage-reset",void 0,this.events.reset);setupButton(element,"connect","connectIcon",this.events.connect);this.form=element.querySelector("form.remotestorage-initial");var el=this.form.userAddress;if(el.addEventListener("load",handleButtonState),el.addEventListener("keyup",handleButtonState),this.userAddress&&(el.value=this.userAddress),options.encryption){this.cipher=!0;var secretKeyInput=element.querySelector("form.remotestorage-cipher-form").userSecretKey;secretKeyInput.type="password";setupButton(element,"rs-cipher","cipherIcon",this.events["secret-entered"]);secretKeyInput.addEventListener("load",handleButtonState),secretKeyInput.addEventListener("keyup",handleButtonState),setupButton(element,"rs-nocipher","nocipherIcon",this.events["secret-cancelled"])}this.cube=setupButton(element,"rs-cube","remoteStorageIcon",this.toggleBubble.bind(this)),setupButton(element,"rs-dropbox","dropbox",this.connectDropbox.bind(this)),setupButton(element,"rs-googledrive","googledrive",this.connectGdrive.bind(this));var bubbleDontCatch={INPUT:!0,BUTTON:!0,IMG:!0},eventListener=function(event){bubbleDontCatch[event.target.tagName]||this.div.classList.contains("remotestorage-state-unauthorized")||this.showBubble(event)}.bind(this);return this.bubble=setupButton(element,"rs-bubble",void 0,eventListener),this.hideBubble(),this.div=element,this.states.initial.call(this),this.events.display.call(this),this.div},states:{initial:function(message){var cube=this.cube,info=message||t("view_info");cube.src=RemoteStorage.Assets.remoteStorageIcon,this._renderTranslatedInitialContent(),message?(cube.src=RemoteStorage.Assets.remoteStorageIconError,removeClass(this.cube,"remotestorage-loading"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},2e3)):this.hideBubble(),this.div.className="remotestorage-state-initial",this.userSecretKey&&delete this.userSecretKey;var backends=1;this._activateBackend("dropbox")&&(backends+=1),this._activateBackend("googledrive")&&(backends+=1),this.div.querySelector(".rs-bubble-text").style.paddingRight=32*backends+8+"px";var cb=this.div.querySelector(".connect");this.form.userAddress.value&&cb.removeAttribute("disabled");var infoEl=this.div.querySelector(".rs-info-msg");infoEl.innerHTML=info,message?infoEl.classList.add("remotestorage-error-info"):infoEl.classList.remove("remotestorage-error-info")},authing:function(){this.div.removeEventListener("click",this.events.connect),this.div.className="remotestorage-state-authing",this.div.querySelector(".rs-status-text").innerHTML=t("view_connecting",this.userAddress),addClass(this.cube,"remotestorage-loading")},connected:function(){var cube=this.cube;this.div.className="remotestorage-state-connected",this.div.querySelector(".userAddress").innerHTML=this.userAddress,cube.src=RemoteStorage.Assets.remoteStorageIcon,removeClass(cube,"remotestorage-loading"),this.cipher&&(this.userSecretKey?this.userSecretKeyError?(cube.src=RemoteStorage.Assets.remoteStorageIconError,addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),addClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),this.showBubble(),setTimeout(function(){cube.src=RemoteStorage.Assets.remoteStorageIcon},5e3)):(removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),cube.src=RemoteStorage.Assets.remoteStorageIconCiphered):(addClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.showBubble()));var icons={googledrive:this.div.querySelector(".rs-googledrive"),dropbox:this.div.querySelector(".rs-dropbox")};icons.googledrive.style.display=icons.dropbox.style.display="none",icons[this.rs.backend]?(icons[this.rs.backend].style.display="inline-block",this.div.querySelector(".rs-bubble-text").style.paddingRight="72px"):this.div.querySelector(".rs-bubble-text").style.paddingRight="40px"},ciphered:function(){this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value="",removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.cube.src=RemoteStorage.Assets.remoteStorageIconCiphered,this.hideBubble()},notciphered:function(){this.cipher=!1,removeClass(this.div.querySelector(".remotestorage-invalid-key"),"remotestorage-cipher-error"),removeClass(this.div.querySelector(".remotestorage-connected"),"remotestorage-cipher"),this.hideBubble()},busy:function(){this.div.className="remotestorage-state-busy",addClass(this.cube,"remotestorage-loading")},offline:function(){this.div.className="remotestorage-state-offline",this.cube.src=RemoteStorage.Assets.remoteStorageIconOffline,this.div.querySelector(".rs-status-text").innerHTML=t("view_offline")},error:function(err){var errorMsg=err;this.div.className="remotestorage-state-error",this.div.querySelector(".rs-bubble-text").innerHTML=""+t("view_error_occured")+"",err instanceof Error&&(errorMsg=err.message+"\n\n"+err.stack),this.div.querySelector(".rs-error-msg").textContent=errorMsg,this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble()},unauthorized:function(){this.div.className="remotestorage-state-unauthorized",this.cube.src=RemoteStorage.Assets.remoteStorageIconError,this.showBubble(),this.div.addEventListener("click",this.events.connect)}},events:{connect:function(event){stopPropagation(event),event.preventDefault(),this._emit("connect",this.div.querySelector("form.remotestorage-initial").userAddress.value)},"secret-entered":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-entered",this.div.querySelector("form.remotestorage-cipher-form").userSecretKey.value)},"secret-cancelled":function(event){stopPropagation(event),event.preventDefault(),this._emit("secret-cancelled")},sync:function(event){stopPropagation(event),event.preventDefault(),this._emit("sync")},disconnect:function(event){stopPropagation(event),event.preventDefault(),this._emit("disconnect")},reset:function(event){event.preventDefault();var result=window.confirm(t("view_confirm_reset"));result&&this._emit("reset")},display:function(event){event&&event.preventDefault(),this._emit("display")}},_renderTranslatedInitialContent:function(){this.div.querySelector(".rs-status-text").innerHTML=t("view_connect"),this.div.querySelector(".remotestorage-reset").innerHTML=t("view_get_me_out"),this.div.querySelector(".rs-error-plz-report").innerHTML=t("view_error_plz_report"),this.div.querySelector(".remotestorage-unauthorized").innerHTML=t("view_unauthorized"),this.div.querySelector(".remotestorage-invalid-key").innerHTML=t("view_invalid_key")},_activateBackend:function(backendName){var className="rs-"+backendName;return this.rs.apiKeys[backendName]?(this.div.querySelector("."+className).style.display="inline-block",!0):(this.div.querySelector("."+className).style.display="none",!1)}}}("undefined"!=typeof window?window:global),function(global,factory){"function"==typeof define&&define.amd?define([],factory):"undefined"!=typeof module&&module.exports?module.exports=factory():global.tv4=factory()}(this,function(){function notReallyPercentEncode(string){return encodeURI(string).replace(/%25[0-9][0-9]/g,function(doubleEncoded){return"%"+doubleEncoded.substring(3)})}function uriTemplateSubstitution(spec){var modifier="";uriTemplateGlobalModifiers[spec.charAt(0)]&&(modifier=spec.charAt(0),spec=spec.substring(1));var separator="",prefix="",shouldEscape=!0,showVariables=!1,trimEmptyString=!1;"+"===modifier?shouldEscape=!1:"."===modifier?(prefix=".",separator="."):"/"===modifier?(prefix="/",separator="/"):"#"===modifier?(prefix="#",shouldEscape=!1):";"===modifier?(prefix=";",separator=";",showVariables=!0,trimEmptyString=!0):"?"===modifier?(prefix="?",separator="&",showVariables=!0):"&"===modifier&&(prefix="&",separator="&",showVariables=!0);for(var varNames=[],varList=spec.split(","),varSpecs=[],varSpecMap={},i=0;i0&&(result+=varSpec.suffices["*"]?separator||",":",",varSpec.suffices["*"]&&showVariables&&(result+=varSpec.name+"=")),result+=shouldEscape?encodeURIComponent(value[j]).replace(/!/g,"%21"):notReallyPercentEncode(value[j])}else if("object"==typeof value){showVariables&&!varSpec.suffices["*"]&&(result+=varSpec.name+"=");var first=!0;for(var key in value)first||(result+=varSpec.suffices["*"]?separator||",":","),first=!1,result+=shouldEscape?encodeURIComponent(key).replace(/!/g,"%21"):notReallyPercentEncode(key),result+=varSpec.suffices["*"]?"=":",",result+=shouldEscape?encodeURIComponent(value[key]).replace(/!/g,"%21"):notReallyPercentEncode(value[key])}else showVariables&&(result+=varSpec.name,trimEmptyString&&""===value||(result+="=")),null!=varSpec.truncate&&(value=value.substring(0,varSpec.truncate)),result+=shouldEscape?encodeURIComponent(value).replace(/!/g,"%21"):notReallyPercentEncode(value)}return result};return subFunction.varNames=varNames,{prefix:prefix,substitution:subFunction}}function UriTemplate(template){if(!(this instanceof UriTemplate))return new UriTemplate(template);for(var parts=template.split("{"),textParts=[parts.shift()],prefixes=[],substitutions=[],varNames=[];parts.length>0;){var part=parts.shift(),spec=part.split("}")[0],remainder=part.substring(spec.length+1),funcs=uriTemplateSubstitution(spec);substitutions.push(funcs.substitution),prefixes.push(funcs.prefix),textParts.push(remainder),varNames=varNames.concat(funcs.substitution.varNames)}this.fill=function(valueFunction){for(var result=textParts[0],i=0;i0&&"/"===testUrl.charAt(baseUrl.length-1)||"#"===remainder.charAt(0)||"?"===remainder.charAt(0))return!0}return!1}function createApi(language){var currentLanguage,customErrorReporter,globalContext=new ValidatorContext,api={setErrorReporter:function(reporter){return"string"==typeof reporter?this.language(reporter):(customErrorReporter=reporter,!0)},addFormat:function(){globalContext.addFormat.apply(globalContext,arguments)},language:function(code){return code?(languages[code]||(code=code.split("-")[0]),languages[code]?(currentLanguage=code,code):!1):currentLanguage},addLanguage:function(code,messageMap){var key;for(key in ErrorCodes)messageMap[key]&&!messageMap[ErrorCodes[key]]&&(messageMap[ErrorCodes[key]]=messageMap[key]);var rootCode=code.split("-")[0];if(languages[rootCode]){languages[code]=Object.create(languages[rootCode]);for(key in messageMap)"undefined"==typeof languages[rootCode][key]&&(languages[rootCode][key]=messageMap[key]),languages[code][key]=messageMap[key]}else languages[code]=messageMap,languages[rootCode]=messageMap;return this},freshApi:function(language){var result=createApi();return language&&result.language(language),result},validate:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!1,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema);var error=context.validateAll(data,schema,null,null,"");return!error&&banUnknownProperties&&(error=context.banUnknownProperties(data,schema)),this.error=error,this.missing=context.missing,this.valid=null===error,this.valid},validateResult:function(){var result={};return this.validate.apply(result,arguments),result},validateMultiple:function(data,schema,checkRecursive,banUnknownProperties){var def=defaultErrorReporter(currentLanguage),errorReporter=customErrorReporter?function(error,data,schema){return customErrorReporter(error,data,schema)||def(error,data,schema)}:def,context=new ValidatorContext(globalContext,!0,errorReporter,checkRecursive,banUnknownProperties);"string"==typeof schema&&(schema={$ref:schema}),context.addSchema("",schema),context.validateAll(data,schema,null,null,""),banUnknownProperties&&context.banUnknownProperties(data,schema);var result={};return result.errors=context.errors,result.missing=context.missing,result.valid=0===result.errors.length,result},addSchema:function(){return globalContext.addSchema.apply(globalContext,arguments)},getSchema:function(){return globalContext.getSchema.apply(globalContext,arguments)},getSchemaMap:function(){return globalContext.getSchemaMap.apply(globalContext,arguments)},getSchemaUris:function(){return globalContext.getSchemaUris.apply(globalContext,arguments)},getMissingUris:function(){return globalContext.getMissingUris.apply(globalContext,arguments)},dropSchemas:function(){globalContext.dropSchemas.apply(globalContext,arguments)},defineKeyword:function(){globalContext.defineKeyword.apply(globalContext,arguments)},defineError:function(codeName,codeNumber,defaultMessage){if("string"!=typeof codeName||!/^[A-Z]+(_[A-Z]+)*$/.test(codeName))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof codeNumber||codeNumber%1!==0||1e4>codeNumber)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof ErrorCodes[codeName])throw new Error("Error already defined: "+codeName+" as "+ErrorCodes[codeName]);if("undefined"!=typeof ErrorCodeLookup[codeNumber])throw new Error("Error code already used: "+ErrorCodeLookup[codeNumber]+" as "+codeNumber);ErrorCodes[codeName]=codeNumber,ErrorCodeLookup[codeNumber]=codeName,ErrorMessagesDefault[codeName]=ErrorMessagesDefault[codeNumber]=defaultMessage;for(var langCode in languages){var language=languages[langCode];language[codeName]&&(language[codeNumber]=language[codeNumber]||language[codeName])}},reset:function(){globalContext.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:normSchema,resolveUrl:resolveUrl,getDocumentUri:getDocumentUri,errorCodes:ErrorCodes};return api.language(language||"en"),api}Object.keys||(Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if("object"!=typeof obj&&"function"!=typeof obj||null===obj)throw new TypeError("Object.keys called on non-object");var result=[];for(var prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(var i=0;dontEnumsLength>i;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result}}()),Object.create||(Object.create=function(){function F(){}return function(o){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Array.isArray||(Array.isArray=function(vArg){return"[object Array]"===Object.prototype.toString.call(vArg)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(searchElement){if(null===this)throw new TypeError;var t=Object(this),len=t.length>>>0;if(0===len)return-1;var n=0;if(arguments.length>1&&(n=Number(arguments[1]),n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=len)return-1;for(var k=n>=0?n:Math.max(len-Math.abs(n),0);len>k;k++)if(k in t&&t[k]===searchElement)return k;return-1}),Object.isFrozen||(Object.isFrozen=function(obj){for(var key="tv4_test_frozen_key";obj.hasOwnProperty(key);)key+=Math.random();try{return obj[key]=!0,delete obj[key],!1}catch(e){return!0}});var uriTemplateGlobalModifiers={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},uriTemplateSuffices={"*":!0};UriTemplate.prototype={toString:function(){return this.template},fillFromObject:function(obj){return this.fill(function(varName){return obj[varName]})}};var ValidatorContext=function(parent,collectMultiple,errorReporter,checkRecursive,trackUnknownProperties){if(this.missing=[],this.missingMap={},this.formatValidators=parent?Object.create(parent.formatValidators):{},this.schemas=parent?Object.create(parent.schemas):{},this.collectMultiple=collectMultiple,this.errors=[],this.handleError=collectMultiple?this.collectError:this.returnError,checkRecursive&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),trackUnknownProperties&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=errorReporter||defaultErrorReporter("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},parent)for(var key in parent.definedKeywords)this.definedKeywords[key]=parent.definedKeywords[key].slice(0)};ValidatorContext.prototype.defineKeyword=function(keyword,keywordFunction){this.definedKeywords[keyword]=this.definedKeywords[keyword]||[],this.definedKeywords[keyword].push(keywordFunction)},ValidatorContext.prototype.createError=function(code,messageParams,dataPath,schemaPath,subErrors,data,schema){var error=new ValidationError(code,messageParams,dataPath,schemaPath,subErrors);return error.message=this.errorReporter(error,data,schema),error},ValidatorContext.prototype.returnError=function(error){return error},ValidatorContext.prototype.collectError=function(error){return error&&this.errors.push(error),null},ValidatorContext.prototype.prefixErrors=function(startIndex,dataPath,schemaPath){for(var i=startIndex;i=CLOSE_ENOUGH_LOW&&CLOSE_ENOUGH_HIGH>remainder)return this.createError(ErrorCodes.NUMBER_MULTIPLE_OF,{value:data,multipleOf:multipleOf},"","",null,data,schema)}return null},ValidatorContext.prototype.validateMinMax=function(data,schema){if("number"!=typeof data)return null;if(void 0!==schema.minimum){if(dataschema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM,{value:data,maximum:schema.maximum},"","/maximum",null,data,schema);if(schema.exclusiveMaximum&&data===schema.maximum)return this.createError(ErrorCodes.NUMBER_MAXIMUM_EXCLUSIVE,{value:data,maximum:schema.maximum},"","/exclusiveMaximum",null,data,schema)}return null},ValidatorContext.prototype.validateNaN=function(data,schema){return"number"!=typeof data?null:isNaN(data)===!0||data===1/0||data===-(1/0)?this.createError(ErrorCodes.NUMBER_NOT_A_NUMBER,{value:data},"","/type",null,data,schema):null},ValidatorContext.prototype.validateString=function(data,schema,dataPointerPath){return this.validateStringLength(data,schema,dataPointerPath)||this.validateStringPattern(data,schema,dataPointerPath)||null},ValidatorContext.prototype.validateStringLength=function(data,schema){return"string"!=typeof data?null:void 0!==schema.minLength&&data.lengthschema.maxLength?this.createError(ErrorCodes.STRING_LENGTH_LONG,{length:data.length,maximum:schema.maxLength},"","/maxLength",null,data,schema):null},ValidatorContext.prototype.validateStringPattern=function(data,schema){if("string"!=typeof data||"string"!=typeof schema.pattern&&!(schema.pattern instanceof RegExp))return null;var regexp;if(schema.pattern instanceof RegExp)regexp=schema.pattern;else{var body,flags="",literal=schema.pattern.match(/^\/(.+)\/([img]*)$/);literal?(body=literal[1],flags=literal[2]):body=schema.pattern,regexp=new RegExp(body,flags)}return regexp.test(data)?null:this.createError(ErrorCodes.STRING_PATTERN,{pattern:schema.pattern},"","/pattern",null,data,schema)},ValidatorContext.prototype.validateArray=function(data,schema,dataPointerPath){return Array.isArray(data)?this.validateArrayLength(data,schema,dataPointerPath)||this.validateArrayUniqueItems(data,schema,dataPointerPath)||this.validateArrayItems(data,schema,dataPointerPath)||null:null},ValidatorContext.prototype.validateArrayLength=function(data,schema){var error;return void 0!==schema.minItems&&data.lengthschema.maxItems&&(error=this.createError(ErrorCodes.ARRAY_LENGTH_LONG,{length:data.length,maximum:schema.maxItems},"","/maxItems",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateArrayUniqueItems=function(data,schema){if(schema.uniqueItems)for(var i=0;ischema.maxProperties&&(error=this.createError(ErrorCodes.OBJECT_PROPERTIES_MAXIMUM,{propertyCount:keys.length,maximum:schema.maxProperties},"","/maxProperties",null,data,schema),this.handleError(error))?error:null},ValidatorContext.prototype.validateObjectRequiredProperties=function(data,schema){if(void 0!==schema.required)for(var i=0;ii;i++)uuid[i]=chars[0|Math.random()*radix];else{var r;for(uuid[8]=uuid[13]=uuid[18]=uuid[23]="-",uuid[14]="4",i=0;36>i;i++)uuid[i]||(r=0|16*Math.random(),uuid[i]=chars[19==i?3&r|8:r])}return uuid.join("")},function(global){function deprecate(thing,replacement){console.log("WARNING: "+thing+" is deprecated. Use "+replacement+" instead.")}var RS=RemoteStorage;RS.BaseClient=function(storage,base){if("/"!==base[base.length-1])throw"Not a folder: "+base;"/"===base&&(this.makePath=function(path){return("/"===path[0]?"":"/")+path}),this.storage=storage,this.base=base;var parts=this.base.split("/");parts.length>2?this.moduleName=parts[1]:this.moduleName="root",RS.eventHandling(this,"change"),this.on=this.on.bind(this),storage.onChange(this.base,this._fireChange.bind(this))},RS.BaseClient.prototype={extend:function(object){for(var key in object)this[key]=object[key];return this},scope:function(path){return new RS.BaseClient(this.storage,this.makePath(path))},getListing:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){return 404===r.statusCode?{}:r.body})},getAll:function(path,maxAge){if("string"!=typeof path)path="";else if(path.length>0&&"/"!==path[path.length-1])return Promise.reject("Not a folder: "+path);return this.storage.get(this.makePath(path),maxAge).then(function(r){if(404===r.statusCode)return{};if("object"==typeof r.body){var keys=Object.keys(r.body);if(0===keys.length)return{};var calls=keys.map(function(key){return this.storage.get(this.makePath(path+key),maxAge).then(function(o){if("string"==typeof o.body)try{o.body=JSON.parse(o.body)}catch(e){}"object"==typeof o.body&&(r.body[key]=o.body)})}.bind(this));return Promise.all(calls).then(function(){return r.body})}}.bind(this))},getFile:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getFile must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){return{data:r.body,contentType:r.contentType,revision:r.revision}})},storeFile:function(mimeType,path,body){return"string"!=typeof mimeType?Promise.reject("Argument 'mimeType' of baseClient.storeFile must be a string"):"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.storeFile must be a string"):"string"!=typeof body&&"object"!=typeof body?Promise.reject("Argument 'body' of baseClient.storeFile must be a string, ArrayBuffer, or ArrayBufferView"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Editing a document to which only read access ('r') was claimed"),this.storage.put(this.makePath(path),body,mimeType).then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this)))},getObject:function(path,maxAge){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.getObject must be a string"):this.storage.get(this.makePath(path),maxAge).then(function(r){if("object"==typeof r.body)return r.body;if("string"==typeof r.body)try{return JSON.parse(r.body)}catch(e){throw"Not valid JSON: "+this.makePath(path)}else if("undefined"!=typeof r.body&&200===r.statusCode)return Promise.reject("Not an object: "+this.makePath(path))}.bind(this))},storeObject:function(typeAlias,path,object){if("string"!=typeof typeAlias)return Promise.reject("Argument 'typeAlias' of baseClient.storeObject must be a string");if("string"!=typeof path)return Promise.reject("Argument 'path' of baseClient.storeObject must be a string");if("object"!=typeof object)return Promise.reject("Argument 'object' of baseClient.storeObject must be an object");this._attachType(object,typeAlias);try{var validationResult=this.validate(object);if(!validationResult.valid)return Promise.reject(validationResult)}catch(exc){return Promise.reject(exc)}return this.storage.put(this.makePath(path),JSON.stringify(object),"application/json; charset=UTF-8").then(function(r){return 200===r.statusCode||201===r.statusCode?r.revision:Promise.reject("Request (PUT "+this.makePath(path)+") failed with status: "+r.statusCode)}.bind(this))},remove:function(path){return"string"!=typeof path?Promise.reject("Argument 'path' of baseClient.remove must be a string"):(this.storage.access.checkPathPermission(this.makePath(path),"rw")||console.warn("WARNING: Removing a document to which only read access ('r') was claimed"),this.storage["delete"](this.makePath(path)))},cache:function(path,strategy){if("string"!=typeof path)throw"Argument 'path' of baseClient.cache must be a string";if(strategy===!1?(deprecate("caching strategy ",'<"FLUSH">'),strategy="FLUSH"):void 0===strategy?strategy="ALL":"string"!=typeof strategy&&(deprecate("that caching strategy",'<"ALL">'),strategy="ALL"),"FLUSH"!==strategy&&"SEEN"!==strategy&&"ALL"!==strategy)throw'Argument \'strategy\' of baseclient.cache must be one of ["FLUSH", "SEEN", "ALL"]';return this.storage.caching.set(this.makePath(path),strategy),this},flush:function(path){return this.storage.local.flush(path)},makePath:function(path){return this.base+(path||"")},_fireChange:function(event){RemoteStorage.config.changeEvents[event.origin]&&(["new","old","lastCommon"].forEach(function(fieldNamePrefix){if((!event[fieldNamePrefix+"ContentType"]||/^application\/(.*)json(.*)/.exec(event[fieldNamePrefix+"ContentType"]))&&"string"==typeof event[fieldNamePrefix+"Value"])try{event[fieldNamePrefix+"Value"]=JSON.parse(event[fieldNamePrefix+"Value"])}catch(e){}}),this._emit("change",event))},_cleanPath:RemoteStorage.util.cleanPath,getItemURL:function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.getItemURL must be a string";return this.storage.connected?(path=this._cleanPath(this.makePath(path)),this.storage.remote.href+path):void 0},uuid:function(){return Math.uuid()}},RS.BaseClient._rs_init=function(){RS.prototype.scope=function(path){if("string"!=typeof path)throw"Argument 'path' of baseClient.scope must be a string";if(!this.access.checkPathPermission(path,"r")){var escapedPath=path.replace(/(['\\])/g,"\\$1");console.warn("WARNING: please call remoteStorage.access.claim('"+escapedPath+"', 'r') (read only) or remoteStorage.access.claim('"+escapedPath+"', 'rw') (read/write) first")}return new RS.BaseClient(this,path)}}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.BaseClient.Types={uris:{},schemas:{},aliases:{},declare:function(moduleName,alias,uri,schema){var fullAlias=moduleName+"/"+alias;if(schema["extends"]){var extendedAlias,parts=schema["extends"].split("/");extendedAlias=1===parts.length?moduleName+"/"+parts.shift():parts.join("/");var extendedUri=this.uris[extendedAlias];if(!extendedUri)throw"Type '"+fullAlias+"' tries to extend unknown schema '"+extendedAlias+"'";schema["extends"]=this.schemas[extendedUri]}this.uris[fullAlias]=uri,this.aliases[uri]=fullAlias,this.schemas[uri]=schema},resolveAlias:function(alias){return this.uris[alias]},getSchema:function(uri){return this.schemas[uri]},inScope:function(moduleName){var ml=moduleName.length,schemas={};for(var alias in this.uris)if(alias.substr(0,ml+1)===moduleName+"/"){var uri=this.uris[alias];schemas[uri]=this.schemas[uri]}return schemas}};var SchemaNotFound=function(uri){var error=new Error("Schema not found: "+uri);return error.name="SchemaNotFound",error};SchemaNotFound.prototype=Error.prototype,RemoteStorage.BaseClient.Types.SchemaNotFound=SchemaNotFound,RemoteStorage.BaseClient.prototype.extend({declareType:function(alias,uri,schema){schema||(schema=uri,uri=this._defaultTypeURI(alias)),RemoteStorage.BaseClient.Types.declare(this.moduleName,alias,uri,schema)},validate:function(object){var schema=RemoteStorage.BaseClient.Types.getSchema(object["@context"]);if(schema)return tv4.validateResult(object,schema);throw new SchemaNotFound(object["@context"])},_defaultTypeURI:function(alias){return"http://remotestorage.io/spec/modules/"+encodeURIComponent(this.moduleName)+"/"+encodeURIComponent(alias)},_attachType:function(object,alias){object["@context"]=RemoteStorage.BaseClient.Types.resolveAlias(this.moduleName+"/"+alias)||this._defaultTypeURI(alias)}}),Object.defineProperty(RemoteStorage.BaseClient.prototype,"schemas",{configurable:!0,get:function(){return RemoteStorage.BaseClient.Types.inScope(this.moduleName)}})}("undefined"!=typeof window?window:global),function(global){var containingFolder=RemoteStorage.util.containingFolder;RemoteStorage.Caching=function(){this.reset(); -},RemoteStorage.Caching.prototype={pendingActivations:[],set:function(path,strategy){if("string"!=typeof path)throw new Error("path should be a string");if(!RemoteStorage.util.isFolder(path))throw new Error("path should be a folder");if(this._remoteStorage&&this._remoteStorage.access&&!this._remoteStorage.access.checkPathPermission(path,"r"))throw new Error('No access to path "'+path+'". You have to claim access to it first.');if(!strategy.match(/^(FLUSH|SEEN|ALL)$/))throw new Error("strategy should be 'FLUSH', 'SEEN', or 'ALL'");this._rootPaths[path]=strategy,"ALL"===strategy&&(this.activateHandler?this.activateHandler(path):this.pendingActivations.push(path))},enable:function(path){this.set(path,"ALL")},disable:function(path){this.set(path,"FLUSH")},onActivate:function(cb){var i;for(RemoteStorage.log("[Caching] Setting activate handler",cb,this.pendingActivations),this.activateHandler=cb,i=0;i1e3&&36e5>interval}var syncInterval=1e4,backgroundSyncInterval=6e4,isBackground=!1,isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,equal=RemoteStorage.util.equal,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=RemoteStorage.util.pathsFromRoot;RemoteStorage.Sync=function(setLocal,setRemote,setAccess,setCaching){this.local=setLocal,this.local.onDiff(function(path){this.addTask(path),this.doTasks()}.bind(this)),this.remote=setRemote,this.access=setAccess,this.caching=setCaching,this._tasks={},this._running={},this._timeStarted={},RemoteStorage.eventHandling(this,"done","req-done"),this.caching.onActivate(function(path){this.addTask(path),this.doTasks()}.bind(this))},RemoteStorage.Sync.prototype={now:function(){return(new Date).getTime()},queueGetRequest:function(path){var pending=Promise.defer();return this.remote.connected?this.remote.online?(this.addTask(path,function(){this.local.get(path).then(function(r){return pending.resolve(r)})}.bind(this)),this.doTasks()):pending.reject("cannot fulfill maxAge requirement - remote is not online"):pending.reject("cannot fulfill maxAge requirement - remote is not connected"),pending.promise},corruptServerItemsMap:function(itemsMap,force02){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap){var item=itemsMap[itemName];if("object"!=typeof item)return!0;if("string"!=typeof item.ETag)return!0;if(isFolder(itemName)){if(-1!==itemName.substring(0,itemName.length-1).indexOf("/"))return!0}else{if(-1!==itemName.indexOf("/"))return!0;if(force02){if("string"!=typeof item["Content-Type"])return!0;if("number"!=typeof item["Content-Length"])return!0}}}return!1},corruptItemsMap:function(itemsMap){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap)if("boolean"!=typeof itemsMap[itemName])return!0;return!1},corruptRevision:function(rev){return"object"!=typeof rev||Array.isArray(rev)||rev.revision&&"string"!=typeof rev.revision||rev.body&&"string"!=typeof rev.body&&"object"!=typeof rev.body||rev.contentType&&"string"!=typeof rev.contentType||rev.contentLength&&"number"!=typeof rev.contentLength||rev.timestamp&&"number"!=typeof rev.timestamp||rev.itemsMap&&this.corruptItemsMap(rev.itemsMap)},isCorrupt:function(node){return"object"!=typeof node||Array.isArray(node)||"string"!=typeof node.path||this.corruptRevision(node.common)||node.local&&this.corruptRevision(node.local)||node.remote&&this.corruptRevision(node.remote)||node.push&&this.corruptRevision(node.push)},hasTasks:function(){return Object.getOwnPropertyNames(this._tasks).length>0},collectDiffTasks:function(){var num=0;return this.local.forAllNodes(function(node){num>100||(this.isCorrupt(node)?(RemoteStorage.log("[Sync] WARNING: corrupt node in local cache",node),"object"==typeof node&&node.path&&(this.addTask(node.path),num++)):this.needsFetch(node)&&this.access.checkPathPermission(node.path,"r")?(this.addTask(node.path),num++):isDocument(node.path)&&this.needsPush(node)&&this.access.checkPathPermission(node.path,"rw")&&(this.addTask(node.path),num++))}.bind(this)).then(function(){return num},function(err){throw err})},inConflict:function(node){return node.local&&node.remote&&(void 0!==node.remote.body||node.remote.itemsMap)},needsRefresh:function(node){return node.common?node.common.timestamp?this.now()-node.common.timestamp>syncInterval:!0:!1},needsFetch:function(node){return this.inConflict(node)?!0:node.common&&void 0===node.common.itemsMap&&void 0===node.common.body?!0:!(!node.remote||void 0!==node.remote.itemsMap||void 0!==node.remote.body)},needsPush:function(node){return this.inConflict(node)?!1:node.local&&!node.push?!0:void 0},needsRemotePut:function(node){return node.local&&node.local.body},needsRemoteDelete:function(node){return node.local&&node.local.body===!1},getParentPath:function(path){var parts=path.match(/^(.*\/)([^\/]+\/?)$/);if(parts)return parts[1];throw new Error('Not a valid path: "'+path+'"')},deleteChildPathsFromTasks:function(){for(var path in this._tasks)for(var paths=pathsFromRoot(path),i=1;i=numToAdd)return!0;for(path in this._tasks)if(!this._running[path]&&(this._timeStarted[path]=this.now(),this._running[path]=this.doTask(path),this._running[path].then(this.finishTask.bind(this)),numAdded++,numAdded>=numToAdd))return!0;return numAdded>=numToAdd},collectTasks:function(alsoCheckRefresh){return this.hasTasks()||this.stopped?Promise.resolve():this.collectDiffTasks().then(function(numDiffs){return numDiffs||alsoCheckRefresh===!1?Promise.resolve():this.collectRefreshTasks()}.bind(this),function(err){throw err})},addTask:function(path,cb){this._tasks[path]||(this._tasks[path]=[]),"function"==typeof cb&&this._tasks[path].push(cb)},sync:function(){return this.done=!1,this.doTasks()?Promise.resolve():this.collectTasks().then(function(){try{this.doTasks()}catch(e){console.error("[Sync] doTasks error",e)}}.bind(this),function(e){throw console.error("[Sync] Sync error",e),new Error("Local cache unavailable")})}},RemoteStorage.prototype.getSyncInterval=function(){return syncInterval},RemoteStorage.prototype.setSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=syncInterval;syncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getBackgroundSyncInterval=function(){return backgroundSyncInterval},RemoteStorage.prototype.setBackgroundSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=backgroundSyncInterval;backgroundSyncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getCurrentSyncInterval=function(){return isBackground?backgroundSyncInterval:syncInterval};var SyncError=function(originalError){var msg="Sync failed: ";msg+="object"==typeof originalError&&"message"in originalError?originalError.message:originalError,this.originalError=originalError,this.message=msg};SyncError.prototype=new Error,SyncError.prototype.constructor=SyncError,RemoteStorage.SyncError=SyncError,RemoteStorage.prototype.syncCycle=function(){this.sync.stopped||(this.sync.on("done",function(){RemoteStorage.log("[Sync] Sync done. Setting timer to",this.getCurrentSyncInterval()),this.sync.stopped||(this._syncTimer&&clearTimeout(this._syncTimer),this._syncTimer=setTimeout(this.sync.sync.bind(this.sync),this.getCurrentSyncInterval()))}.bind(this)),this.sync.sync())},RemoteStorage.prototype.stopSync=function(){this.sync?(RemoteStorage.log("[Sync] Stopping sync"),this.sync.stopped=!0):(RemoteStorage.log("[Sync] Will instantiate sync stopped"),this.syncStopped=!0)},RemoteStorage.prototype.startSync=function(){this.sync.stopped=!1,this.syncStopped=!1,this.sync.sync()};var syncCycleCb;RemoteStorage.Sync._rs_init=function(remoteStorage){syncCycleCb=function(){RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),RemoteStorage.Env.isBrowser()&&handleVisibility.bind(remoteStorage)(),remoteStorage.sync||(remoteStorage.sync=new RemoteStorage.Sync(remoteStorage.local,remoteStorage.remote,remoteStorage.access,remoteStorage.caching),remoteStorage.syncStopped&&(RemoteStorage.log("[Sync] Instantiating sync stopped"),remoteStorage.sync.stopped=!0,delete remoteStorage.syncStopped)),RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),remoteStorage.syncCycle()},syncOnConnect=function(){remoteStorage.removeEventListener("connected",syncOnConnect),remoteStorage.startSync()},remoteStorage.on("ready",syncCycleCb),remoteStorage.on("connected",syncOnConnect)},RemoteStorage.Sync._rs_cleanup=function(remoteStorage){remoteStorage.stopSync(),remoteStorage.removeEventListener("ready",syncCycleCb),remoteStorage.removeEventListener("connected",syncOnConnect),delete remoteStorage.sync}}("undefined"!=typeof window?window:global),function(){function getLatest(node){if("object"==typeof node&&"string"==typeof node.path)if(isFolder(node.path)){if(node.local&&node.local.itemsMap)return node.local;if(node.common&&node.common.itemsMap)return node.common}else{if(node.local&&node.local.body&&node.local.contentType)return node.local;if(node.common&&node.common.body&&node.common.contentType)return node.common;if(node.body&&node.contentType)return{body:node.body,contentType:node.contentType}}}function isOutdated(nodes,maxAge){var path;for(path in nodes){if(nodes[path]&&nodes[path].remote)return!0;var nodeVersion=getLatest(nodes[path]);if(nodeVersion&&nodeVersion.timestamp&&(new Date).getTime()-nodeVersion.timestamp<=maxAge)return!1;if(!nodeVersion)return!0}return!0}function makeNode(path){var node={path:path,common:{}};return isFolder(path)&&(node.common.itemsMap={}),node}function updateFolderNodeWithItemName(node,itemName){return node.common||(node.common={itemsMap:{}}),node.common.itemsMap||(node.common.itemsMap={}),node.local||(node.local=deepClone(node.common)),node.local.itemsMap||(node.local.itemsMap=node.common.itemsMap),node.local.itemsMap[itemName]=!0,node}var isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=(RemoteStorage.util.equal,RemoteStorage.util.pathsFromRoot),methods={get:function(path,maxAge,queueGetRequest){var self=this;return"number"==typeof maxAge?self.getNodes(pathsFromRoot(path)).then(function(objs){var node=getLatest(objs[path]);return isOutdated(objs,maxAge)?queueGetRequest(path):node?{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}:{statusCode:404}}):self.getNodes([path]).then(function(objs){var node=getLatest(objs[path]);if(node){if(isFolder(path))for(var i in node.itemsMap)node.itemsMap.hasOwnProperty(i)&&node.itemsMap[i]===!1&&delete node.itemsMap[i];return{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}}return{statusCode:404}})},put:function(path,body,contentType){function _processNodes(paths,nodes){try{for(var i=0,len=paths.length;len>i;i++){var previous,path=paths[i],node=nodes[path];if(node||(nodes[path]=node=makeNode(path)),0===i)previous=getLatest(node),node.local={body:body,contentType:contentType,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{var itemName=paths[i-1].substring(path.length);node=updateFolderNodeWithItemName(node,itemName)}}return nodes}catch(e){throw RemoteStorage.log("[Cachinglayer] Error during PUT",nodes,i,e),e}}var paths=pathsFromRoot(path);return this._updateNodes(paths,_processNodes)},"delete":function(path){var paths=pathsFromRoot(path);return this._updateNodes(paths,function(paths,nodes){for(var i=0,len=paths.length;len>i;i++){var path=paths[i],node=nodes[path];if(!node)throw new Error("Cannot delete non-existing node "+path);if(0===i)previous=getLatest(node),node.local={body:!1,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{node.local||(node.local=deepClone(node.common));var itemName=paths[i-1].substring(path.length);if(delete node.local.itemsMap[itemName],Object.getOwnPropertyNames(node.local.itemsMap).length>0)break}}return nodes})},flush:function(path){var self=this;return self._getAllDescendentPaths(path).then(function(paths){return self.getNodes(paths)}).then(function(nodes){for(var path in nodes){var node=nodes[path];node&&node.common&&node.local&&self._emitChange({path:node.path,origin:"local",oldValue:node.local.body===!1?void 0:node.local.body,newValue:node.common.body===!1?void 0:node.common.body}),nodes[path]=void 0}return self.setNodes(nodes)})},_emitChange:function(obj){RemoteStorage.config.changeEvents[obj.origin]&&this._emit("change",obj)},fireInitial:function(){if(RemoteStorage.config.changeEvents.local){var self=this;self.forAllNodes(function(node){var latest;isDocument(node.path)&&(latest=getLatest(node),latest&&self._emitChange({path:node.path,origin:"local",oldValue:void 0,oldContentType:void 0,newValue:latest.body,newContentType:latest.contentType}))}).then(function(){self._emit("local-events-done")})}},onDiff:function(diffHandler){this.diffHandler=diffHandler},migrate:function(node){return"object"!=typeof node||node.common||(node.common={},"string"==typeof node.path?"/"===node.path.substr(-1)&&"object"==typeof node.body&&(node.common.itemsMap=node.body):(node.local||(node.local={}),node.local.body=node.body,node.local.contentType=node.contentType)),node},_updateNodesRunning:!1,_updateNodesQueued:[],_updateNodes:function(paths,_processNodes){var pending=Promise.defer();return this._doUpdateNodes(paths,_processNodes,pending),pending.promise},_doUpdateNodes:function(paths,_processNodes,promise){var self=this;return self._updateNodesRunning?void self._updateNodesQueued.push({paths:paths,cb:_processNodes,promise:promise}):(self._updateNodesRunning=!0,void self.getNodes(paths).then(function(nodes){var node,existingNodes=deepClone(nodes),changeEvents=[],equal=RemoteStorage.util.equal;nodes=_processNodes(paths,nodes);for(var path in nodes)node=nodes[path],equal(node,existingNodes[path])?delete nodes[path]:isDocument(path)&&(equal(node.local.body,node.local.previousBody)&&node.local.contentType===node.local.previousContentType||changeEvents.push({path:path,origin:"window",oldValue:node.local.previousBody,newValue:node.local.body===!1?void 0:node.local.body,oldContentType:node.local.previousContentType,newContentType:node.local.contentType}),delete node.local.previousBody,delete node.local.previousContentType);self.setNodes(nodes).then(function(){self._emitChangeEvents(changeEvents),promise.resolve({statusCode:200})})}).then(function(){return Promise.resolve()},function(err){promise.reject(err)}).then(function(){self._updateNodesRunning=!1;var nextJob=self._updateNodesQueued.shift();nextJob&&self._doUpdateNodes(nextJob.paths,nextJob.cb,nextJob.promise)}))},_emitChangeEvents:function(events){for(var i=0,len=events.length;len>i;i++)this._emitChange(events[i]),this.diffHandler&&this.diffHandler(events[i].path)},_getAllDescendentPaths:function(path){var self=this;return isFolder(path)?self.getNodes([path]).then(function(nodes){var allPaths=[path],latest=getLatest(nodes[path]),itemNames=Object.keys(latest.itemsMap),calls=itemNames.map(function(itemName){return self._getAllDescendentPaths(path+itemName).then(function(paths){for(var i=0,len=paths.length;len>i;i++)allPaths.push(paths[i])})});return Promise.all(calls).then(function(){return allPaths})}):Promise.resolve([path])},_getInternals:function(){return{getLatest:getLatest,makeNode:makeNode,isOutdated:isOutdated}}};RemoteStorage.cachingLayer=function(object){for(var key in methods)object[key]=methods[key]}}(),function(global){var DEFAULT_DB,RS=RemoteStorage,DB_VERSION=2,DEFAULT_DB_NAME="remotestorage";RS.IndexedDB=function(database){return this.db=database||DEFAULT_DB,this.db?(RS.cachingLayer(this),RS.eventHandling(this,"change","local-events-done"),this.getsRunning=0,this.putsRunning=0,this.changesQueued={},void(this.changesRunning={})):void RemoteStorage.log("[IndexedDB] Failed to open DB")},RS.IndexedDB.prototype={getNodes:function(paths){for(var misses=[],fromCache={},i=0,len=paths.length;len>i;i++)void 0!==this.changesQueued[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesQueued[paths[i]]||void 0):void 0!==this.changesRunning[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesRunning[paths[i]]||void 0):misses.push(paths[i]);return misses.length>0?this.getNodesFromDb(misses).then(function(nodes){for(var i in fromCache)nodes[i]=fromCache[i];return nodes}):Promise.resolve(fromCache)},setNodes:function(nodes){for(var i in nodes)this.changesQueued[i]=nodes[i]||!1;return this.maybeFlush(),Promise.resolve()},maybeFlush:function(){0===this.putsRunning?this.flushChangesQueued():this.commitSlownessWarning||(this.commitSlownessWarning=setInterval(function(){console.log("WARNING: waited more than 10 seconds for previous commit to finish")},1e4))},flushChangesQueued:function(){this.commitSlownessWarning&&(clearInterval(this.commitSlownessWarning),this.commitSlownessWarning=null),Object.keys(this.changesQueued).length>0&&(this.changesRunning=this.changesQueued,this.changesQueued={},this.setNodesInDb(this.changesRunning).then(this.flushChangesQueued.bind(this)))},getNodesFromDb:function(paths){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),nodes=transaction.objectStore("nodes"),retrievedNodes={};(new Date).getTime();return this.getsRunning++,paths.map(function(path,i){nodes.get(path).onsuccess=function(evt){retrievedNodes[path]=evt.target.result}}),transaction.oncomplete=function(){pending.resolve(retrievedNodes),this.getsRunning--}.bind(this),transaction.onerror=transaction.onabort=function(){pending.reject("get transaction error/abort"),this.getsRunning--}.bind(this),pending.promise},setNodesInDb:function(nodes){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readwrite"),nodesStore=transaction.objectStore("nodes"),startTime=(new Date).getTime(); -this.putsRunning++,RemoteStorage.log("[IndexedDB] Starting put",nodes,this.putsRunning);for(var path in nodes){var node=nodes[path];if("object"==typeof node)try{nodesStore.put(node)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while putting",node,e),e}else try{nodesStore["delete"](path)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while removing",nodesStore,node,e),e}}return transaction.oncomplete=function(){this.putsRunning--,RemoteStorage.log("[IndexedDB] Finished put",nodes,this.putsRunning,(new Date).getTime()-startTime+"ms"),pending.resolve()}.bind(this),transaction.onerror=function(){this.putsRunning--,pending.reject("transaction error")}.bind(this),transaction.onabort=function(){pending.reject("transaction abort"),this.putsRunning--}.bind(this),pending.promise},reset:function(callback){var dbName=this.db.name,self=this;this.db.close(),RS.IndexedDB.clean(this.db.name,function(){RS.IndexedDB.open(dbName,function(err,other){err?RemoteStorage.log("[IndexedDB] Error while resetting local storage",err):self.db=other,"function"==typeof callback&&callback(self)})})},forAllNodes:function(cb){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),cursorReq=transaction.objectStore("nodes").openCursor();return cursorReq.onsuccess=function(evt){var cursor=evt.target.result;cursor?(cb(this.migrate(cursor.value)),cursor["continue"]()):pending.resolve()}.bind(this),pending.promise},closeDB:function(){this.db.close()}},RS.IndexedDB.open=function(name,callback){var timer=setTimeout(function(){callback("timeout trying to open db")},1e4);try{var req=indexedDB.open(name,DB_VERSION);req.onerror=function(){RemoteStorage.log("[IndexedDB] Opening DB failed",req),clearTimeout(timer),callback(req.error)},req.onupgradeneeded=function(event){var db=req.result;RemoteStorage.log("[IndexedDB] Upgrade: from ",event.oldVersion," to ",event.newVersion),1!==event.oldVersion&&(RemoteStorage.log("[IndexedDB] Creating object store: nodes"),db.createObjectStore("nodes",{keyPath:"path"})),RemoteStorage.log("[IndexedDB] Creating object store: changes"),db.createObjectStore("changes",{keyPath:"path"})},req.onsuccess=function(){clearTimeout(timer);var db=req.result;return db.objectStoreNames.contains("nodes")&&db.objectStoreNames.contains("changes")?void callback(null,req.result):(RemoteStorage.log("[IndexedDB] Missing object store. Resetting the database."),void RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)}))}}catch(error){RemoteStorage.log("[IndexedDB] Failed to open database: "+error),RemoteStorage.log("[IndexedDB] Resetting database and trying again."),clearTimeout(timer),RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)})}},RS.IndexedDB.clean=function(databaseName,callback){var req=indexedDB.deleteDatabase(databaseName);req.onsuccess=function(){RemoteStorage.log("[IndexedDB] Done removing DB"),callback()},req.onerror=req.onabort=function(evt){console.error('Failed to remove database "'+databaseName+'"',evt)}},RS.IndexedDB._rs_init=function(remoteStorage){var pending=Promise.defer();return RS.IndexedDB.open(DEFAULT_DB_NAME,function(err,db){err?pending.reject(err):(DEFAULT_DB=db,db.onerror=function(){remoteStorage._emit("error",err)},pending.resolve())}),pending.promise},RS.IndexedDB._rs_supported=function(){var pending=Promise.defer();global.indexedDB=global.indexedDB||global.webkitIndexedDB||global.mozIndexedDB||global.oIndexedDB||global.msIndexedDB;var poorIndexedDbSupport=!1;if("undefined"!=typeof global.navigator&&global.navigator.userAgent.match(/Android (2|3|4\.[0-3])/)&&(navigator.userAgent.match(/Chrome|Firefox/)||(poorIndexedDbSupport=!0)),"indexedDB"in global&&!poorIndexedDbSupport)try{var check=indexedDB.open("rs-check");check.onerror=function(event){pending.reject()},check.onsuccess=function(event){check.result.close(),indexedDB.deleteDatabase("rs-check"),pending.resolve()}}catch(e){pending.reject()}else pending.reject();return pending.promise},RS.IndexedDB._rs_cleanup=function(remoteStorage){var pending=Promise.defer();return remoteStorage.local&&remoteStorage.local.closeDB(),RS.IndexedDB.clean(DEFAULT_DB_NAME,function(){pending.resolve()}),pending.promise}}("undefined"!=typeof window?window:global),function(global){function isRemoteStorageKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX||key.substr(0,CHANGES_PREFIX.length)===CHANGES_PREFIX}function isNodeKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX}var NODES_PREFIX="remotestorage:cache:nodes:",CHANGES_PREFIX="remotestorage:cache:changes:";RemoteStorage.LocalStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[LocalStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done")},RemoteStorage.LocalStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)try{nodes[paths[i]]=JSON.parse(localStorage[NODES_PREFIX+paths[i]])}catch(e){nodes[paths[i]]=void 0}return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)localStorage[NODES_PREFIX+path]=JSON.stringify(nodes[path]);return Promise.resolve()},forAllNodes:function(cb){for(var node,i=0,len=localStorage.length;len>i;i++)if(isNodeKey(localStorage.key(i))){try{node=this.migrate(JSON.parse(localStorage[localStorage.key(i)]))}catch(e){node=void 0}node&&cb(node)}return Promise.resolve()}},RemoteStorage.LocalStorage._rs_init=function(){},RemoteStorage.LocalStorage._rs_supported=function(){return RemoteStorage.util.localStorageAvailable()},RemoteStorage.LocalStorage._rs_cleanup=function(){for(var keys=[],i=0,len=localStorage.length;len>i;i++){var key=localStorage.key(i);isRemoteStorageKey(key)&&keys.push(key)}keys.forEach(function(key){RemoteStorage.log("[LocalStorage] Removing",key),delete localStorage[key]})}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.InMemoryStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[InMemoryStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done"),this._storage={}},RemoteStorage.InMemoryStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)nodes[paths[i]]=this._storage[paths[i]];return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)void 0===nodes[path]?delete this._storage[path]:this._storage[path]=nodes[path];return Promise.resolve()},forAllNodes:function(cb){for(var path in this._storage)cb(this.migrate(this._storage[path]));return Promise.resolve()}},RemoteStorage.InMemoryStorage._rs_init=function(){},RemoteStorage.InMemoryStorage._rs_supported=function(){return!0},RemoteStorage.InMemoryStorage._rs_cleanup=function(){}}("undefined"!=typeof window?window:global),function(){RemoteStorage.MODULES={},RemoteStorage.defineModule=function(moduleName,builder){if(RemoteStorage.MODULES[moduleName]=builder,Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,RS.WireClient.request(method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():xhr})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){rs._emit("error",new RemoteStorage.SyncError(err))})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?global.setTimeout(self._request(method,url,options),3210):Promise.resolve(xhr)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return;rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),promise.reject(err)}).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response); -}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):(200!==resp.status&&404!==resp.status||(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file +},RemoteStorage.Caching.prototype={pendingActivations:[],set:function(path,strategy){if("string"!=typeof path)throw new Error("path should be a string");if(!RemoteStorage.util.isFolder(path))throw new Error("path should be a folder");if(this._remoteStorage&&this._remoteStorage.access&&!this._remoteStorage.access.checkPathPermission(path,"r"))throw new Error('No access to path "'+path+'". You have to claim access to it first.');if(!strategy.match(/^(FLUSH|SEEN|ALL)$/))throw new Error("strategy should be 'FLUSH', 'SEEN', or 'ALL'");this._rootPaths[path]=strategy,"ALL"===strategy&&(this.activateHandler?this.activateHandler(path):this.pendingActivations.push(path))},enable:function(path){this.set(path,"ALL")},disable:function(path){this.set(path,"FLUSH")},onActivate:function(cb){var i;for(RemoteStorage.log("[Caching] Setting activate handler",cb,this.pendingActivations),this.activateHandler=cb,i=0;i1e3&&36e5>interval}var syncInterval=1e4,backgroundSyncInterval=6e4,isBackground=!1,isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,equal=RemoteStorage.util.equal,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=RemoteStorage.util.pathsFromRoot;RemoteStorage.Sync=function(setLocal,setRemote,setAccess,setCaching){this.local=setLocal,this.local.onDiff(function(path){this.addTask(path),this.doTasks()}.bind(this)),this.remote=setRemote,this.access=setAccess,this.caching=setCaching,this._tasks={},this._running={},this._timeStarted={},RemoteStorage.eventHandling(this,"done","req-done"),this.caching.onActivate(function(path){this.addTask(path),this.doTasks()}.bind(this))},RemoteStorage.Sync.prototype={now:function(){return(new Date).getTime()},queueGetRequest:function(path){var pending=Promise.defer();return this.remote.connected?this.remote.online?(this.addTask(path,function(){this.local.get(path).then(function(r){return pending.resolve(r)})}.bind(this)),this.doTasks()):pending.reject("cannot fulfill maxAge requirement - remote is not online"):pending.reject("cannot fulfill maxAge requirement - remote is not connected"),pending.promise},corruptServerItemsMap:function(itemsMap,force02){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap){var item=itemsMap[itemName];if("object"!=typeof item)return!0;if("string"!=typeof item.ETag)return!0;if(isFolder(itemName)){if(-1!==itemName.substring(0,itemName.length-1).indexOf("/"))return!0}else{if(-1!==itemName.indexOf("/"))return!0;if(force02){if("string"!=typeof item["Content-Type"])return!0;if("number"!=typeof item["Content-Length"])return!0}}}return!1},corruptItemsMap:function(itemsMap){if("object"!=typeof itemsMap||Array.isArray(itemsMap))return!0;for(var itemName in itemsMap)if("boolean"!=typeof itemsMap[itemName])return!0;return!1},corruptRevision:function(rev){return"object"!=typeof rev||Array.isArray(rev)||rev.revision&&"string"!=typeof rev.revision||rev.body&&"string"!=typeof rev.body&&"object"!=typeof rev.body||rev.contentType&&"string"!=typeof rev.contentType||rev.contentLength&&"number"!=typeof rev.contentLength||rev.timestamp&&"number"!=typeof rev.timestamp||rev.itemsMap&&this.corruptItemsMap(rev.itemsMap)},isCorrupt:function(node){return"object"!=typeof node||Array.isArray(node)||"string"!=typeof node.path||this.corruptRevision(node.common)||node.local&&this.corruptRevision(node.local)||node.remote&&this.corruptRevision(node.remote)||node.push&&this.corruptRevision(node.push)},hasTasks:function(){return Object.getOwnPropertyNames(this._tasks).length>0},collectDiffTasks:function(){var num=0;return this.local.forAllNodes(function(node){num>100||(this.isCorrupt(node)?(RemoteStorage.log("[Sync] WARNING: corrupt node in local cache",node),"object"==typeof node&&node.path&&(this.addTask(node.path),num++)):this.needsFetch(node)&&this.access.checkPathPermission(node.path,"r")?(this.addTask(node.path),num++):isDocument(node.path)&&this.needsPush(node)&&this.access.checkPathPermission(node.path,"rw")&&(this.addTask(node.path),num++))}.bind(this)).then(function(){return num},function(err){throw err})},inConflict:function(node){return node.local&&node.remote&&(void 0!==node.remote.body||node.remote.itemsMap)},needsRefresh:function(node){return node.common?node.common.timestamp?this.now()-node.common.timestamp>syncInterval:!0:!1},needsFetch:function(node){return this.inConflict(node)?!0:node.common&&void 0===node.common.itemsMap&&void 0===node.common.body?!0:node.remote&&void 0===node.remote.itemsMap&&void 0===node.remote.body?!0:!1},needsPush:function(node){return this.inConflict(node)?!1:node.local&&!node.push?!0:void 0},needsRemotePut:function(node){return node.local&&node.local.body},needsRemoteDelete:function(node){return node.local&&node.local.body===!1},getParentPath:function(path){var parts=path.match(/^(.*\/)([^\/]+\/?)$/);if(parts)return parts[1];throw new Error('Not a valid path: "'+path+'"')},deleteChildPathsFromTasks:function(){for(var path in this._tasks)for(var paths=pathsFromRoot(path),i=1;i=numToAdd)return!0;for(path in this._tasks)if(!this._running[path]&&(this._timeStarted[path]=this.now(),this._running[path]=this.doTask(path),this._running[path].then(this.finishTask.bind(this)),numAdded++,numAdded>=numToAdd))return!0;return numAdded>=numToAdd},collectTasks:function(alsoCheckRefresh){return this.hasTasks()||this.stopped?Promise.resolve():this.collectDiffTasks().then(function(numDiffs){return numDiffs||alsoCheckRefresh===!1?Promise.resolve():this.collectRefreshTasks()}.bind(this),function(err){throw err})},addTask:function(path,cb){this._tasks[path]||(this._tasks[path]=[]),"function"==typeof cb&&this._tasks[path].push(cb)},sync:function(){return this.done=!1,this.doTasks()?Promise.resolve():this.collectTasks().then(function(){try{this.doTasks()}catch(e){console.error("[Sync] doTasks error",e)}}.bind(this),function(e){throw console.error("[Sync] Sync error",e),new Error("Local cache unavailable")})}},RemoteStorage.prototype.getSyncInterval=function(){return syncInterval},RemoteStorage.prototype.setSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=syncInterval;syncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getBackgroundSyncInterval=function(){return backgroundSyncInterval},RemoteStorage.prototype.setBackgroundSyncInterval=function(interval){if(!isValidInterval(interval))throw interval+" is not a valid sync interval";var oldValue=backgroundSyncInterval;backgroundSyncInterval=parseInt(interval,10),this._emit("sync-interval-change",{oldValue:oldValue,newValue:interval})},RemoteStorage.prototype.getCurrentSyncInterval=function(){return isBackground?backgroundSyncInterval:syncInterval};var SyncError=function(originalError){var msg="Sync failed: ";msg+="object"==typeof originalError&&"message"in originalError?originalError.message:originalError,this.originalError=originalError,this.message=msg};SyncError.prototype=new Error,SyncError.prototype.constructor=SyncError,RemoteStorage.SyncError=SyncError,RemoteStorage.prototype.syncCycle=function(){this.sync.stopped||(this.sync.on("done",function(){RemoteStorage.log("[Sync] Sync done. Setting timer to",this.getCurrentSyncInterval()),this.sync.stopped||(this._syncTimer&&clearTimeout(this._syncTimer),this._syncTimer=setTimeout(this.sync.sync.bind(this.sync),this.getCurrentSyncInterval()))}.bind(this)),this.sync.sync())},RemoteStorage.prototype.stopSync=function(){this.sync?(RemoteStorage.log("[Sync] Stopping sync"),this.sync.stopped=!0):(RemoteStorage.log("[Sync] Will instantiate sync stopped"),this.syncStopped=!0)},RemoteStorage.prototype.startSync=function(){this.sync.stopped=!1,this.syncStopped=!1,this.sync.sync()};var syncCycleCb;RemoteStorage.Sync._rs_init=function(remoteStorage){syncCycleCb=function(){RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),RemoteStorage.Env.isBrowser()&&handleVisibility.bind(remoteStorage)(),remoteStorage.sync||(remoteStorage.sync=new RemoteStorage.Sync(remoteStorage.local,remoteStorage.remote,remoteStorage.access,remoteStorage.caching),remoteStorage.syncStopped&&(RemoteStorage.log("[Sync] Instantiating sync stopped"),remoteStorage.sync.stopped=!0,delete remoteStorage.syncStopped)),RemoteStorage.log("[Sync] syncCycleCb calling syncCycle"),remoteStorage.syncCycle()},syncOnConnect=function(){remoteStorage.removeEventListener("connected",syncOnConnect),remoteStorage.startSync()},remoteStorage.on("ready",syncCycleCb),remoteStorage.on("connected",syncOnConnect)},RemoteStorage.Sync._rs_cleanup=function(remoteStorage){remoteStorage.stopSync(),remoteStorage.removeEventListener("ready",syncCycleCb),remoteStorage.removeEventListener("connected",syncOnConnect),delete remoteStorage.sync}}("undefined"!=typeof window?window:global),function(){function getLatest(node){if("object"==typeof node&&"string"==typeof node.path)if(isFolder(node.path)){if(node.local&&node.local.itemsMap)return node.local;if(node.common&&node.common.itemsMap)return node.common}else{if(node.local&&node.local.body&&node.local.contentType)return node.local;if(node.common&&node.common.body&&node.common.contentType)return node.common;if(node.body&&node.contentType)return{body:node.body,contentType:node.contentType}}}function isOutdated(nodes,maxAge){var path;for(path in nodes){if(nodes[path]&&nodes[path].remote)return!0;var nodeVersion=getLatest(nodes[path]);if(nodeVersion&&nodeVersion.timestamp&&(new Date).getTime()-nodeVersion.timestamp<=maxAge)return!1;if(!nodeVersion)return!0}return!0}function makeNode(path){var node={path:path,common:{}};return isFolder(path)&&(node.common.itemsMap={}),node}function updateFolderNodeWithItemName(node,itemName){return node.common||(node.common={itemsMap:{}}),node.common.itemsMap||(node.common.itemsMap={}),node.local||(node.local=deepClone(node.common)),node.local.itemsMap||(node.local.itemsMap=node.common.itemsMap),node.local.itemsMap[itemName]=!0,node}var isFolder=RemoteStorage.util.isFolder,isDocument=RemoteStorage.util.isDocument,deepClone=RemoteStorage.util.deepClone,pathsFromRoot=(RemoteStorage.util.equal,RemoteStorage.util.pathsFromRoot),methods={get:function(path,maxAge,queueGetRequest){var self=this;return"number"==typeof maxAge?self.getNodes(pathsFromRoot(path)).then(function(objs){var node=getLatest(objs[path]);return isOutdated(objs,maxAge)?queueGetRequest(path):node?{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}:{statusCode:404}}):self.getNodes([path]).then(function(objs){var node=getLatest(objs[path]);if(node){if(isFolder(path))for(var i in node.itemsMap)node.itemsMap.hasOwnProperty(i)&&node.itemsMap[i]===!1&&delete node.itemsMap[i];return{statusCode:200,body:node.body||node.itemsMap,contentType:node.contentType}}return{statusCode:404}})},put:function(path,body,contentType){function _processNodes(paths,nodes){try{for(var i=0,len=paths.length;len>i;i++){var previous,path=paths[i],node=nodes[path];if(node||(nodes[path]=node=makeNode(path)),0===i)previous=getLatest(node),node.local={body:body,contentType:contentType,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{var itemName=paths[i-1].substring(path.length);node=updateFolderNodeWithItemName(node,itemName)}}return nodes}catch(e){throw RemoteStorage.log("[Cachinglayer] Error during PUT",nodes,i,e),e}}var paths=pathsFromRoot(path);return this._updateNodes(paths,_processNodes)},"delete":function(path){var paths=pathsFromRoot(path);return this._updateNodes(paths,function(paths,nodes){for(var i=0,len=paths.length;len>i;i++){var path=paths[i],node=nodes[path];if(!node)throw new Error("Cannot delete non-existing node "+path);if(0===i)previous=getLatest(node),node.local={body:!1,previousBody:previous?previous.body:void 0,previousContentType:previous?previous.contentType:void 0};else{node.local||(node.local=deepClone(node.common));var itemName=paths[i-1].substring(path.length);if(delete node.local.itemsMap[itemName],Object.getOwnPropertyNames(node.local.itemsMap).length>0)break}}return nodes})},flush:function(path){var self=this;return self._getAllDescendentPaths(path).then(function(paths){return self.getNodes(paths)}).then(function(nodes){for(var path in nodes){var node=nodes[path];node&&node.common&&node.local&&self._emitChange({path:node.path,origin:"local",oldValue:node.local.body===!1?void 0:node.local.body,newValue:node.common.body===!1?void 0:node.common.body}),nodes[path]=void 0}return self.setNodes(nodes)})},_emitChange:function(obj){RemoteStorage.config.changeEvents[obj.origin]&&this._emit("change",obj)},fireInitial:function(){if(RemoteStorage.config.changeEvents.local){var self=this;self.forAllNodes(function(node){var latest;isDocument(node.path)&&(latest=getLatest(node),latest&&self._emitChange({path:node.path,origin:"local",oldValue:void 0,oldContentType:void 0,newValue:latest.body,newContentType:latest.contentType}))}).then(function(){self._emit("local-events-done")})}},onDiff:function(diffHandler){this.diffHandler=diffHandler},migrate:function(node){return"object"!=typeof node||node.common||(node.common={},"string"==typeof node.path?"/"===node.path.substr(-1)&&"object"==typeof node.body&&(node.common.itemsMap=node.body):(node.local||(node.local={}),node.local.body=node.body,node.local.contentType=node.contentType)),node},_updateNodesRunning:!1,_updateNodesQueued:[],_updateNodes:function(paths,_processNodes){var pending=Promise.defer();return this._doUpdateNodes(paths,_processNodes,pending),pending.promise},_doUpdateNodes:function(paths,_processNodes,promise){var self=this;return self._updateNodesRunning?void self._updateNodesQueued.push({paths:paths,cb:_processNodes,promise:promise}):(self._updateNodesRunning=!0,void self.getNodes(paths).then(function(nodes){var node,existingNodes=deepClone(nodes),changeEvents=[],equal=RemoteStorage.util.equal;nodes=_processNodes(paths,nodes);for(var path in nodes)node=nodes[path],equal(node,existingNodes[path])?delete nodes[path]:isDocument(path)&&(equal(node.local.body,node.local.previousBody)&&node.local.contentType===node.local.previousContentType||changeEvents.push({path:path,origin:"window",oldValue:node.local.previousBody,newValue:node.local.body===!1?void 0:node.local.body,oldContentType:node.local.previousContentType,newContentType:node.local.contentType}),delete node.local.previousBody,delete node.local.previousContentType);self.setNodes(nodes).then(function(){self._emitChangeEvents(changeEvents),promise.resolve({statusCode:200})})}).then(function(){return Promise.resolve()},function(err){promise.reject(err)}).then(function(){self._updateNodesRunning=!1;var nextJob=self._updateNodesQueued.shift();nextJob&&self._doUpdateNodes(nextJob.paths,nextJob.cb,nextJob.promise)}))},_emitChangeEvents:function(events){for(var i=0,len=events.length;len>i;i++)this._emitChange(events[i]),this.diffHandler&&this.diffHandler(events[i].path)},_getAllDescendentPaths:function(path){var self=this;return isFolder(path)?self.getNodes([path]).then(function(nodes){var allPaths=[path],latest=getLatest(nodes[path]),itemNames=Object.keys(latest.itemsMap),calls=itemNames.map(function(itemName){return self._getAllDescendentPaths(path+itemName).then(function(paths){for(var i=0,len=paths.length;len>i;i++)allPaths.push(paths[i])})});return Promise.all(calls).then(function(){return allPaths})}):Promise.resolve([path])},_getInternals:function(){return{getLatest:getLatest,makeNode:makeNode,isOutdated:isOutdated}}};RemoteStorage.cachingLayer=function(object){for(var key in methods)object[key]=methods[key]}}(),function(global){var DEFAULT_DB,RS=RemoteStorage,DB_VERSION=2,DEFAULT_DB_NAME="remotestorage";RS.IndexedDB=function(database){return this.db=database||DEFAULT_DB,this.db?(RS.cachingLayer(this),RS.eventHandling(this,"change","local-events-done"),this.getsRunning=0,this.putsRunning=0,this.changesQueued={},void(this.changesRunning={})):void RemoteStorage.log("[IndexedDB] Failed to open DB")},RS.IndexedDB.prototype={getNodes:function(paths){for(var misses=[],fromCache={},i=0,len=paths.length;len>i;i++)void 0!==this.changesQueued[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesQueued[paths[i]]||void 0):void 0!==this.changesRunning[paths[i]]?fromCache[paths[i]]=RemoteStorage.util.deepClone(this.changesRunning[paths[i]]||void 0):misses.push(paths[i]);return misses.length>0?this.getNodesFromDb(misses).then(function(nodes){for(var i in fromCache)nodes[i]=fromCache[i];return nodes}):Promise.resolve(fromCache)},setNodes:function(nodes){for(var i in nodes)this.changesQueued[i]=nodes[i]||!1;return this.maybeFlush(),Promise.resolve()},maybeFlush:function(){0===this.putsRunning?this.flushChangesQueued():this.commitSlownessWarning||(this.commitSlownessWarning=setInterval(function(){console.log("WARNING: waited more than 10 seconds for previous commit to finish")},1e4))},flushChangesQueued:function(){this.commitSlownessWarning&&(clearInterval(this.commitSlownessWarning),this.commitSlownessWarning=null),Object.keys(this.changesQueued).length>0&&(this.changesRunning=this.changesQueued,this.changesQueued={},this.setNodesInDb(this.changesRunning).then(this.flushChangesQueued.bind(this)))},getNodesFromDb:function(paths){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),nodes=transaction.objectStore("nodes"),retrievedNodes={};(new Date).getTime();return this.getsRunning++,paths.map(function(path,i){nodes.get(path).onsuccess=function(evt){retrievedNodes[path]=evt.target.result}}),transaction.oncomplete=function(){pending.resolve(retrievedNodes),this.getsRunning--}.bind(this),transaction.onerror=transaction.onabort=function(){pending.reject("get transaction error/abort"),this.getsRunning--}.bind(this),pending.promise},setNodesInDb:function(nodes){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readwrite"),nodesStore=transaction.objectStore("nodes"),startTime=(new Date).getTime(); +this.putsRunning++,RemoteStorage.log("[IndexedDB] Starting put",nodes,this.putsRunning);for(var path in nodes){var node=nodes[path];if("object"==typeof node)try{nodesStore.put(node)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while putting",node,e),e}else try{nodesStore["delete"](path)}catch(e){throw RemoteStorage.log("[IndexedDB] Error while removing",nodesStore,node,e),e}}return transaction.oncomplete=function(){this.putsRunning--,RemoteStorage.log("[IndexedDB] Finished put",nodes,this.putsRunning,(new Date).getTime()-startTime+"ms"),pending.resolve()}.bind(this),transaction.onerror=function(){this.putsRunning--,pending.reject("transaction error")}.bind(this),transaction.onabort=function(){pending.reject("transaction abort"),this.putsRunning--}.bind(this),pending.promise},reset:function(callback){var dbName=this.db.name,self=this;this.db.close(),RS.IndexedDB.clean(this.db.name,function(){RS.IndexedDB.open(dbName,function(err,other){err?RemoteStorage.log("[IndexedDB] Error while resetting local storage",err):self.db=other,"function"==typeof callback&&callback(self)})})},forAllNodes:function(cb){var pending=Promise.defer(),transaction=this.db.transaction(["nodes"],"readonly"),cursorReq=transaction.objectStore("nodes").openCursor();return cursorReq.onsuccess=function(evt){var cursor=evt.target.result;cursor?(cb(this.migrate(cursor.value)),cursor["continue"]()):pending.resolve()}.bind(this),pending.promise},closeDB:function(){this.db.close()}},RS.IndexedDB.open=function(name,callback){var timer=setTimeout(function(){callback("timeout trying to open db")},1e4);try{var req=indexedDB.open(name,DB_VERSION);req.onerror=function(){RemoteStorage.log("[IndexedDB] Opening DB failed",req),clearTimeout(timer),callback(req.error)},req.onupgradeneeded=function(event){var db=req.result;RemoteStorage.log("[IndexedDB] Upgrade: from ",event.oldVersion," to ",event.newVersion),1!==event.oldVersion&&(RemoteStorage.log("[IndexedDB] Creating object store: nodes"),db.createObjectStore("nodes",{keyPath:"path"})),RemoteStorage.log("[IndexedDB] Creating object store: changes"),db.createObjectStore("changes",{keyPath:"path"})},req.onsuccess=function(){clearTimeout(timer);var db=req.result;return db.objectStoreNames.contains("nodes")&&db.objectStoreNames.contains("changes")?void callback(null,req.result):(RemoteStorage.log("[IndexedDB] Missing object store. Resetting the database."),void RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)}))}}catch(error){RemoteStorage.log("[IndexedDB] Failed to open database: "+error),RemoteStorage.log("[IndexedDB] Resetting database and trying again."),clearTimeout(timer),RS.IndexedDB.clean(name,function(){RS.IndexedDB.open(name,callback)})}},RS.IndexedDB.clean=function(databaseName,callback){var req=indexedDB.deleteDatabase(databaseName);req.onsuccess=function(){RemoteStorage.log("[IndexedDB] Done removing DB"),callback()},req.onerror=req.onabort=function(evt){console.error('Failed to remove database "'+databaseName+'"',evt)}},RS.IndexedDB._rs_init=function(remoteStorage){var pending=Promise.defer();return RS.IndexedDB.open(DEFAULT_DB_NAME,function(err,db){err?pending.reject(err):(DEFAULT_DB=db,db.onerror=function(){remoteStorage._emit("error",err)},pending.resolve())}),pending.promise},RS.IndexedDB._rs_supported=function(){var pending=Promise.defer();global.indexedDB=global.indexedDB||global.webkitIndexedDB||global.mozIndexedDB||global.oIndexedDB||global.msIndexedDB;var poorIndexedDbSupport=!1;if("undefined"!=typeof global.navigator&&global.navigator.userAgent.match(/Android (2|3|4\.[0-3])/)&&(navigator.userAgent.match(/Chrome|Firefox/)||(poorIndexedDbSupport=!0)),"indexedDB"in global&&!poorIndexedDbSupport)try{var check=indexedDB.open("rs-check");check.onerror=function(event){pending.reject()},check.onsuccess=function(event){check.result.close(),indexedDB.deleteDatabase("rs-check"),pending.resolve()}}catch(e){pending.reject()}else pending.reject();return pending.promise},RS.IndexedDB._rs_cleanup=function(remoteStorage){var pending=Promise.defer();return remoteStorage.local&&remoteStorage.local.closeDB(),RS.IndexedDB.clean(DEFAULT_DB_NAME,function(){pending.resolve()}),pending.promise}}("undefined"!=typeof window?window:global),function(global){function isRemoteStorageKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX||key.substr(0,CHANGES_PREFIX.length)===CHANGES_PREFIX}function isNodeKey(key){return key.substr(0,NODES_PREFIX.length)===NODES_PREFIX}var NODES_PREFIX="remotestorage:cache:nodes:",CHANGES_PREFIX="remotestorage:cache:changes:";RemoteStorage.LocalStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[LocalStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done")},RemoteStorage.LocalStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)try{nodes[paths[i]]=JSON.parse(localStorage[NODES_PREFIX+paths[i]])}catch(e){nodes[paths[i]]=void 0}return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)localStorage[NODES_PREFIX+path]=JSON.stringify(nodes[path]);return Promise.resolve()},forAllNodes:function(cb){for(var node,i=0,len=localStorage.length;len>i;i++)if(isNodeKey(localStorage.key(i))){try{node=this.migrate(JSON.parse(localStorage[localStorage.key(i)]))}catch(e){node=void 0}node&&cb(node)}return Promise.resolve()}},RemoteStorage.LocalStorage._rs_init=function(){},RemoteStorage.LocalStorage._rs_supported=function(){return RemoteStorage.util.localStorageAvailable()},RemoteStorage.LocalStorage._rs_cleanup=function(){for(var keys=[],i=0,len=localStorage.length;len>i;i++){var key=localStorage.key(i);isRemoteStorageKey(key)&&keys.push(key)}keys.forEach(function(key){RemoteStorage.log("[LocalStorage] Removing",key),delete localStorage[key]})}}("undefined"!=typeof window?window:global),function(global){RemoteStorage.InMemoryStorage=function(){RemoteStorage.cachingLayer(this),RemoteStorage.log("[InMemoryStorage] Registering events"),RemoteStorage.eventHandling(this,"change","local-events-done"),this._storage={}},RemoteStorage.InMemoryStorage.prototype={getNodes:function(paths){for(var nodes={},i=0,len=paths.length;len>i;i++)nodes[paths[i]]=this._storage[paths[i]];return Promise.resolve(nodes)},setNodes:function(nodes){for(var path in nodes)void 0===nodes[path]?delete this._storage[path]:this._storage[path]=nodes[path];return Promise.resolve()},forAllNodes:function(cb){for(var path in this._storage)cb(this.migrate(this._storage[path]));return Promise.resolve()}},RemoteStorage.InMemoryStorage._rs_init=function(){},RemoteStorage.InMemoryStorage._rs_supported=function(){return!0},RemoteStorage.InMemoryStorage._rs_cleanup=function(){}}("undefined"!=typeof window?window:global),function(){RemoteStorage.MODULES={},RemoteStorage.defineModule=function(moduleName,builder){if(RemoteStorage.MODULES[moduleName]=builder,Object.defineProperty(RemoteStorage.prototype,moduleName,{configurable:!0,get:function(){var instance=this._loadModule(moduleName);return Object.defineProperty(this,moduleName,{value:instance}),instance}}),-1!==moduleName.indexOf("-")){var camelizedName=moduleName.replace(/\-[a-z]/g,function(s){return s[1].toUpperCase()});Object.defineProperty(RemoteStorage.prototype,camelizedName,{get:function(){return this[moduleName]}})}},RemoteStorage.prototype._loadModule=function(moduleName){var builder=RemoteStorage.MODULES[moduleName];if(builder){var module=builder(new RemoteStorage.BaseClient(this,"/"+moduleName+"/"),new RemoteStorage.BaseClient(this,"/public/"+moduleName+"/"));return module.exports}throw"Unknown module: "+moduleName},RemoteStorage.prototype.defineModule=function(moduleName){console.log("remoteStorage.defineModule is deprecated, use RemoteStorage.defineModule instead!"),RemoteStorage.defineModule.apply(RemoteStorage,arguments)}}(),function(){function loadTable(table,storage,paths){function renderRow(tr,path,contentType,revision){[path,contentType,revision].forEach(function(value){var td=document.createElement("td");td.textContent=value||"",tr.appendChild(td)})}function loadRow(path){function processRow(status,body,contentType,revision){if(200===status){var tr=document.createElement("tr");if(tbody.appendChild(tr),renderRow(tr,path,contentType,revision),"/"===path[path.length-1])for(var key in body)loadRow(path+key)}}storage.connected!==!1&&storage.get(path).then(processRow)}table.setAttribute("border","1"),table.style.margin="8px",table.style.color="white",table.innerHTML="";var thead=document.createElement("thead");table.appendChild(thead);var titleRow=document.createElement("tr");thead.appendChild(titleRow),["Path","Content-Type","Revision"].forEach(function(label){var th=document.createElement("th");th.textContent=label,thead.appendChild(th)});var tbody=document.createElement("tbody");table.appendChild(tbody),paths.forEach(loadRow)}function renderWrapper(title,table,storage,paths){var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent=title,wrapper.appendChild(heading);var updateButton=document.createElement("button");if(updateButton.textContent="Refresh",updateButton.onclick=function(){loadTable(table,storage,paths)},wrapper.appendChild(updateButton),storage.reset){var resetButton=document.createElement("button");resetButton.textContent="Reset",resetButton.onclick=function(){storage.reset(function(newStorage){storage=newStorage,loadTable(table,storage,paths)})},wrapper.appendChild(resetButton)}return wrapper.appendChild(table),loadTable(table,storage,paths),wrapper}function renderLocalChanges(local){function updateList(){list.innerHTML="",local.forAllNodes(function(node){if(node.local&&node.local.body){var el=document.createElement("li");el.textContent=JSON.stringify(node.local),list.appendChild(el)}})}var wrapper=document.createElement("div"),heading=document.createElement("h2");heading.textContent="Outgoing changes",wrapper.appendChild(heading);var updateButton=document.createElement("button");updateButton.textContent="Refresh",wrapper.appendChild(updateButton);var list=document.createElement("ul");return list.style.fontFamily="courier",wrapper.appendChild(list),updateButton.onclick=updateList,updateList(),wrapper}RemoteStorage.prototype.inspect=function(){var widget=document.createElement("div");widget.id="remotestorage-inspect",widget.style.position="absolute",widget.style.top=0,widget.style.left=0,widget.style.background="black",widget.style.color="white",widget.style.border="groove 5px #ccc";var controls=document.createElement("div");controls.style.position="absolute",controls.style.top=0,controls.style.left=0;var heading=document.createElement("strong");heading.textContent=" remotestorage.js inspector ",controls.appendChild(heading);var syncButton;this.local&&(syncButton=document.createElement("button"),syncButton.textContent="Synchronize",controls.appendChild(syncButton));var closeButton=document.createElement("button");closeButton.textContent="Close",closeButton.onclick=function(){document.body.removeChild(widget)},controls.appendChild(closeButton),widget.appendChild(controls);var remoteRootPaths=[];for(var path in this.caching._rootPaths)this.caching._rootPaths.hasOwnProperty(path)&&remoteRootPaths.push(path);var remoteTable=document.createElement("table"),localTable=document.createElement("table");widget.appendChild(renderWrapper("Remote",remoteTable,this.remote,remoteRootPaths)),this.local&&(widget.appendChild(renderWrapper("Local",localTable,this.local,["/"])),widget.appendChild(renderLocalChanges(this.local)),syncButton.onclick=function(){this.log("sync clicked"),this.sync.sync().then(function(){this.log("SYNC FINISHED"),loadTable(localTable,this.local,["/"])}.bind(this),function(err){console.error("SYNC FAILED",err,err.stack)})}.bind(this)),document.body.appendChild(widget)}}(),function(global){function metaTitleFromFileName(filename){return"/"===filename.substr(-1)&&(filename=filename.substr(0,filename.length-1)),decodeURIComponent(filename)}function parentPath(path){return path.replace(/[^\/]+\/?$/,"")}function baseName(path){var parts=path.split("/");return"/"===path.substr(-1)?parts[parts.length-2]+"/":parts[parts.length-1]}var RS=RemoteStorage,BASE_URL="https://www.googleapis.com",AUTH_URL="https://accounts.google.com/o/oauth2/auth",AUTH_SCOPE="https://www.googleapis.com/auth/drive",GD_DIR_MIME_TYPE="application/vnd.google-apps.folder",RS_DIR_MIME_TYPE="application/json; charset=UTF-8",isFolder=RemoteStorage.util.isFolder,Cache=function(maxAge){this.maxAge=maxAge,this._items={}};Cache.prototype={get:function(key){var item=this._items[key],now=(new Date).getTime();return item&&item.t>=now-this.maxAge?item.v:void 0},set:function(key,value){this._items[key]={v:value,t:(new Date).getTime()}}},RS.GoogleDrive=function(remoteStorage,clientId){RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),this.rs=remoteStorage,this.clientId=clientId,this._fileIdCache=new Cache(300)},RS.GoogleDrive.prototype={connected:!1,online:!0,configure:function(settings){settings.token?(localStorage["remotestorage:googledrive:token"]=settings.token,this.token=settings.token,this.connected=!0,this._emit("connected")):(this.connected=!1,delete this.token,delete localStorage["remotestorage:googledrive:token"])},connect:function(){this.rs.setBackend("googledrive"),RS.Authorize(this.rs,AUTH_URL,AUTH_SCOPE,String(RS.Authorize.getLocation()),this.clientId)},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},get:function(path,options){return"/"===path.substr(-1)?this._getFolder(path,options):this._getFile(path,options)},put:function(path,body,contentType,options){function putDone(response){if(response.status>=200&&response.status<300){var meta=JSON.parse(response.responseText),etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1);return Promise.resolve({statusCode:200,contentType:meta.mimeType,revision:etagWithoutQuotes})}return 412===response.status?Promise.resolve({statusCode:412,revision:"conflict"}):Promise.reject("PUT failed with status "+response.status+" ("+response.responseText+")")}var self=this;return self._getFileId(path).then(function(id){return id?options&&"*"===options.ifNoneMatch?putDone({status:412}):self._updateFile(id,path,body,contentType,options).then(putDone):self._createFile(path,body,contentType,options).then(putDone)})},"delete":function(path,options){var self=this;return self._getFileId(path).then(function(id){return id?self._getMeta(id).then(function(meta){var etagWithoutQuotes;return"object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifMatch&&options.ifMatch!==etagWithoutQuotes?{statusCode:412,revision:etagWithoutQuotes}:self._request("DELETE",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status||204===response.status?{statusCode:200}:Promise.reject("Delete failed: "+response.status+" ("+response.responseText+")")})}):Promise.resolve({statusCode:200})})},_updateFile:function(id,path,body,contentType,options){var self=this,metadata={mimeType:contentType},headers={"Content-Type":"application/json; charset=UTF-8"};return options&&options.ifMatch&&(headers["If-Match"]='"'+options.ifMatch+'"'),self._request("PUT",BASE_URL+"/upload/drive/v2/files/"+id+"?uploadType=resumable",{body:JSON.stringify(metadata),headers:headers}).then(function(response){return 412===response.status?response:self._request("PUT",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})},_createFile:function(path,body,contentType,options){var self=this;return self._getParentId(path).then(function(parentId){var fileName=baseName(path),metadata={title:metaTitleFromFileName(fileName),mimeType:contentType,parents:[{kind:"drive#fileLink",id:parentId}]};return self._request("POST",BASE_URL+"/upload/drive/v2/files?uploadType=resumable",{body:JSON.stringify(metadata),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){return self._request("POST",response.getResponseHeader("Location"),{body:contentType.match(/^application\/json/)?JSON.stringify(body):body})})})},_getFile:function(path,options){var self=this;return self._getFileId(path).then(function(id){return self._getMeta(id).then(function(meta){var etagWithoutQuotes;if("object"==typeof meta&&"string"==typeof meta.etag&&(etagWithoutQuotes=meta.etag.substring(1,meta.etag.length-1)),options&&options.ifNoneMatch&&etagWithoutQuotes===options.ifNoneMatch)return Promise.resolve({statusCode:304});var options2={};if(!meta.downloadUrl){if(!meta.exportLinks||!meta.exportLinks["text/html"])return Promise.resolve({statusCode:200,body:"",contentType:meta.mimeType,revision:etagWithoutQuotes});meta.mimeType+=";export=text/html",meta.downloadUrl=meta.exportLinks["text/html"]}return meta.mimeType.match(/charset=binary/)&&(options2.responseType="blob"),self._request("GET",meta.downloadUrl,options2).then(function(response){var body=response.response;if(meta.mimeType.match(/^application\/json/))try{body=JSON.parse(body)}catch(e){}return Promise.resolve({statusCode:200,body:body,contentType:meta.mimeType,revision:etagWithoutQuotes})})})})},_getFolder:function(path,options){var self=this;return self._getFileId(path).then(function(id){var query,fields,data,etagWithoutQuotes,itemsMap;return id?(query="'"+id+"' in parents",fields="items(downloadUrl,etag,fileSize,id,mimeType,title)",self._request("GET",BASE_URL+"/drive/v2/files?q="+encodeURIComponent(query)+"&fields="+encodeURIComponent(fields)+"&maxResults=1000",{}).then(function(response){if(200!==response.status)return Promise.reject("request failed or something: "+response.status);try{data=JSON.parse(response.responseText)}catch(e){return Promise.reject("non-JSON response from GoogleDrive")}itemsMap={};for(var i=0,len=data.items.length;len>i;i++)etagWithoutQuotes=data.items[i].etag.substring(1,data.items[i].etag.length-1),data.items[i].mimeType===GD_DIR_MIME_TYPE?(self._fileIdCache.set(path+data.items[i].title+"/",data.items[i].id),itemsMap[data.items[i].title+"/"]={ETag:etagWithoutQuotes}):(self._fileIdCache.set(path+data.items[i].title,data.items[i].id),itemsMap[data.items[i].title]={ETag:etagWithoutQuotes,"Content-Type":data.items[i].mimeType,"Content-Length":data.items[i].fileSize});return Promise.resolve({statusCode:200,body:itemsMap,contentType:RS_DIR_MIME_TYPE,revision:void 0})})):Promise.resolve({statusCode:404})})},_getParentId:function(path){var foldername=parentPath(path),self=this;return self._getFileId(foldername).then(function(parentId){return parentId?Promise.resolve(parentId):self._createFolder(foldername)})},_createFolder:function(path){var self=this;return self._getParentId(path).then(function(parentId){return self._request("POST",BASE_URL+"/drive/v2/files",{body:JSON.stringify({title:metaTitleFromFileName(baseName(path)),mimeType:GD_DIR_MIME_TYPE,parents:[{id:parentId}]}),headers:{"Content-Type":"application/json; charset=UTF-8"}}).then(function(response){var meta=JSON.parse(response.responseText);return Promise.resolve(meta.id)})})},_getFileId:function(path){var id,self=this;return"/"===path?Promise.resolve("root"):(id=this._fileIdCache.get(path))?Promise.resolve(id):self._getFolder(parentPath(path)).then(function(){return id=self._fileIdCache.get(path),id?Promise.resolve(id):"/"===path.substr(-1)?self._createFolder(path).then(function(){return self._getFileId(path)}):Promise.resolve()})},_getMeta:function(id){return this._request("GET",BASE_URL+"/drive/v2/files/"+id,{}).then(function(response){return 200===response.status?Promise.resolve(JSON.parse(response.responseText)):Promise.reject("request (getting metadata for "+id+") failed with status: "+response.status)})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+self.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&401===xhr.status?void self.connect():(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})}},RS.GoogleDrive._rs_init=function(remoteStorage){var config=remoteStorage.apiKeys.googledrive;config&&(remoteStorage.googledrive=new RS.GoogleDrive(remoteStorage,config.clientId),"googledrive"===remoteStorage.backend&&(remoteStorage._origRemote=remoteStorage.remote,remoteStorage.remote=remoteStorage.googledrive))},RS.GoogleDrive._rs_supported=function(rs){return!0},RS.GoogleDrive._rs_cleanup=function(remoteStorage){remoteStorage.setBackend(void 0),remoteStorage._origRemote&&(remoteStorage.remote=remoteStorage._origRemote,delete remoteStorage._origRemote)}}(this),function(global){function LowerCaseCache(defaultValue){this.defaultValue=defaultValue,this._storage={},this.set=this.justSet,this["delete"]=this.justDelete}function hookSync(rs){rs._dropboxOrigSync||(rs._dropboxOrigSync=rs.sync.sync.bind(rs.sync),rs.sync.sync=function(){return this.dropbox.fetchDelta.apply(this.dropbox,arguments).then(rs._dropboxOrigSync,function(err){return rs._emit("error",new RemoteStorage.SyncError(err)),Promise.reject(err)})}.bind(rs))}function unHookSync(rs){rs._dropboxOrigSync&&(rs.sync.sync=rs._dropboxOrigSync,delete rs._dropboxOrigSync)}function hookGetItemURL(rs){rs._origBaseClientGetItemURL||(rs._origBaseClientGetItemURL=RS.BaseClient.prototype.getItemURL,RS.BaseClient.prototype.getItemURL=function(path){var ret=rs.dropbox._itemRefs[path];return ret?ret:""})}function unHookGetItemURL(rs){rs._origBaseClientGetItemURL&&(RS.BaseClient.prototype.getItemURL=rs._origBaseClientGetItemURL,delete rs._origBaseClientGetItemURL)}function hookRemote(rs){rs._origRemote||(rs._origRemote=rs.remote,rs.remote=rs.dropbox)}function unHookRemote(rs){rs._origRemote&&(rs.remote=rs._origRemote,delete rs._origRemote)}function hookIt(rs){hookRemote(rs),rs.sync?hookSync(rs):rs.on("connected",function(){rs.sync&&hookSync(rs)}),hookGetItemURL(rs)}function unHookIt(rs){unHookRemote(rs),unHookSync(rs),unHookGetItemURL(rs)}var hasLocalStorage,RS=RemoteStorage,AUTH_URL="https://www.dropbox.com/1/oauth2/authorize",SETTINGS_KEY="remotestorage:dropbox",PATH_PREFIX="/remotestorage",isFolder=RemoteStorage.util.isFolder,getDropboxPath=function(path){return RS.WireClient.cleanPath(PATH_PREFIX+"/"+path)},encodeQuery=function(obj){var pairs=[];for(var key in obj)obj.hasOwnProperty(key)&&pairs.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));return pairs.join("&")};LowerCaseCache.prototype={get:function(key){key=key.toLowerCase();var stored=this._storage[key];return"undefined"==typeof stored&&(stored=this.defaultValue,this._storage[key]=stored),stored},propagateSet:function(key,value){return key=key.toLowerCase(),this._storage[key]===value?value:(this._propagate(key,value),this._storage[key]=value,value)},propagateDelete:function(key){return key=key.toLowerCase(),this._propagate(key,this._storage[key]),delete this._storage[key]},_activatePropagation:function(){return this.set=this.propagateSet,this["delete"]=this.propagateDelete,!0},justSet:function(key,value){return key=key.toLowerCase(),this._storage[key]=value,value},justDelete:function(key,value){return key=key.toLowerCase(),delete this._storage[key]},_propagate:function(key,rev){for(var folders=key.split("/").slice(0,-1),path="",i=0,len=folders.length;len>i;i++)path+=folders[i]+"/",rev||(rev=this._storage[path]+1),this._storage[path]=rev}};var onErrorCb;RS.Dropbox=function(rs){this.rs=rs,this.connected=!1,this.rs=rs;var self=this;if(onErrorCb=function(error){error instanceof RemoteStorage.Unauthorized&&self.configure({userAddress:null,href:null,storageApi:null,token:null,options:null})},RS.eventHandling(this,"change","connected","wire-busy","wire-done","not-connected"),rs.on("error",onErrorCb),this.clientId=rs.apiKeys.dropbox.appKey,this._revCache=new LowerCaseCache("rev"),this._itemRefs={},this._metadataCache={},hasLocalStorage){var settings;try{settings=JSON.parse(localStorage[SETTINGS_KEY])}catch(e){}settings&&this.configure(settings);try{this._itemRefs=JSON.parse(localStorage[SETTINGS_KEY+":shares"])}catch(e){}}this.connected&&setTimeout(this._emit.bind(this),0,"connected")},RS.Dropbox.prototype={online:!0,connect:function(){this.rs.setBackend("dropbox"),this.token?hookIt(this.rs):RS.Authorize(this.rs,AUTH_URL,"",String(RS.Authorize.getLocation()),this.clientId)},configure:function(settings){"undefined"!=typeof settings.userAddress&&(this.userAddress=settings.userAddress),"undefined"!=typeof settings.token&&(this.token=settings.token),this.token?(this.connected=!0,this.userAddress||this.info().then(function(info){this.userAddress=info.display_name,this.rs.widget.view.setUserAddress(this.userAddress),this._emit("connected")}.bind(this))):this.connected=!1,hasLocalStorage&&(localStorage[SETTINGS_KEY]=JSON.stringify({userAddress:this.userAddress,token:this.token}))},stopWaitingForToken:function(){this.connected||this._emit("not-connected")},_getFolder:function(path,options){var url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path),revCache=this._revCache,self=this;return this._request("GET",url,{}).then(function(resp){var status=resp.status;if(304===status)return Promise.resolve({statusCode:status});var listing,body,mime,rev;try{body=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}return rev=self._revCache.get(path),mime="application/json; charset=UTF-8",body.contents&&(listing=body.contents.reduce(function(m,item){var itemName=item.path.split("/").slice(-1)[0]+(item.is_dir?"/":"");return item.is_dir?m[itemName]={ETag:revCache.get(path+itemName)}:m[itemName]={ETag:item.rev},m},{})),Promise.resolve({statusCode:status,body:listing,contentType:mime,revision:rev})})},get:function(path,options){if(!this.connected)return Promise.reject("not connected (path: "+path+")");var url="https://api-content.dropbox.com/1/files/auto"+getDropboxPath(path),self=this,savedRev=this._revCache.get(path);return null===savedRev?Promise.resolve({statusCode:404}):options&&options.ifNoneMatch&&savedRev&&savedRev===options.ifNoneMatch?Promise.resolve({statusCode:304}):"/"===path.substr(-1)?this._getFolder(path,options):this._request("GET",url,{}).then(function(resp){var meta,body,mime,rev,status=resp.status;if(200!==status)return Promise.resolve({statusCode:status});body=resp.responseText;try{meta=JSON.parse(resp.getResponseHeader("x-dropbox-metadata"))}catch(e){return Promise.reject(e)}if(mime=meta.mime_type,rev=meta.rev,self._revCache.set(path,rev),self._shareIfNeeded(path),!resp.getResponseHeader("Content-Type")||resp.getResponseHeader("Content-Type").match(/charset=binary/)){var pending=Promise.defer();return RS.WireClient.readBinaryData(resp.response,mime,function(result){pending.resolve({statusCode:status,body:result,contentType:mime,revision:rev})}),pending.promise}if(mime&&mime.search("application/json")>=0,!0)try{body=JSON.parse(body),mime="application/json; charset=UTF-8"}catch(e){}return Promise.resolve({statusCode:status,body:body,contentType:mime,revision:rev})})},put:function(path,body,contentType,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);if(options&&options.ifMatch&&savedRev&&savedRev!==options.ifMatch)return Promise.resolve({statusCode:412,revision:savedRev});if(options&&"*"===options.ifNoneMatch&&savedRev&&"rev"!==savedRev)return Promise.resolve({statusCode:412,revision:savedRev});if(!contentType.match(/charset=/)&&(body instanceof ArrayBuffer||RS.WireClient.isArrayBufferView(body))&&(contentType+="; charset=binary"),body.length>157286400)return Promise.reject(new Error("Cannot upload file larger than 150MB"));var result,needsMetadata=options&&(options.ifMatch||"*"===options.ifNoneMatch),uploadParams={body:body,contentType:contentType,path:path};return result=needsMetadata?this._getMetadata(path).then(function(metadata){return options&&"*"===options.ifNoneMatch&&metadata?Promise.resolve({statusCode:412,revision:metadata.rev}):options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._uploadSimple(uploadParams)}):self._uploadSimple(uploadParams),result.then(function(ret){return self._shareIfNeeded(path),ret})},"delete":function(path,options){var self=this;if(!this.connected)throw new Error("not connected (path: "+path+")");var savedRev=this._revCache.get(path);return options&&options.ifMatch&&savedRev&&options.ifMatch!==savedRev?Promise.resolve({statusCode:412,revision:savedRev}):options&&options.ifMatch?this._getMetadata(path).then(function(metadata){return options&&options.ifMatch&&metadata&&metadata.rev!==options.ifMatch?Promise.resolve({statusCode:412,revision:metadata.rev}):self._deleteSimple(path)}):self._deleteSimple(path)},_shareIfNeeded:function(path){path.match(/^\/public\/.*[^\/]$/)&&void 0===this._itemRefs[path]&&this.share(path)},share:function(path){var self=this,url="https://api.dropbox.com/1/media/auto"+getDropboxPath(path);return this._request("POST",url,{}).then(function(response){if(200!==response.status)return Promise.reject(new Error('Invalid Dropbox API response status when sharing "'+path+'":'+response.status));try{response=JSON.parse(response.responseText)}catch(e){return Promise.reject(new Error('Invalid Dropbox API response when sharing "'+path+'": '+response.responseText))}return self._itemRefs[path]=response.url,hasLocalStorage&&(localStorage[SETTINGS_KEY+":shares"]=JSON.stringify(self._itemRefs)),Promise.resolve(url)},function(error){return err.message='Sharing dropbox file or folder ("'+path+'") failed.'+err.message,Promise.reject(error)})},info:function(){var url="https://api.dropbox.com/1/account/info";return this._request("GET",url,{}).then(function(resp){try{var info=JSON.parse(resp.responseText);return Promise.resolve(info)}catch(e){return Promise.reject(e)}})},_request:function(method,url,options){var self=this;return options.headers||(options.headers={}),options.headers.Authorization="Bearer "+this.token,this._emit("wire-busy",{method:method,isFolder:isFolder(url)}),RS.WireClient.request.call(this,method,url,options).then(function(xhr){return xhr&&503===xhr.status?(self.online&&(self.online=!1,self.rs._emit("network-offline")),global.setTimeout(self._request(method,url,options),3210)):(self.online||(self.online=!0,self.rs._emit("network-online")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!0}),Promise.resolve(xhr))},function(error){return self.online&&(self.online=!1,self.rs._emit("network-offline")),self._emit("wire-done",{method:method,isFolder:isFolder(url),success:!1}),Promise.reject(error)})},fetchDelta:function(){var args=Array.prototype.slice.call(arguments),self=this,body={path_prefix:PATH_PREFIX};return self._deltaCursor&&(body.cursor=self._deltaCursor),self._request("POST","https://api.dropbox.com/1/delta",{body:encodeQuery(body),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(response){if(200!==response.status)return 400===response.status?(self.rs._emit("error",new RemoteStorage.Unauthorized),Promise.resolve(args)):Promise.reject("dropbox.fetchDelta returned "+response.status+response.responseText);var delta;try{delta=JSON.parse(response.responseText)}catch(error){return RS.log("fetchDeltas can not parse response",error),Promise.reject("can not parse response of fetchDelta : "+error.message)}return delta.entries?(delta.reset&&(self._revCache=new LowerCaseCache("rev")),delta.cursor&&(self._deltaCursor=delta.cursor),delta.entries.forEach(function(entry){var rev,path=entry[0].substr(PATH_PREFIX.length);if(entry[1]){if(entry[1].is_dir)return; +rev=entry[1].rev}else rev=null;self._revCache.set(path,rev)}),Promise.resolve(args)):Promise.reject("dropbox.fetchDeltas failed, no entries found")},function(err){return this.rs.log("fetchDeltas",err),this.rs._emit("error",new RemoteStorage.SyncError("fetchDeltas failed."+err)),Promise.resolve(args)}.bind(this)).then(function(){if(self._revCache){var args=Array.prototype.slice.call(arguments);return self._revCache._activatePropagation(),Promise.resolve(args)}})},_getMetadata:function(path,options){var self=this,cached=this._metadataCache[path],url="https://api.dropbox.com/1/metadata/auto"+getDropboxPath(path);return url+="?list="+(options&&options.list?"true":"false"),cached&&cached.hash&&(url+="&hash="+encodeURIComponent(cached.hash)),this._request("GET",url,{}).then(function(resp){if(304===resp.status)return Promise.resolve(cached);if(200===resp.status){var response=JSON.parse(resp.responseText);return self._metadataCache[path]=response,Promise.resolve(response)}return Promise.resolve()})},_uploadSimple:function(params){var self=this,url="https://api-content.dropbox.com/1/files_put/auto"+getDropboxPath(params.path)+"?";return params&¶ms.ifMatch&&(url+="parent_rev="+encodeURIComponent(params.ifMatch)),self._request("PUT",url,{body:params.body,headers:{"Content-Type":params.contentType}}).then(function(resp){if(200!==resp.status)return Promise.resolve({statusCode:resp.status});var response;try{response=JSON.parse(resp.responseText)}catch(e){return Promise.reject(e)}if(response.path!==getDropboxPath(params.path)){var deleteUrl="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(response.path);return self._request("POST",deleteUrl,{}),self._getMetadata(params.path).then(function(metadata){return Promise.resolve({statusCode:412,revision:metadata.rev})})}return self._revCache.propagateSet(params.path,response.rev),Promise.resolve({statusCode:resp.status})})},_deleteSimple:function(path){var self=this,url="https://api.dropbox.com/1/fileops/delete?root=auto&path="+encodeURIComponent(getDropboxPath(path));return self._request("POST",url,{}).then(function(resp){return 406===resp.status?Promise.reject(new Error("Cannot delete '"+path+"': too many files involved")):((200===resp.status||404===resp.status)&&(self._revCache["delete"](path),delete self._itemRefs[path]),Promise.resolve({statusCode:resp.status}))})}},RS.Dropbox._rs_init=function(rs){hasLocalStorage=RemoteStorage.util.localStorageAvailable(),rs.apiKeys.dropbox&&(rs.dropbox=new RS.Dropbox(rs)),"dropbox"===rs.backend&&hookIt(rs)},RS.Dropbox._rs_supported=function(){return!0},RS.Dropbox._rs_cleanup=function(rs){unHookIt(rs),hasLocalStorage&&delete localStorage[SETTINGS_KEY],rs.removeEventListener("error",onErrorCb),rs.setBackend(void 0)}}(this),remoteStorage=new RemoteStorage; \ No newline at end of file diff --git a/src/version.js b/src/version.js index 2ee6719ee..2430b4bac 100644 --- a/src/version.js +++ b/src/version.js @@ -1,9 +1,9 @@ RemoteStorage.version = RemoteStorage.prototype.version = { productName: 'remotestorage.js', product: 0, - major: 13, - minor: 1, - postfix: 'pre' + major: 14, + minor: 0, + postfix: '' }; RemoteStorage.version.toString = function () {