don't encoded non-objects as JSON before PUT
author() <nilclass@riseup.net>
Wed, 26 Sep 2012 23:24:11 +0000 (01:24 +0200)
committer() <nilclass@riseup.net>
Wed, 26 Sep 2012 23:24:11 +0000 (01:24 +0200)
build/0.7.0-head/remoteStorage-debug.js
build/0.7.0-head/remoteStorage-modules-debug.js
build/0.7.0-head/remoteStorage-modules.js
build/0.7.0-head/remoteStorage-node-debug.js
build/0.7.0-head/remoteStorage-node.js
build/0.7.0-head/remoteStorage.js
src/lib/sync.js

index f145ee2..52c2682 100644 (file)
@@ -1523,7 +1523,10 @@ define('lib/sync',['./wireClient', './store', './util'], function(wireClient, st
           var childNode = store.getNode(dirPath+i);
           var childData = store.getNodeData(dirPath + i);
           startOne();
-          wireClient.set(dirPath+i, JSON.stringify(childData), 'application/json', function(err) {
+          if(typeof(childData) === 'object') {
+            childData = JSON.stringify(childData);
+          }
+          wireClient.set(dirPath+i, childData, 'application/json', function(err) {
             finishOne();
           });
         }
index 62b131d..3698ea9 100644 (file)
@@ -1523,7 +1523,10 @@ define('lib/sync',['./wireClient', './store', './util'], function(wireClient, st
           var childNode = store.getNode(dirPath+i);
           var childData = store.getNodeData(dirPath + i);
           startOne();
-          wireClient.set(dirPath+i, JSON.stringify(childData), 'application/json', function(err) {
+          if(typeof(childData) === 'object') {
+            childData = JSON.stringify(childData);
+          }
+          wireClient.set(dirPath+i, childData, 'application/json', function(err) {
             finishOne();
           });
         }
index f0562c2..9e67ab1 100644 (file)
@@ -23,4 +23,4 @@
     Dual licensed under the MIT and GPL licenses.
   */
 
-(function(){var requirejs,require,define;(function(undef){function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=map&&map["*"]||{};if(name&&name.charAt(0)==="."&&baseName){baseParts=baseParts.slice(0,baseParts.length-1),name=baseParts.concat(name.split("/"));for(i=0;i<name.length;i+=1){part=name[i];if(part===".")name.splice(i,1),i-=1;else if(part===".."){if(i===1&&(name[2]===".."||name[0]===".."))break;i>0&&(name.splice(i-1,2),i-=2)}}name=name.join("/")}if((baseParts||starMap)&&map){nameParts=name.split("/");for(i=nameParts.length;i>0;i-=1){nameSegment=nameParts.slice(0,i).join("/");if(baseParts)for(j=baseParts.length;j>0;j-=1){mapValue=map[baseParts.slice(0,j).join("/")];if(mapValue){mapValue=mapValue[nameSegment];if(mapValue){foundMap=mapValue,foundI=i;break}}}if(foundMap)break;!foundStarMap&&starMap&&starMap[nameSegment]&&(foundStarMap=starMap[nameSegment],starI=i)}!foundMap&&foundStarMap&&(foundMap=foundStarMap,foundI=starI),foundMap&&(nameParts.splice(0,foundI,foundMap),name=nameParts.join("/"))}return name}function makeRequire(relName,forceSync){return function(){return req.apply(undef,aps.call(arguments,0).concat([relName,forceSync]))}}function makeNormalize(relName){return function(name){return normalize(name,relName)}}function makeLoad(depName){return function(value){defined[depName]=value}}function callDep(name){if(waiting.hasOwnProperty(name)){var args=waiting[name];delete waiting[name],defining[name]=!0,main.apply(undef,args)}if(!defined.hasOwnProperty(name))throw new Error("No "+name);return defined[name]}function makeMap(name,relName){var prefix,plugin,index=name.indexOf("!");return index!==-1?(prefix=normalize(name.slice(0,index),relName),name=name.slice(index+1),plugin=callDep(prefix),plugin&&plugin.normalize?name=plugin.normalize(name,makeNormalize(relName)):name=normalize(name,relName)):name=normalize(name,relName),{f:prefix?prefix+"!"+name:name,n:name,p:plugin}}function makeConfig(name){return function(){return config&&config.config&&config.config[name]||{}}}var main,req,defined={},waiting={},config={},defining={},aps=[].slice;main=function(name,deps,callback,relName){var cjsModule,depName,ret,map,i,args=[],usingExports;relName=relName||name;if(typeof callback=="function"){deps=!deps.length&&callback.length?["require","exports","module"]:deps;for(i=0;i<deps.length;i+=1){map=makeMap(deps[i],relName),depName=map.f;if(depName==="require")args[i]=makeRequire(name);else if(depName==="exports")args[i]=defined[name]={},usingExports=!0;else if(depName==="module")cjsModule=args[i]={id:name,uri:"",exports:defined[name],config:makeConfig(name)};else if(defined.hasOwnProperty(depName)||waiting.hasOwnProperty(depName))args[i]=callDep(depName);else if(map.p)map.p.load(map.n,makeRequire(relName,!0),makeLoad(depName),{}),args[i]=defined[depName];else if(!defining[depName])throw new Error(name+" missing "+depName)}ret=callback.apply(defined[name],args);if(name)if(cjsModule&&cjsModule.exports!==undef&&cjsModule.exports!==defined[name])defined[name]=cjsModule.exports;else if(ret!==undef||!usingExports)defined[name]=ret}else name&&(defined[name]=callback)},requirejs=require=req=function(deps,callback,relName,forceSync,alt){return typeof deps=="string"?callDep(makeMap(deps,callback).f):(deps.splice||(config=deps,callback.splice?(deps=callback,callback=relName,relName=null):deps=undef),callback=callback||function(){},typeof relName=="function"&&(relName=forceSync,forceSync=alt),forceSync?main(undef,deps,callback,relName):setTimeout(function(){main(undef,deps,callback,relName)},15),req)},req.config=function(cfg){return config=cfg,req},define=function(name,deps,callback){deps.splice||(callback=deps,deps=[]),waiting[name]=[name,deps,callback]},define.amd={jQuery:!0}})(),define("../build/lib/almond",function(){}),define("lib/assets",[],function(){return{remoteStorageIcon:"data:image/png;base64,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",remoteStorageCube:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAR2SURBVFiFtddfqGVVHQfwz2/vfZ28c2WgP6hMoYkUV4qIYnSKmaQYwaaJ3oLeUnpJmDCmUhCaIhhKGelhelCqN9+ECKdAxR6kgnJASBN9KTGwP2oKTtyZs8/+9bDXPufcfe51xju6YLHX2fu3ft/v+q7fWb/fisy0o3brez6qmt4Luvo7frvx/E7cxNsmcCj2WGnuEb6JaXlbSz8zaX/ksXzj3SHwg6j8aeU28jjeh8TZ8nU3Aq8Sx+2b/ML3s3vnCHxp5YB0Hz6OTkgpMax2jxBSoMJfhGMemTx5aQQOxzWsnCC/gm6hZ+mvFMv36xUYCJQev2Jyt9P54tsj8OVYNW2+izuxIkzlAoGUQuLlMuNqKcQCgVBJNSa4X93+xK/zfxcmcLj5GtUJ8ipMC/i0gA/PQYF/lFkfHClQFxJ1IVET/6S72+n2oa0JHL7s0+RPsR9tAZuOxuNtGKS9xpL8A7BmNP4j8S2nzz+lGJaWDxB7RyCbV54DkZiSrbAhbJBt/25LtUbEY2+P1bdmQY1V8mr8DruET5Z9n4NHTOmmZK9A2ihzp3RdL3tVy+z16OeG0ElncI48yGzeogIzQgexByelp2fMZ+CDAtFK56XzxFwBXSE6C9incbL4PDha9BKBPrjCddJRVT5DHsMLczkLUGhFbPR9iJNYjJUXyGOqfEY6KlxnHrybVjwm0JVDJmV8FZ8TeZysZdyBK9FKXb/6mdTZ+4uXRXcKUxnHpavKdqV58G5JYJFdLvT3yuok3ROiuY3JZ3Rxu7CH7lxvHlPpNVX+nJU/yMk9VJ8nm5GvMc42W6Bwnhl2KRyQ7cOyaqy1R0ScEvFq6aestUdk1cj2YeEA3RwwtwbfSoHtxxmJXeS3nV25RR0/9KnJL8GZyz7i7MoD5MfQ9LZ5YZ+WY+AiW16vc8if/av8PkRevxNPiwTiLceRISPIM3iUOGxa/wfUbiTvxy3ETb3tRfi0HAMx+xgLY1XIeAUPYoO4S+YNqupyVXW5zBuIu/pvHuxtq5j5DLHkfxsFxoaBlN1vVKbEN2TQ5wdYLc8++YibhZvJx3VZizgy8rVEYhwDfUKZFxd/Jf8m4gsydtENJ17TZ8lcLbOGrFfJrKmOiDxHPk58GJ8oPqu3UmDOLr2B5/AhYt08K9Z9AMdAsCeQml6BnKdiriC+iP/iKWkdH7gQgSRfQoi4SWoLcMqsRaUcZiX1xu4yrZmpp6p721lavlLYK/PfeIm4djsCE7xZDNqSVocV9evNJCKIjq6TuTbbAlWvQGZfiCwWJqkqqb7pMUwG0IV/QXwdz1ouKjZXOP021EQjqt2i2k00/Tv1Evj8OfRnC1aPeokl2e/LrM/aYUk2Pgc43T6knqzjBCZytqqhpGpK0DXCmrC26d1Qgs3BJzihnqyPwbdWYJMaFyzLnyuW6yMFLrEsH7ftLyZ/LxbX7vRisrwFW7VHJk/a1+4njuL1udx5Rd9nW/A6cdS+dv/FgHPpl9PhorH67l9Ox62/nv8YdPX3dno9/z+G+TGrzjgPKwAAAABJRU5ErkJggg==",widgetCss:"#remotestorage-state { position:fixed; top:15px; right:15px; height:32px; width:275px; font:normal 16px/100% sans-serif; z-index:99999; background:rgba(0,0,0,.3); padding:5px; border-radius:7px; box-shadow:0 1px rgba(255,255,255,.05), inset 0 1px rgba(0,0,0,.05); transition:width 500ms, background 500ms; }\n#remotestorage-state.connected, #remotestorage-state.busy, #remotestorage-state.offline { width:32px; background:none; box-shadow:none; }\n.remotestorage-button { margin:0; padding:.3em; font-size:14px; height:26px !important; background:#ddd; color:#333; border:1px solid #ccc; border-radius:3px; box-shadow:0 1px 1px #fff inset; }\n#remotestorage-register-button { position:absolute; left:25px; top:8px; max-height:16px; text-decoration:none; font-weight:normal; }\n#remotestorage-connect-button { position:absolute; right:8px; top:8px; padding:0 0 0 17px; width:90px; cursor:pointer; text-align:left; border-radius:0 3px 3px 0; font-weight:normal; }\n#remotestorage-connect-button:hover, #remotestorage-connect-button:focus, .remotestorage-button:hover, .remotestorage-button:focus { background:#eee; color:#000; text-decoration:none; }\n#remotestorage-useraddress { position:absolute; left:25px; top:8px; margin:0; padding:0 17px 0 3px; height:25px; width:142px; background:#eee; color:#333; border:0; border-radius:3px 0 0 3px; box-shadow:0 1px #fff, inset 0 1px #999; font-weight:normal; font-size:14px;}\n#remotestorage-useraddress:hover, #remotestorage-useraddress:focus { background:#fff; color:#000; }\n#remotestorage-cube { position:absolute; right:84px; -webkit-transition:right 500ms; -moz-transition:right 500ms; transition:right 500ms; z-index:99997; }\n#remotestorage-questionmark { position:absolute; left:0; padding:9px 8px; color:#fff; text-decoration:none; z-index:99999; font-weight:normal; }\n.infotext { position:absolute; left:0; top:0; width:255px; height:32px; padding:6px 5px 4px 25px; font-size:10px; background:black; color:white; border-radius:7px; opacity:.85; text-decoration:none; white-space:nowrap; z-index:99998; }\n#remotestorage-questiomark:hover { color:#fff; }\n#remotestorage-questionmark:hover+#remotestorage-infotext { display:inline; }\n#remotestorage-state.busy #remotestorage-cube, #remotestorage-state.connecting #remotestorage-cube {   -webkit-animation-name:remotestorage-loading; -webkit-animation-duration:2s; -webkit-animation-iteration-count:infinite; -webkit-animation-timing-function:linear;\n   -moz-animation-name:remotestorage-loading; -moz-animation-duration:2s; -moz-animation-iteration-count:infinite; -moz-animation-timing-function:linear;\n   -o-animation-name:remotestorage-loading; -o-animation-duration:2s; -o-animation-iteration-count:infinite; -o-animation-timing-function:linear;\n   -ms-animation-name:remotestorage-loading; -ms-animation-duration:2s; -ms-animation-iteration-count:infinite; -ms-animation-timing-function:linear; }\n   @-webkit-keyframes remotestorage-loading { from{-webkit-transform:rotate(0deg)} to{-webkit-transform:rotate(360deg)} }\n   @-moz-keyframes remotestorage-loading { from{-moz-transform:rotate(0deg)} to{-moz-transform:rotate(360deg)} }\n   @-o-keyframes remotestorage-loading { from{-o-transform:rotate(0deg)} to{-o-transform:rotate(360deg)} }\n   @-ms-keyframes remotestorage-loading { from{-ms-transform:rotate(0deg)} to{ -ms-transform:rotate(360deg)} }\n#remotestorage-connect-button, #remotestorage-questionmark, #remotestorage-register-button, #remotestorage-cube, #remotestorage-useraddress, #remotestorage-infotext, #remotestorage-devsonly, #remotestorage-disconnect { display:none }\n#remotestorage-state.anonymous #remotestorage-cube, #remotestorage-state.anonymous #remotestorage-connect-button, #remotestorage-state.anonymous #remotestorage-register-button, #remotestorage-state.anonymous #remotestorage-questionmark { display: block }\n#remotestorage-state.registering #remotestorage-cube, #remotestorage-state.registering #remotestorage-connect-button, #remotestorage-state.registering #remotestorage-register-button, #remotestorage-state.registering #remotestorage-questionmark { display: block }\n#remotestorage-state.interrupted #remotestorage-cube, #remotestorage-state.interrupted #remotestorage-connect-button, #remotestorage-state.interrupted #remotestorage-register-button, #remotestorage-state.interrupted #remotestorage-questionmark { display: block }\n#remotestorage-state.failed #remotestorage-cube, #remotestorage-state.failed #remotestorage-connect-button, #remotestorage-state.failed #remotestorage-register-button, #remotestorage-state.failed #remotestorage-questionmark { display: block }\n#remotestorage-state.typing #remotestorage-cube, #remotestorage-state.typing #remotestorage-connect-button, #remotestorage-state.typing #remotestorage-useraddress, #remotestorage-state.typing #remotestorage-questionmark { display: block }\n#remotestorage-state.connected #remotestorage-cube, #remotestorage-state.busy #remotestorage-cube, #remotestorage-state.offline #remotestorage-cube { right:0; opacity:.5; cursor:pointer; display: block }\n#remotestorage-state.devsonly #remotestorage-devsonly { display: block }\n#remotestorage-disconnect { position:absolute; right:6px; top:9px; padding:5px 28px 2px 6px; height:17px; white-space:nowrap; font-size:10px; background:#000; color:#fff; border-radius:5px; opacity:.5; text-decoration:none; z-index:99996; }\n#remotestorage-disconnect strong { font-weight:bold; }\n#remotestorage-state.connected #remotestorage-cube:hover, #remotestorage-state.busy #remotestorage-cube:hover, #remotestorage-state.offline #remotestorage-cube:hover { opacity:1; }\n#remotestorage-state.connected #remotestorage-disconnect:hover, #remotestorage-state.busy #remotestorage-disconnect:hover, #remotestorage-state.offline #remotestorage-disconnect:hover { display:inline; }\n#remotestorage-state.connected #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.busy #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.offline #remotestorage-cube:hover+#remotestorage-disconnect { display:inline; }\n"}}),define("lib/util",[],function(){var loggers={},silentLogger={},knownLoggers=["sync","webfinger","getputdelete","platform","baseClient"],util={toArray:function(enumerable){var a=[];for(var i in enumerable)a.push(enumerable[i]);return a},getLogger:function(name){return loggers[name]||(loggers[name]={info:function(){this.log("info",util.toArray(arguments))},debug:function(){this.log("debug",util.toArray(arguments),"debug")},error:function(){this.log("error",util.toArray(arguments),"error")},log:function(level,args,type){if(silentLogger[name])return;type||(type="log"),args.unshift("["+name.toUpperCase()+"] -- "+level+" "),(console[type]||console.log).apply(console,args)}}),loggers[name]},silenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)silentLogger[names[i]]=!0},unsilenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)delete silentLogger[names[i]]},silenceAllLoggers:function(){this.silenceLogger.apply(this,knownLoggers)},unsilenceAllLoggers:function(){this.unsilenceLogger.apply(this,knownLoggers)}};return util}),define("lib/platform",["./util"],function(util){function browserParseHeaders(rawHeaders){var headers={},lines=rawHeaders.split(/\r?\n/),lastKey=null,md,key,value;for(var i=0;i<lines.length;i++){if(lines[i].length==0)continue;(md=lines[i].match(/^([^:]+):\s*(.+)$/))?(key=md[1],value=md[2],headers[key]=value,lastKey=key):(md=lines[i].match(/^\s+(.+)$/))?(key=lastKey,value=md[1],headers[key]=headers[key]+value):logger.error("Failed to parse header line: "+lines[i])}return headers}function ajaxBrowser(params){var timedOut=!1,timer;params.timeout&&(timer=window.setTimeout(function(){timedOut=!0,params.error("timeout")},params.timeout));var xhr=new XMLHttpRequest;params.method||(params.method="GET"),xhr.open(params.method,params.url,!0);if(params.headers)for(var header in params.headers)xhr.setRequestHeader(header,params.headers[header]);logger.debug("A "+params.url),xhr.onreadystatechange=function(){xhr.readyState==4&&!timedOut&&(logger.debug("B "+params.url),timer&&window.clearTimeout(timer),logger.debug("xhr cb "+params.url),xhr.status==200||xhr.status==201||xhr.status==204||xhr.status==207?params.success(xhr.responseText,browserParseHeaders(xhr.getAllResponseHeaders())):params.error(xhr.status))},logger.debug("xhr "+params.url),typeof params.data=="string"?xhr.send(params.data):xhr.send()}function ajaxExplorer(params){var xdr=new XDomainRequest;xdr.timeout=params.timeout||3e3,xdr.open(params.method,params.url),xdr.onload=function(){xdr.status==200||xdr.status==201||xdr.status==204?params.success(xhr.responseText):params.error(xhr.status)},xdr.onerror=function(){err("unknown error")},xdr.ontimeout=function(){err(timeout)},params.data?xdr.send(params.data):xdr.send()}function ajaxNode(params){function normalizeHeaders(headers){var h={};for(var key in headers)h[key.replace(/(?:^|\-)[a-z]/g,function(match){return match.toUpperCase()})]=headers[key];return h}var http=require("http"),https=require("https"),url=require("url");params.method||(params.method="GET"),params.data?params.headers["content-length"]=params.data.length:params.data=null;var urlObj=url.parse(params.url),options={method:params.method,host:urlObj.hostname,path:urlObj.path,port:urlObj.port?port:urlObj.protocol=="https:"?443:80,headers:params.headers},timer,timedOut;params.timeout&&(timer=setTimeout(function(){params.error("timeout"),timedOut=!0},params.timeout));var lib=urlObj.protocol=="https:"?https:http,request=lib.request(options,function(response){var str="";response.setEncoding("utf8"),response.on("data",function(chunk){str+=chunk}),response.on("end",function(){timer&&clearTimeout(timer),timedOut||(response.statusCode==200||response.statusCode==201||response.statusCode==204?params.success(str,normalizeHeaders(response.headers)):params.error(response.statusCode))})});request.on("error",function(e){timer&&clearTimeout(timer),params.error(e.message)}),params.data?request.end(params.data):request.end()}function parseXmlBrowser(str,cb){var tree=(new DOMParser).parseFromString(str,"text/xml"),nodes=tree.getElementsByTagName("Link"),obj={Link:[]};for(var i=0;i<nodes.length;i++){var link={};if(nodes[i].attributes)for(var j=0;j<nodes[i].attributes.length;j++)link[nodes[i].attributes[j].name]=nodes[i].attributes[j].value;var props=nodes[i].getElementsByTagName("Property");link.properties={},xyz=props;for(var k=0;k<props.length;k++)link.properties[props[k].getAttribute("type")]=props[k].childNodes[0].nodeValue;link.rel&&obj.Link.push({"@":link})}cb(null,obj)}function parseXmlNode(str,cb){var xml2js=require("xml2js");(new xml2js.Parser).parseString(str,cb)}function harvestParamNode(){}function harvestParamBrowser(param){if(location.hash.length){var pairs=location.hash.substring(1).split("&");for(var i=0;i<pairs.length;i++)if(pairs[i].substring(0,(param+"=").length)==param+"="){var ret=decodeURIComponent(pairs[i].substring((param+"=").length));return delete pairs[i],location="#"+pairs.join("&"),ret}}}function setElementHtmlNode(eltName,html){}function setElementHtmlBrowser(eltName,html){var elt=eltName;elt instanceof Element||(elt=document.getElementById(eltName)),elt.innerHTML=html}function getElementValueNode(eltName){}function getElementValueBrowser(eltName){return document.getElementById(eltName).value}function eltOnNode(eltName,eventType,cb){}function eltOnBrowser(eltName,eventType,cb){eventType=="click"?document.getElementById(eltName).onclick=cb:eventType=="hover"?document.getElementById(eltName).onmouseover=cb:eventType=="type"&&(document.getElementById(eltName).onkeyup=cb)}function getLocationBrowser(){return window.location.href.split("#")[0]}function getLocationNode(){}function setLocationBrowser(location){window.location=location}function setLocationNode(){}function alertBrowser(str){alert(str)}function alertNode(str){console.log(str)}var logger=util.getLogger("platform");return typeof window=="undefined"?{ajax:ajaxNode,parseXml:parseXmlNode,harvestParam:harvestParamNode,setElementHTML:setElementHtmlNode,getElementValue:getElementValueNode,eltOn:eltOnNode,getLocation:getLocationNode,setLocation:setLocationNode,alert:alertNode}:window.XDomainRequest?{ajax:ajaxExplorer,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}:{ajax:ajaxBrowser,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}}),define("lib/webfinger",["./platform","./util"],function(platform,util){function userAddress2hostMetas(userAddress,cb){var parts=userAddress.toLowerCase().split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9a-z\-\_]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9a-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{var query="?resource=acct:"+encodeURIComponent(userAddress);cb(null,["https://"+parts[1]+"/.well-known/host-meta.json"+query,"https://"+parts[1]+"/.well-known/host-meta"+query,"http://"+parts[1]+"/.well-known/host-meta.json"+query,"http://"+parts[1]+"/.well-known/host-meta"+query])}}function fetchXrd(addresses,timeout,cb){var firstAddress=addresses.shift();firstAddress?platform.ajax({url:firstAddress,success:function(data){parseAsJrd(data,function(err,obj){err?parseAsXrd(data,function(err,obj){err?fetchXrd(addresses,timeout,cb):cb(null,obj)}):cb(null,obj)})},error:function(data){fetchXrd(addresses,timeout,cb)},timeout:timeout}):cb("could not fetch xrd")}function parseAsXrd(str,cb){platform.parseXml(str,function(err,obj){if(err)cb(err);else if(obj&&obj.Link){var links={};if(obj.Link&&obj.Link["@"])obj.Link["@"].rel&&(links[obj.Link["@"].rel]=obj.Link["@"]);else for(var i=0;i<obj.Link.length;i++)obj.Link[i]["@"]&&obj.Link[i]["@"].rel&&(links[obj.Link[i]["@"].rel]=obj.Link[i]["@"]);cb(null,links)}else cb("found valid xml but with no Link elements in there")})}function parseAsJrd(str,cb){var obj;try{obj=JSON.parse(str)}catch(e){cb("not valid JSON");return}obj.links||cb("JRD contains no links");var links={};for(var i=0;i<obj.links.length;i++)obj.links[i].rel&&(links[obj.links[i].rel]=obj.links[i]);cb(null,links)}function parseRemoteStorageLink(obj,cb){obj&&obj.href&&obj.type&&obj.properties&&obj.properties["auth-endpoint"]?cb(null,obj):cb("could not extract storageInfo from lrdd")}function getStorageInfo(userAddress,options,cb){userAddress2hostMetas(userAddress,function(err1,hostMetaAddresses){logger.debug("HOST META ADDRESSES",hostMetaAddresses,"(error: ",err1,")"),err1?cb(err1):fetchXrd(hostMetaAddresses,options.timeout,function(err2,hostMetaLinks){if(err2)cb("could not fetch host-meta for "+userAddress);else if(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage)parseRemoteStorageLink(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage,cb);else if(hostMetaLinks.lrdd&&hostMetaLinks.lrdd.template){var parts=hostMetaLinks.lrdd.template.split("{uri}"),lrddAddresses=[parts.join("acct:"+userAddress),parts.join(userAddress)];fetchXrd(lrddAddresses,options.timeout,function(err4,lrddLinks){err4?cb("could not fetch lrdd for "+userAddress):lrddLinks.remoteStorage?parseRemoteStorageLink(lrddLinks.remoteStorage,cb):lrddLinks.remotestorage?parseRemoteStorageLink(lrddLinks.remotestorage,cb):cb("could not extract storageInfo from lrdd")})}else cb("could not extract lrdd template from host-meta")})})}var logger=util.getLogger("webfinger");return{getStorageInfo:getStorageInfo}}),define("lib/hardcoded",["./platform"],function(platform){function testIrisCouch(userAddress,options,cb){platform.ajax({url:"http://proxy.unhosted.org/irisCouchCheck?q=acct:"+userAddress,success:function(data){var obj;try{obj=JSON.parse(data)}catch(e){}obj?cb(null,obj):cb("err: unparsable response from IrisCouch check")},error:function(err){cb("err: during IrisCouch test:"+err)},timeout:options.timeout})}function mapToIrisCouch(userAddress){var parts=userAddress.split("@");return["libredocs","mail","browserid","me"].indexOf(parts[0])==-1?parts[0]+"@iriscouch.com":parts[2].substring(0,parts[2].indexOf("."))+"@iriscouch.com"}function guessStorageInfo(userAddress,options,cb){var parts=userAddress.split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9A-Za-z]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9A-Za-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{while(parts[1].indexOf(".")!=-1){if(guesses[parts[1]]){blueprint=guesses[parts[1]],cb(null,{rel:"https://www.w3.org/community/unhosted/wiki/personal-data-service-00",type:blueprint.type,href:blueprint.hrefPrefix+"/"+(blueprint.pathFormat=="user@host"?userAddress:parts[1]+"/"+parts[0]),properties:{"access-methods":["http://oauth.net/core/1.0/parameters/auth-header"],"auth-methods":["http://oauth.net/discovery/1.0/consumer-identity/static"],"auth-endpoint":blueprint.authPrefix+userAddress}});return}parts[1]=parts[1].substring(parts[1].indexOf(".")+1)}new Date<new Date("9/9/2012")?testIrisCouch(userAddress,options,cb):cb("err: not a guessable domain, and fakefinger-migration has ended")}}var guesses={"iriscouch.com":{type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#couchdb",authPrefix:"http://proxy.unhosted.org/OAuth.html?userAddress=",hrefPrefix:"http://proxy.unhosted.org/CouchDb",pathFormat:"host/user"}};return function(){var surfnetSaml={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/saml/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/saml",pathFormat:"user@host"},surfnetBrowserId={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/browserid/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/browserid",pathFormat:"user@host"},dutchUniversitiesNoSaml=["leidenuniv.nl","leiden.edu","uva.nl","vu.nl","eur.nl","maastrichtuniversity.nl","ru.nl","rug.nl","uu.nl","tudelft.nl","utwente.nl","tue.nl","tilburguniversity.edu","uvt.nl","wur.nl","wageningenuniversity.nl","ou.nl","lumc.nl","amc.nl","ahk.nl","cah.nl","driestar.nl","che.nl","chn.nl","hen.nl","huygens.nl","diedenoort.nl","efa.nl","dehaagsehogeschool.nl","hasdenbosch.nl","inholland.nl","hsbrabant.nl","dehorst.nl","kempel.nl","domstad.nl","hsdrenthe.nl","edith.nl","hsleiden.nl","interport.nl","schumann.nl","hsbos.nl","hva.nl","han.nl","hvu.nl","hesasd.nl","hes-rdam.nl","hku.nl","hmtr.nl","hzeeland.nl","hotelschool.nl","ichtus-rdam.nl","larenstein.nl","iselinge.nl","koncon.nl","kabk.nl","lhump.nl","msm.nl","hsmarnix.nl","nhtv.nl","nth.nl","nhl.nl","sandberg.nl","hsij.nl","stoas.nl","thrijswijk.nl","tio.nl","vhall.nl","chw.nl","hogeschoolrotterdam.nl"],dutchUniversitiesSaml=["surfnet.nl","fontys.nl"];for(var i=0;i<dutchUniversitiesSaml.length;i++)guesses[dutchUniversitiesSaml[i]]=surfnetSaml;for(var i=0;i<dutchUniversitiesNoSaml.length;i++)guesses[dutchUniversitiesNoSaml[i]]=surfnetBrowserId}(),{guessStorageInfo:guessStorageInfo}}),define("lib/getputdelete",["./platform","./util"],function(platform,util){function doCall(method,url,value,mimeType,token,cb,deadLine){var platformObj={url:url,method:method,error:function(err){cb(err)},success:function(data,headers){logger.debug("doCall cb "+url,"headers:",headers),cb(null,data,headers["Content-Type"]||defaultContentType)},timeout:3e3};platformObj.headers={Authorization:"Bearer "+token},mimeType&&(platformObj.headers["Content-Type"]=mimeType),platformObj.fields={withCredentials:"true"},method!="GET"&&(platformObj.data=value),logger.debug("platform.ajax "+url),platform.ajax(platformObj)}function get(url,token,cb){doCall("GET",url,null,null,token,function(err,data,mimetype){if(err==404)cb(null,undefined);else{if(url.substr(-1)=="/")try{data=JSON.parse(data)}catch(e){cb("unparseable directory index");return}cb(err,data,mimetype)}})}function put(url,value,mimeType,token,cb){logger.info("calling PUT "+url),doCall("PUT",url,value,mimeType,token,function(err,data){logger.debug("cb from PUT "+url),err==404?doPut(url,value,token,1,cb):cb(err,data)})}function set(url,valueStr,mimeType,token,cb){typeof valueStr=="undefined"?doCall("DELETE",url,null,null,token,cb):put(url,valueStr,mimeType,token,cb)}var logger=util.getLogger("getputdelete"),defaultContentType="application/octet-stream";return{get:get,set:set}}),define("lib/wireClient",["./getputdelete"],function(getputdelete){function set(key,value){localStorage.setItem(prefix+key,JSON.stringify(value))}function remove(key){localStorage.removeItem(prefix+key)}function get(key){var valStr=localStorage.getItem(prefix+key);if(typeof valStr=="string")try{return JSON.parse(valStr)}catch(e){localStorage.removeItem(prefix+key)}return null}function disconnectRemote(){remove("storageType"),remove("storageHref"),remove("bearerToken")}function getState(){return get("storageType")&&get("storageHref")?get("bearerToken")?"connected":"authing":"anonymous"}function on(eventType,cb){eventType=="error"&&(errorHandler=cb)}function resolveKey(storageType,storageHref,basePath,relPath){var item=(basePath.length?basePath+"/":"")+relPath;return storageHref+item}function setChain(driver,hashMap,mimeType,token,cb,timestamp){var i;for(i in hashMap)break;if(i){var thisOne=hashMap[i];delete hashMap[i],driver.set(i,thisOne,mimeType,token,function(err,timestamp){err?cb(err):setChain(driver,hashMap,mimeType,token,cb,timestamp)})}else cb(null,timestamp)}var prefix="remote_storage_wire_",errorHandler=function(){};return{get:function(path,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.get(resolveKey(storageType,storageHref,"",path),token,cb)},set:function(path,valueStr,mimeType,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.set(resolveKey(storageType,storageHref,"",path),valueStr,mimeType,token,cb)},setStorageInfo:function(type,href){set("storageType",type),set("storageHref",href)},getStorageHref:function(){return get("storageHref")},setBearerToken:function(bearerToken){set("bearerToken",bearerToken)},disconnectRemote:disconnectRemote,on:on,getState:getState}}),define("lib/store",["./util"],function(util){function fireChange(e){for(var i=0;i<onChange.length;i++)onChange[i](e)}function getNode(path){var valueStr=localStorage.getItem(prefixNodes+path),value;if(valueStr)try{value=JSON.parse(valueStr)}catch(e){}return value||(value={startAccess:null,startForce:null,timestamp:0,keep:!0,diff:{}}),value}function isDir(path){return typeof path!="string"&&(logger.error("Given path is not a string: ",path),doSomething()),path.substr(-1)=="/"}function getContainingDir(path){var parts=path.split("/");return parts[parts.length-1].length||parts.pop(),parts.length?(parts.pop(),parts.join("/")+(parts.length?"/":"")):undefined}function getFileName(path){var parts=path.split("/");return isDir(path)?parts[parts.length-2]+"/":parts[parts.length-1]}function getCurrTimestamp(){return(new Date).getTime()}function updateNode(path,node,outgoing,meta,timestamp){node?localStorage.setItem(prefixNodes+path,JSON.stringify(node)):localStorage.removeItem(prefixNodes+path);var containingDir=getContainingDir(path);if(containingDir){var parentNode=getNode(containingDir),parentData=getNodeData(parentNode)||{};if(meta){if(!parentData||!parentData[getFileName(path)])parentData[getFileName(path)]=0;updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!0)}else if(outgoing)node?parentData[getFileName(path)]=(new Date).getTime():delete parentData[getFileName(path)],parentNode.diff[getFileName(path)]=(new Date).getTime(),updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!0);else{if(node){if(!parentData[getFileName(path)]||parentData[getFileName(path)]<timestamp)parentData[getFileName(path)]=timestamp,delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp)}else parentData[getFileName(path)]&&(delete parentData[getFileName(path)],delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp));path.substr(-1)!="/"&&fireChange({path:path,origin:"remote",oldValue:undefined,newValue:node?getNodeData(node):undefined,timestamp:timestamp})}}}function forget(path){localStorage.removeItem(prefixNodes+path)}function forgetAll(){for(var i=0;i<localStorage.length;i++)localStorage.key(i).substr(0,prefixNodes.length)==prefixNodes&&(localStorage.removeItem(localStorage.key(i)),i--)}function on(eventName,cb){if(eventName!="change")throw"Unknown event: "+eventName;onChange.push(cb)}function getState(path){return"disconnected"}function updateNodeData(path,data){if(!path)throw console.trace(),"Path is required!";var encodedData;try{encodedData=JSON.stringify(data)}catch(exc){encodedData=data}localStorage.setItem(prefixNodesData+path,encodedData)}function setNodeData(path,data,outgoing,timestamp,mimeType){var node=getNode(path);mimeType||(mimeType="application/json"),node.mimeType=mimeType,timestamp||(timestamp=(new Date).getTime()),updateNodeData(path,data),updateNode(path,data?node:undefined,outgoing,!1,timestamp)}function getNodeData(path){typeof path=="object"&&(path=path.path);var valueStr=localStorage.getItem(prefixNodesData+path);if(!valueStr)return undefined;try{return JSON.parse(valueStr)}catch(exc){return valueStr}}function setNodeAccess(path,claim){var node=getNode(path);claim!=node.startAccess&&(claim=="rw"||node.startAccess==null)&&(node.startAccess=claim,updateNode(path,node,!1,!0))}function setNodeForce(path,force){var node=getNode(path);node.startForce=force,updateNode(path,node,!1,!0)}function clearDiff(path,i){var node=getNode(path);delete node.diff[i],updateNode(path,node,!1,!0)}var logger=util.getLogger("store"),onChange=[],prefixNodes="remote_storage_nodes:",prefixNodesData="remote_storage_node_data:";return typeof window!="undefined"&&window.addEventListener("storage",function(e){e.key.substring(0,prefixNodes.length==prefixNodes)&&(e.path=e.key.substring(prefixNodes.length),isDir(e.path)||(e.origin="device",fireChange(e)))}),{on:on,getNode:getNode,getNodeData:getNodeData,setNodeData:setNodeData,setNodeAccess:setNodeAccess,setNodeForce:setNodeForce,clearDiff:clearDiff,forget:forget,forgetAll:forgetAll}}),define("lib/sync",["./wireClient","./store","./util"],function(wireClient,store,util){function getState(path){return busy?"busy":"connected"}function setBusy(val){busy=val;for(var i=0;i<stateCbs.length;i++)stateCbs[i](val?"busy":"connected")}function on(eventType,cb){eventType=="state"&&stateCbs.push(cb)}function dirMerge(dirPath,remote,cached,diff,force,access,startOne,finishOne,clearCb){for(var i in remote)(!cached[i]&&!diff[i]||cached[i]<remote[i])&&pullNode(dirPath+i,force,access,startOne,finishOne);for(var i in cached)if(!remote[i]||cached[i]>remote[i])if(i.substr(-1)=="/")pullNode(dirPath+i,force,access,startOne,finishOne);else{var childNode=store.getNode(dirPath+i),childData=store.getNodeData(dirPath+i);startOne(),wireClient.set(dirPath+i,JSON.stringify(childData),"application/json",function(err){finishOne()})}for(var i in diff)cached[i]?remote[i]===cached[i]&&clearCb(i):remote[i]?(startOne(),wireClient.set(dirPath+i,undefined,undefined,function(err){finishOne()})):clearCb(i)}function pullNode(path,force,access,startOne,finishOne){var thisNode=store.getNode(path),thisData=store.getNodeData(path);!thisData&&path.substr(-1)=="/"&&(thisData={}),logger.debug("pullNode "+path,thisNode);if(thisNode.startAccess=="rw"||!access)access=thisNode.startAccess;thisNode.startForce&&(force=thisNode.startForce);if(access)startOne(),wireClient.get(path,function(err,data){!err&&data&&(path.substr(-1)=="/"?dirMerge(path,data,thisData,thisNode.diff,force,access,startOne,finishOne,function(i){store.clearDiff(path,i)}):store.setNodeData(path,data,!1)),finishOne(err)});else for(var i in thisData)i.substr(-1)=="/"&&pullNode(path+i,force,access,startOne,finishOne)}function fetchNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(err),outstanding--,outstanding==0&&(setBusy(!1),callback(errors||null,store.getNode(path)))}var outstanding=0,errors=[];setBusy(!0),pullNode(path,!1,!0,startOne,finishOne)}function syncNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(path),outstanding--,outstanding==0&&(setBusy(!1),callback&&callback(errors.length>0?errors:null))}if(wireClient.getState()=="anonymous"){callback&&callback(["not connected"]);return}var outstanding=0,errors=[];logger.info("syncNow "+path),setBusy(!0),pullNode(path,!1,!1,startOne,finishOne)}var prefix="_remoteStorage_",busy=!1,stateCbs=[],logger=util.getLogger("sync");return{syncNow:syncNow,fetchNow:fetchNow,getState:getState,on:on}}),define("lib/widget",["./assets","./webfinger","./hardcoded","./wireClient","./sync","./store","./platform"],function(assets,webfinger,hardcoded,wireClient,sync,store,platform){function translate(text){return text}function isRegistering(){return localStorage.getItem("remote_storage_registering")}function setRegistering(value){value===!1?localStorage.removeItem("remote_storage_registering"):localStorage.setItem("remote_storage_registering","true")}function calcWidgetStateOnLoad(){wc=wireClient;if(isRegistering())return"registering";var wireClientState=wireClient.getState();return wireClientState=="connected"?sync.getState():wireClientState}function setWidgetStateOnLoad(){setWidgetState(calcWidgetStateOnLoad())}function setWidgetState(state){widgetState=state,displayWidgetState(state,userAddress)}function getWidgetState(){return widgetState}function displayWidgetState(state,userAddress){var userAddress=localStorage.remote_storage_widget_useraddress,html="<style>"+assets.widgetCss+"</style>"+'<div id="remotestorage-state" class="'+state+'">'+'  <input id="remotestorage-connect-button" class="remotestorage-button" type="submit" value="'+translate("connect")+'"/>'+'  <span id="remotestorage-register-button" class="remotestorage-button">'+translate("get remoteStorage")+"</span>"+'  <img id="remotestorage-cube" src="'+assets.remoteStorageCube+'"/>'+'  <span id="remotestorage-disconnect">Disconnect '+(userAddress?"<strong>"+userAddress+"</strong>":"")+"</span>"+'  <a id="remotestorage-questionmark" href="http://unhosted.org/#remotestorage" target="_blank">?</a>'+'  <span class="infotext" id="remotestorage-infotext">This app allows you to use your own data storage!<br/>Click for more info on the Unhosted movement.</span>'+'  <input id="remotestorage-useraddress" type="text" value="me@local.dev" placeholder="you@remotestorage" autofocus="" />'+'  <a class="infotext" href="http://remotestoragejs.com/" target="_blank" id="remotestorage-devsonly">RemoteStorageJs is still in developer preview!<br/>Click for more info.</a>'+"</div>";platform.setElementHTML(connectElement,html),platform.eltOn("remotestorage-register-button","click",handleRegisterButtonClick),platform.eltOn("remotestorage-connect-button","click",handleConnectButtonClick),platform.eltOn("remotestorage-disconnect","click",handleDisconnectClick),platform.eltOn("remotestorage-cube","click",handleCubeClick),platform.eltOn("remotestorage-useraddress","type",handleWidgetTypeUserAddress)}function handleRegisterButtonClick(){setRegistering();var win=window.open("http://unhosted.org/en/a/register.html","Get your remote storage","resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=820,height=800,top=0,left=0");setWidgetState("registering")}function redirectUriToClientId(loc){if(loc.substring(0,"http://".length)=="http://")loc=loc.substring("http://".length);else{if(loc.substring(0,"https://".length)!="https://")return loc;loc=loc.substring("https://".length)}var hostParts=loc.split("/")[0].split("@");return hostParts.length>2?loc:(hostParts.length==2&&hostParts.shift(),hostParts[0])}function dance(endpoint){var endPointParts=endpoint.split("?"),queryParams=[];endPointParts.length==2?queryParams=endPointParts[1].split("&"):endPointParts.length>2&&errorHandler("more than one questionmark in auth-endpoint - ignoring");var loc=platform.getLocation(),scopesArr=[];for(var i in scopesObj)scopesArr.push(i+":"+scopesObj[i]);queryParams.push("response_type=token"),queryParams.push("scope="+encodeURIComponent(scopesArr.join(" "))),queryParams.push("redirect_uri="+encodeURIComponent(loc)),queryParams.push("client_id="+encodeURIComponent(redirectUriToClientId(loc))),platform.setLocation(endPointParts[0]+"?"+queryParams.join("&"))}function discoverStorageInfo(userAddress,cb){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?hardcoded.guessStorageInfo(userAddress,{timeout:3e3},function(err2,data2){err2?cb(err2):data2.type&&data2.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data2.type,data2.href),cb(null,data2.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from webfinger")}):data.type&&data.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data.type,data.href),cb(null,data.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from hardcoded")})}function handleConnectButtonClick(){widgetState=="typing"?(userAddress=platform.getElementValue("remotestorage-useraddress"),localStorage.remote_storage_widget_useraddress=userAddress,setWidgetState("connecting"),discoverStorageInfo(userAddress,function(err,auth){err?(alert("webfinger discovery failed! (sorry this is still a developer preview! developers, point local.dev to 127.0.0.1, then run sudo node server/nodejs-example.js from the repo)"),setWidgetState("failed")):dance(auth)})):setWidgetState("typing")}function handleDisconnectClick(){widgetState=="connected"?(wireClient.disconnectRemote(),store.forgetAll(),setWidgetState("anonymous")):alert("you cannot disconnect now, please wait until the cloud is up to date...")}function handleCubeClick(){sync.syncNow("/",function(errors){})}function handleWidgetTypeUserAddress(){setRegistering(!1),console.log("handleWidgetTypeUserAddress")}function handleWidgetHover(){console.log("handleWidgetHover")}function display(setConnectElement,setLocale){var tokenHarvested=platform.harvestParam("access_token"),storageRootHarvested=platform.harvestParam("storage_root"),storageApiHarvested=platform.harvestParam("storage_api"),authorizeEndpointHarvested=platform.harvestParam("authorize_endpoint");tokenHarvested&&wireClient.setBearerToken(tokenHarvested),storageRootHarvested&&wireClient.setStorageInfo(storageApiHarvested?storageApiHarvested:"2012.04",storageRootHarvested),authorizeEndpointHarvested&&dance(authorizeEndpointHarvested),connectElement=setConnectElement,locale=setLocale,wireClient.on("error",function(err){platform.alert(translate(err))}),sync.on("state",setWidgetState),setWidgetStateOnLoad(),window.onkeydown=function(evt){if(evt.ctrlKey&&evt.which==83)return evt.preventDefault(),console.log("CTRL+S - SYNCING"),sync.syncNow("/",function(errors){}),!1}}function addScope(module,mode){if(!scopesObj[module]||mode=="rw")scopesObj[module]=mode}var locale="en",connectElement,widgetState,userAddress,scopesObj={};return{display:display,addScope:addScope,getState:getWidgetState}}),define("lib/baseClient",["./sync","./store","./util"],function(sync,store,util){function bindContext(callback,context){return context?function(){return callback.apply(context,arguments)}:callback}function extractModuleName(path){if(path&&typeof path=="string"){var parts=path.split("/");if(parts.length>3&&parts[1]=="public")return parts[2];if(parts.length>2)return parts[1]}}function fireChange(moduleName,eventObj){if(moduleName&&moduleChangeHandlers[moduleName])for(var i=0;i<moduleChangeHandlers[moduleName].length;i++)moduleChangeHandlers[moduleName][i](eventObj)}function fireError(str){for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](str)}function set(path,absPath,valueStr){if(isDir(absPath)){fireError("attempt to set a value to a directory "+absPath);return}var node=store.getNode(absPath),changeEvent={origin:"window",oldValue:store.getNodeData(node),newValue:valueStr,path:path},ret=store.setNodeData(absPath,valueStr,!0),moduleName=extractModuleName(absPath);return fireChange(moduleName,changeEvent),fireChange("root",changeEvent),ret}function claimAccess(path,claim){store.setNodeAccess(path,claim)}function isDir(path){return typeof path!="string"&&doSomething(),path.substr(-1)=="/"}var moduleChangeHandlers={},errorHandlers=[],logger=util.getLogger("baseClient");return store.on("change",function(e){var moduleName=extractModuleName(e.path);fireChange(moduleName,e),fireChange("root",e)}),{claimAccess:claimAccess,getInstance:function(moduleName,isPublic){function makePath(path){return moduleName=="root"?path:(isPublic?"/public/":"/")+moduleName+"/"+path}function nodeGivesAccess(path,mode){var node=store.getNode(path);logger.debug("check node access",path,mode,node);var access=(new RegExp(mode)).test(node.startAccess);if(access)return!0;if(path.length>0)return nodeGivesAccess(path.replace(/[^\/]+\/?$/,""))}function ensureAccess(mode){var path=makePath(moduleName=="root"?"/":"");if(!nodeGivesAccess(path,mode))throw"Not sufficient access claimed for node at "+path}return{on:function(eventType,cb,context){eventType=="change"?moduleName&&(moduleChangeHandlers[moduleName]||(moduleChangeHandlers[moduleName]=[]),moduleChangeHandlers[moduleName].push(bindContext(cb,context))):eventType=="error"&&errorHandlers.push(bindContext(cb,context))},getObject:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath);return data&&typeof data=="object"&&delete data["@type"],data}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node);data&&typeof data=="object"&&delete data["@type"],bindContext(cb,context)(data)})},getListing:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath),arr=[];for(var i in data)arr.push(i);return arr}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node),arr=[];for(var i in data)arr.push(i);bindContext(cb,context)(arr)})},getDocument:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath);return{mimeType:node.mimeType,data:store.getNodeData(node)}}sync.fetchNow(absPath,function(err,node){bindContext(cb,context)({mimeType:node.mimeType,data:store.getNodeData(node)})})},remove:function(path,cb,context){ensureAccess("w");var ret=set(path,makePath(path));return this.syncNow(cb,context),ret},storeObject:function(type,path,obj,cb,context){ensureAccess("w");if(typeof obj!="object")throw"storeObject needs to get an object as value!";obj["@type"]="https://remotestoragejs.com/spec/modules/"+moduleName+"/"+type;var ret=set(path,makePath(path),obj,"application/json");return this.sync(path),this.syncNow(cb,context),ret},storeDocument:function(mimeType,path,data,cb,context){ensureAccess("w");var ret=set(path,makePath(path),data,mimeType);return this.syncNow(cb,context),ret},getItemURL:function(path){var base=remoteStorage.getStorageHref();return base?(base.substr(-1)!="/"&&(base+="/"),base+makePath(path)):null},getCurrentWebRoot:function(){return"https://example.com/this/is/an/example/"+(isPublic?"public/":"")+moduleName+"/"},sync:function(path,switchVal){var absPath=makePath(path);store.setNodeForce(absPath,switchVal!=0)},syncNow:function(cb,context){sync.syncNow(makePath(""),cb?bindContext(cb,context):function(errors){errors&&errors.length>0&&(logger.error("Error syncing: ",errors),fireError(errors))})},getState:function(path){}}}}}),define("lib/nodeConnect",["./wireClient","./webfinger"],function(wireClient,webfinger){return{setUserAddress:function(userAddress,callback){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?console.error("Failed to look up storage info for user "+userAddress+": ",err):wireClient.setStorageInfo(data.type,data.href),callback(err)})},setStorageInfo:wireClient.setStorageInfo,setBearerToken:wireClient.setBearerToken}}),define("remoteStorage",["require","./lib/widget","./lib/baseClient","./lib/store","./lib/sync","./lib/wireClient","./lib/nodeConnect","./lib/util"],function(require,widget,baseClient,store,sync,wireClient,nodeConnect,util){function deprecate(oldFn,newFn){logger.error("DEPRECATION: "+oldFn+" is deprecated! Use "+newFn+" instead.")}var claimedModules={},modules={},logger=util.getLogger("base"),remoteStorage={defineModule:function(moduleName,builder){logger.debug("DEFINE MODULE",moduleName);var module=builder(baseClient.getInstance(moduleName,!1),baseClient.getInstance(moduleName,!0));modules[moduleName]=module,this[moduleName]=module.exports,logger.debug("Module defined: "+moduleName,module,this)},getModuleList:function(){return Object.keys(modules)},getClaimedModuleList:function(){return Object.keys(claimedModules)},getModuleInfo:function(moduleName){return modules[moduleName]},claimAccess:function(claimed){if(typeof claimed!="object"||claimed instanceof Array){claimed instanceof Array||(claimed=Array.prototype.slice.call(arguments));var _modules=claimed,mode="rw";claimed={};var lastArg=arguments[arguments.length-1];typeof lastArg=="string"&&lastArg.match(/^rw?$/)&&(mode=lastArg,delete arguments[arguments.length-1]);for(var i in _modules)claimed[_modules[i]]=mode}for(var moduleName in claimed)this.claimModuleAccess(moduleName,claimed[moduleName])},claimModuleAccess:function(moduleName,mode){logger.debug("claimModuleAccess",moduleName,mode);if(!moduleName in modules)throw"Module not defined: "+moduleName;if(moduleName in claimedModules)return;mode||(mode="r"),moduleName=="root"?(moduleName="",widget.addScope("",mode),baseClient.claimAccess("/",mode)):(widget.addScope(moduleName,mode),baseClient.claimAccess("/"+moduleName+"/",mode),baseClient.claimAccess("/public/"+moduleName+"/",mode)),claimedModules[moduleName]=!0},loadModule:function(){deprecate("remoteStorage.loadModule","remoteStorage.claimAccess"),this.claimModuleAccess.apply(this,arguments)},setBearerToken:function(bearerToken,claimedScopes){wireClient.setBearerToken(bearerToken),baseClient.claimScopes(claimedScopes)},disconnectRemote:wireClient.disconnectRemote,flushLocal:store.forgetAll,syncNow:sync.syncNow,displayWidget:widget.display,getWidgetState:widget.getState,setStorageInfo:wireClient.setStorageInfo,getStorageHref:wireClient.getStorageHref,nodeConnect:nodeConnect,util:util};return remoteStorage}),define("modules/root",["../remoteStorage"],function(remoteStorage){return remoteStorage.defineModule("public",function(client){function getPublicItems(){return client.getObject("publishedItems")}return{exports:{getPublicItems:getPublicItems,getObject:client.getObject}}}),remoteStorage.defineModule("root",function(myPrivateBaseClient,myPublicBaseClient){function setOnChange(cb){myPrivateBaseClient.on("change",function(e){console.log(e),cb(e)}),myPublicBaseClient.on("change",function(e){console.log(e),cb(e)})}function addToPublicItems(path){var data=myPublicBaseClient.getObject("publishedItems");path[0]=="/"&&(path=path.substr(1)),data?data.indexOf(path)==-1&&data.unshift(path):(data=[],data.push(path)),myPublicBaseClient.storeObject("array","publishedItems",data)}function removeFromPublicItems(path){var data=myPublicBaseClient.getObject("publishedItems");path[0]=="/"&&(path=path.substr(1)),data?data.indexOf(path)!=-1&&data.pop(path):data=[],myPublicBaseClient.storeObject("array","publishedItems",data)}function publishObject(path){if(pathIsPublic(path))return"Object has already been made public";var data=myPrivateBaseClient.getObject(path),publicPath="/public"+path;return addToPublicItems(publicPath),myPrivateBaseClient.remove(path),myPrivateBaseClient.storeObject(data["@type"],publicPath,data),"Object "+path+" has been published to "+publicPath}function archiveObject(path){if(!pathIsPublic(path))return"Object has already been made private";var data=myPrivateBaseClient.getObject(path),privatePath=path.substring(7,path.length);return removeFromPublicItems(path),myPrivateBaseClient.remove(path),myPrivateBaseClient.storeObject(data["@type"],privatePath,data),"Object "+path+" has been archived to "+privatePath}function pathIsPublic(path){return path.substring(0,8)=="/public/"?!0:!1}function getClient(path){return pathIsPublic(path)?myPublicBaseClient:myPrivateBaseClient}function getObject(path,cb,context){var client=getClient(path);return client.getObject(path,cb,context)}function setObject(type,path,obj){var client=getClient(path);typeof obj=="object"?client.storeObject(type,path,obj):client.storeDocument(type,path,obj)}function removeObject(path){var client=getClient(path);client.remove(path)}function getListing(path,cb,context){var client=getClient(path);return client.getListing(path,cb,context)}return{exports:{getListing:getListing,getObject:getObject,setObject:setObject,removeObject:removeObject,archiveObject:archiveObject,publishObject:publishObject,setOnChange:setOnChange}}}),remoteStorage.root}),define("modules/calendar",["../remoteStorage"],function(remoteStorage){var moduleName="calendar";return remoteStorage.defineModule(moduleName,function(privateBaseClient){function getEventsForDay(day){var ids=privateBaseClient.getListing(day+"/"),list=[];for(var i=0;i<ids.length;i++){var obj=privateBaseClient.getObject(day+"/"+ids[i]);list.push({itemId:ids[i],itemValue:obj.text})}return list}function addEvent(itemId,day,value){privateBaseClient.storeObject("event",day+"/"+itemId,{text:value})}function removeEvent(itemId,day){privateBaseClient.remove(day+"/"+itemId)}return{exports:{getEventsForDay:getEventsForDay,addEvent:addEvent,removeEvent:removeEvent}}}),remoteStorage[moduleName]}),define("modules/deps/vcardjs-0.2",[],function(){(function(){var CHARS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");Math.uuid=function(len,radix){var chars=CHARS,uuid=[],i;radix=radix||chars.length;if(len)for(i=0;i<len;i++)uuid[i]=chars[0|Math.random()*radix];else{var r;uuid[8]=uuid[13]=uuid[18]=uuid[23]="-",uuid[14]="4";for(i=0;i<36;i++)uuid[i]||(r=0|Math.random()*16,uuid[i]=chars[i==19?r&3|8:r])}return uuid.join("")},Math.uuidFast=function(){var chars=CHARS,uuid=new Array(36),rnd=0,r;for(var i=0;i<36;i++)i==8||i==13||i==18||i==23?uuid[i]="-":i==14?uuid[i]="4":(rnd<=2&&(rnd=33554432+Math.random()*16777216|0),r=rnd&15,rnd>>=4,uuid[i]=chars[i==19?r&3|8:r]);return uuid.join("")},Math.uuidCompact=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=="x"?r:r&3|8;return v.toString(16)})}})();var VCard;(function(){VCard=function(attributes){this.changed=!1;if(typeof attributes=="object")for(var key in attributes)this[key]=attributes[key],this.changed=!0},VCard.prototype={validate:function(){function addError(attribute,type){errors.push([attribute,type])}function validateCompoundWithType(attribute,values){for(var i in values){var value=values[i];typeof value!="object"?errors.push([attribute+"-"+i,"not-an-object"]):value.type?value.value||errors.push([attribute+"-"+i,"missing-value"]):errors.push([attribute+"-"+i,"missing-type"])}}var errors=[];this.fn||addError("fn","required");for(var key in VCard.multivaluedKeys)this[key]&&!(this[key]instanceof Array)&&(this[key]=[this[key]]);return this.email&&validateCompoundWithType("email",this.email),this.tel&&validateCompoundWithType("email",this.tel),this.uid||this.addAttribute("uid",this.generateUID()),this.rev||this.addAttribute("rev",this.generateRev()),this.errors=errors,!(errors.length>0)},generateUID:function(){return"uuid:"+Math.uuid()},generateRev:function(){return(new Date).toISOString().replace(/[\.\:\-]/g,"")},setAttribute:function(key,value){this[key]=value,this.changed=!0},addAttribute:function(key,value){console.log("add attribute",key,value);if(!value)return;VCard.multivaluedKeys[key]?this[key]?(console.log("multivalued push"),this[key].push(value)):(console.log("multivalued set"),this.setAttribute(key,[value])):this.setAttribute(key,value)},toJSON:function(){return JSON.stringify(this.toJCard())},toJCard:function(){var jcard={};for(var k in VCard.allKeys){var key=VCard.allKeys[k];this[key]&&(jcard[key]=this[key])}return jcard},merge:function(other){function mergeProperty(key){other[key]?other[key]==this[key]?result.setAttribute(this[key]):(result.addAttribute(this[key]),result.addAttribute(other[key])):result[key]=this[key]}if(typeof other.uid!="undefined"&&typeof this.uid!="undefined"&&other.uid!==this.uid)throw"Won't merge vcards without matching UIDs.";var result=new VCard;for(key in this)mergeProperty(key);for(key in other)result[key]||mergeProperty(key)}},VCard.enums={telType:["text","voice","fax","cell","video","pager","textphone"],relatedType:["contact","acquaintance","friend","met","co-worker","colleague","co-resident","neighbor","child","parent","sibling","spouse","kin","muse","crush","date","sweetheart","me","agent","emergency"],emailType:["work","home","internet"],langType:["work","home"]},VCard.allKeys=["fn","n","nickname","photo","bday","anniversary","gender","tel","email","impp","lang","tz","geo","title","role","logo","org","member","related","categories","note","prodid","rev","sound","uid"],VCard.multivaluedKeys={email:!0,tel:!0,geo:!0,title:!0,role:!0,logo:!0,org:!0,member:!0,related:!0,categories:!0,note:!0}})();var VCF;return function(){VCF={simpleKeys:["VERSION","FN","PHOTO","GEO","TITLE","ROLE","LOGO","MEMBER","NOTE","PRODID","SOUND","UID"],csvKeys:["NICKNAME","CATEGORIES"],dateAndOrTimeKeys:["BDAY","ANNIVERSARY","REV"],parse:function(input,callback,context){var vcard=null;context||(context=this),this.lex(input,function(key,value,attrs){function setAttr(val){vcard&&vcard.addAttribute(key.toLowerCase(),val)}if(key=="BEGIN")vcard=new VCard;else if(key=="END")vcard&&(callback.apply(context,[vcard]),vcard=null);else if(this.simpleKeys.indexOf(key)!=-1)setAttr(value);else if(this.csvKeys.indexOf(key)!=-1)setAttr(value.split(","));else if(this.dateAndOrTimeKeys.indexOf(key)!=-1)attrs.VALUE=="text"?setAttr(value):(!attrs.CALSCALE||attrs.CALSCALE=="gregorian")&&setAttr(this.parseDateAndOrTime(value));else if(key=="N")setAttr(this.parseName(value));else if(key=="GENDER")setAttr(this.parseGender(value));else if(key=="TEL")setAttr({type:attrs.TYPE||"voice",pref:attrs.PREF,value:value});else if(key=="EMAIL")setAttr({type:attrs.TYPE,pref:attrs.PREF,value:value});else if(key=="IMPP")setAttr({value:value});else if(key=="LANG")setAttr({type:attrs.TYPE,pref:attrs.PREF,value:value});else if(key=="TZ")attrs.VALUE=="utc-offset"?setAttr({"utc-offset":this.parseTimezone(value)}):setAttr({name:value});else if(key=="ORG"){var parts=value.split(";");setAttr({"organization-name":parts[0],"organization-unit":parts[1]})}else key=="RELATED"?setAttr({type:attrs.TYPE,pref:attrs.PREF,value:attrs.VALUE}):console.log("WARNING: unhandled key: ",key)})},nameParts:["family-name","given-name","additional-name","honorific-prefix","honorific-suffix"],parseName:function(name){var parts=name.split(";"),n={};for(var i in parts)parts[i]&&(n[this.nameParts[i]]=parts[i].split(","));return n},parseGender:function(value){var gender={},parts=value.split(";");switch(parts[0]){case"M":gender.sex="male";break;case"F":gender.sex="female";break;case"O":gender.sex="other"}return parts[1]&&(gender.identity=parts[1]),gender},dateRE:/^(\d{4})(\d{2})(\d{2})$/,dateReducedARE:/^(\d{4})\-(\d{2})$/,dateReducedBRE:/^(\d{4})$/,dateTruncatedMDRE:/^\-{2}(\d{2})(\d{2})$/,dateTruncatedDRE:/^\-{3}(\d{2})$/,timeRE:/^(\d{2})(\d{2})(\d{2})([+\-]\d+|Z|)$/,timeReducedARE:/^(\d{2})(\d{2})([+\-]\d+|Z|)$/,timeReducedBRE:/^(\d{2})([+\-]\d+|Z|)$/,timeTruncatedMSRE:/^\-{2}(\d{2})(\d{2})([+\-]\d+|Z|)$/,timeTruncatedSRE:/^\-{3}(\d{2})([+\-]\d+|Z|)$/,parseDate:function(data){var md,y,m,d;if(md=data.match(this.dateRE))y=md[1],m=md[2],d=md[3];else if(md=data.match(this.dateReducedARE))y=md[1],m=md[2];else if(md=data.match(this.dateReducedBRE))y=md[1];else if(md=data.match(this.dateTruncatedMDRE))m=md[1],d=md[2];else{if(!(md=data.match(this.dateTruncatedDRE)))return console.error("WARNING: failed to parse date: ",data),null;d=md[1]}var dt=new Date(0);return typeof y!="undefined"&&dt.setUTCFullYear(y),typeof m!="undefined"&&dt.setUTCMonth(m-1),typeof d!="undefined"&&dt.setUTCDate(d),dt},parseTime:function(data){var md,h,m,s,tz;if(md=data.match(this.timeRE))h=md[1],m=md[2],s=md[3],tz=md[4];else if(md=data.match(this.timeReducedARE))h=md[1],m=md[2],tz=md[3];else if(md=data.match(this.timeReducedBRE))h=md[1],tz=md[2];else if(md=data.match(this.timeTruncatedMSRE))m=md[1],s=md[2],tz=md[3];else{if(!(md=data.match(this.timeTruncatedSRE)))return console.error("WARNING: failed to parse time: ",data),null;s=md[1],tz=md[2]}var dt=new Date(0);return typeof h!="undefined"&&dt.setUTCHours(h),typeof m!="undefined"&&dt.setUTCMinutes(m),typeof s!="undefined"&&dt.setUTCSeconds(s),tz&&(dt=this.applyTimezone(dt,tz)),dt},addDates:function(aDate,bDate,addSub){typeof addSub=="undefined"&&(addSub=!0);if(!aDate)return bDate;if(!bDate)return aDate;var a=Number(aDate),b=Number(bDate),c=addSub?a+b:a-b;return new Date(c)},parseTimezone:function(tz){var md;if(md=tz.match(/^([+\-])(\d{2})(\d{2})?/)){var offset=new Date(0);return offset.setUTCHours(md[2]),offset.setUTCMinutes(md[3]||0),Number(offset)*(md[1]=="+"?1:-1)}return null},applyTimezone:function(date,tz){var offset=this.parseTimezone(tz);return offset?new Date(Number(date)+offset):date},parseDateTime:function(data){var parts=data.split("T"),t=this.parseDate(parts[0]),d=this.parseTime(parts[1]);return this.addDates(t,d)},parseDateAndOrTime:function(data){switch(data.indexOf("T")){case 0:return this.parseTime(data.slice(1));case-1:return this.parseDate(data);default:return this.parseDateTime(data)}},lineRE:/^([^\s].*)(?:\r?\n|$)/,foldedLineRE:/^\s(.+)(?:\r?\n|$)/,lex:function(input,callback){var md,line=null,length=0;for(;;){(md=input.match(this.lineRE))?(line&&this.lexLine(line,callback),line=md[1],length=md[0].length):(md=input.match(this.foldedLineRE))?line&&(line+=md[1],length=md[0].length):console.error("Unmatched line: "+line),input=input.slice(length);if(!input)break}line&&this.lexLine(line,callback),line=null},lexLine:function(line,callback){function finalizeKeyOrAttr(){if(key){if(!attrKey){console.error("Invalid attribute: ",tmp,"Line dropped.");return}attrs[attrKey]=tmp}else key=tmp}var tmp="",key=null,attrs={},value=null,attrKey=null;for(var i in line){var c=line[i];switch(c){case":":finalizeKeyOrAttr(),value=line.slice(Number(i)+1),callback.apply(this,[key,value,attrs]);return;case";":finalizeKeyOrAttr(),tmp="";break;case"=":attrKey=tmp,tmp="";break;default:tmp+=c}}}}}(),{VCard:VCard,VCF:VCF}}),define("modules/contacts",["../remoteStorage","../modules/deps/vcardjs-0.2"],function(remoteStorage,vCardJS){var moduleName="contacts",VCard=vCardJS.VCard,VCF=vCardJS.VCF;return remoteStorage.defineModule(moduleName,function(base){function extend(destination,source){var keys=Object.keys(source);for(var i=0;i<keys.length;i++){var key=keys[i];destination[key]=source[key]}return destination}function extend(){var destination=arguments[0],source;for(var i=1;i<arguments.length;i++){source=arguments[i];var keys=Object.keys(source);for(var j=0;j<keys.length;j++){var key=keys[j];destination[key]=source[key]}}return destination}var DEBUG=!0,contacts={},bindContext=typeof function(){}.bind=="function"?function(cb,context){return cb.bind(context)}:function(cb,context){return function(){return cb.apply(context,arguments)}},debug=DEBUG?bindContext(console.log,console):function(){},nodePrototype={isNew:!0,markSaved:function(){return this.isNew=!1,this},save:function(){return this.validate(),this.errors&&this.errors.length>0?!1:(base.storeObject("vcard+"+this.kind,this.uid,this.toJCard()),this.markSaved(),!0)}},Contact=function(){VCard.apply(this,arguments),this.setAttribute("kind","individual")};extend(Contact.prototype,nodePrototype,VCard.prototype,{});var Group=function(name){VCard.apply(this,arguments),this.setAttribute("kind","group")};return extend(Group.prototype,nodePrototype,{getMembers:function(){var members=[];for(var i=0;i<this.member.length;i++)members.push(this.lookupMember(member[i]));return members},lookupMember:function(uri){var md=uri.match(/^([^:]):(.*)$/),scheme=md[1],rest=md[2],key;switch(scheme){case"urn":case"uuid":return contacts.get(uri);case"mailto":case"xmpp":case"sip":case"tel":var query={};query[{mailto:"email",xmpp:"impp",sip:"impp",tel:"tel"}[scheme]]=rest;var results=contacts.search(query);if(results.length>0)return results[0];if(scheme=="tel")break;case"acct":console.error("FIXME: implement contact-lookup via webfinger!");break;case"http":console.error("FIXME: implement contact-lookup via HTTP!");break;default:console.error("FIXME: unknown URI scheme "+scheme)}return undefined}}),extend(contacts,{Contact:Contact,on:function(eventType,callback){base.on(eventType,function(event){event.oldValue&&(event.oldValue=new Contact(event.oldValue)),event.newValue&&(event.newValue=new Contact(event.newValue)),callback(event)})},sync:function(){debug("contacts.sync()"),base.sync("/")},list:function(limit,offset){var list=base.getListing("");offset||(offset=0),limit||(limit=list.length-offset);for(var i=0;i<limit;i++)list[i+offset]&&(list[i+offset]=this.get(list[i+offset]));return list},get:function(uid,cb,context){if(!cb)return this._load(base.getObject(uid));base.getObject(uid,function(data){bindContext(cb,context)(this._load(data))},this)},build:function(attributes){return this._wrap(attributes)},create:function(attributes){var instance=this.build(attributes);return instance.save(),instance},filter:function(cb,context){var list=this.list(),results=[],item;for(var i=0;i<list.length;i++)item=bindContext(cb,context)(list[i]),item&&results.push(item);return results},search:function(filter){var keys=Object.keys(filter);return this.filter(function(item){return this.searchMatch(item,filter,keys)},this)},searchMatch:function(item,filter,filterKeys){filterKeys||(filterKeys=Object.keys(filter));var check=function(value,ref){if(value instanceof Array)for(var i=0;i<value.length;i++)check(value[i],ref);else if(typeof value=="object"&&value.value)check(value.value,ref);else{if(typeof ref=="string"&&ref.length===0)return!0;if(ref instanceof RegExp){if(!ref.test(value))return!1}else if(value!==ref)return!1}};return this.filter(function(item){for(var i=0;i<keys.length;i++){var k=keys[i],v=filter[k];if(!check(item[k],v))return!1}return debug("success"),item})},_load:function(data){return this._wrap(data).markSaved()},_wrap:function(data){return data instanceof Contact?data:new Contact(data)}}),{name:moduleName,dataHints:{},exports:contacts}}),remoteStorage[moduleName]}),define("modules/documents",["../remoteStorage"],function(remoteStorage){var moduleName="documents";return remoteStorage.defineModule(moduleName,function(myBaseClient){function fire(eventType,eventObj){if(eventType=="error")for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](eventObj)}function getUuid(){var uuid="",i,random;for(i=0;i<32;i++){random=Math.random()*16|0;if(i===8||i===12||i===16||i===20)uuid+="-";uuid+=(i===12?4:i===16?random&3|8:random).toString(16)}return uuid}function getPrivateList(listName){function getIds(){return myBaseClient.getListing(listName+"/")}function getContent(id){var obj=myBaseClient.getObject(listName+"/"+id);return obj?obj.content:""}function getTitle(id){return getContent(id).slice(0,50)}function setContent(id,content){content==""?myBaseClient.remove(listName+"/"+id):myBaseClient.storeObject("text",listName+"/"+id,{content:content})}function add(content){var id=getUuid();return myBaseClient.storeObject("text",listName+"/"+id,{content:content}),id}function on(eventType,cb){myBaseClient.on(eventType,cb),eventType=="error"&&errorHandlers.push(cb)}return myBaseClient.sync(listName+"/"),{getIds:getIds,getContent:getContent,getTitle:getTitle,setContent:setContent,add:add,on:on}}var errorHandlers=[];return{name:moduleName,dataHints:{module:"documents can be text documents, or etherpad-lite documents or pdfs or whatever people consider a (text) document. But spreadsheets and diagrams probably not","objectType text":"a human-readable plain-text document in utf-8. No html or markdown etc, they should have their own object types","string text#content":"the content of the text document","directory documents/notes/":"used by litewrite for quick notes","item documents/notes/calendar":"used by docrastinate for the 'calendar' pane","item documents/notes/projects":"used by docrastinate for the 'projects' pane","item documents/notes/personal":"used by docrastinate for the 'personal' pane"},exports:{getPrivateList:getPrivateList}}}),remoteStorage[moduleName]}),define("modules/money",["../remoteStorage"],function(remoteStorage){remoteStorage.defineModule("money",function(myPrivateBaseClient,myPublicBaseClient){return{name:"money",dataHints:{},exports:{setDayBusiness:function(tab,year,month,day,transactions,endBalances){var datePath=year+"/"+month+"/"+day+"/"+tab.substring(1)+"/";for(var i=0;i<transactions.length;i++)myPrivateBaseClient.storeObject("transaction",datePath+"transaction/"+i,transactions[i]);for(var i in endBalances)myPrivateBaseClient.storeObject("balance",datePath+"balance/"+i,endBalances[i])}}}})}),define("modules/tasks",["../remoteStorage"],function(remoteStorage){var moduleName="tasks";return remoteStorage.defineModule(moduleName,function(myPrivateBaseClient,myPublicBaseClient){function fire(eventType,eventObj){if(eventType=="error")for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](eventObj)}function getUuid(){var uuid="",i,random;for(i=0;i<32;i++){random=Math.random()*16|0;if(i===8||i===12||i===16||i===20)uuid+="-";uuid+=(i===12?4:i===16?random&3|8:random).toString(16)}return uuid}function getPrivateList(listName){function getIds(){return myPrivateBaseClient.getListing(listName+"/")}function get(id){return myPrivateBaseClient.getObject(listName+"/"+id)}function set(id,title){var obj=myPrivateBaseClient.getObject(listName+"/"+id);obj.title=title,myPrivateBaseClient.storeObject("task",listName+"/"+id,obj)}function add(title){var id=getUuid();return myPrivateBaseClient.storeObject("task",listName+"/"+id,{title:title,completed:!1}),id}function markCompleted(id,completedVal){typeof completedVal=="undefined"&&(completedVal=!0);var obj=myPrivateBaseClient.getObject(listName+"/"+id);obj&&obj.completed!=completedVal&&(obj.completed=completedVal,myPrivateBaseClient.storeObject("task",listName+"/"+id,obj))}function isCompleted(id){var obj=get(id);return obj&&obj.completed}function getStats(){var ids=getIds(),stat={todoCompleted:0,totalTodo:ids.length};for(var i=0;i<stat.totalTodo;i++)isCompleted(ids[i])&&(stat.todoCompleted+=1);return stat.todoLeft=stat.totalTodo-stat.todoCompleted,stat}function remove(id){myPrivateBaseClient.remove(listName+"/"+id)}function on(eventType,cb){myPrivateBaseClient.on(eventType,cb),eventType=="error"&&errorHandlers.push(cb)}return myPrivateBaseClient.sync(listName+"/"),{getIds:getIds,get:get,set:set,add:add,remove:remove,markCompleted:markCompleted,getStats:getStats,on:on}}var errorHandlers=[];return{name:moduleName,dataHints:{module:"tasks are things that need doing; items on your todo list","objectType task":"something that needs doing, like cleaning the windows or fixing a specific bug in a program","string task#title":"describes what it is that needs doing","boolean task#completed":"whether the task has already been completed or not (yet)","directory tasks/todos/":"default private todo list","directory tasks/:year/":"tasks that need doing during year :year","directory public/tasks/:hash/":"tasks list shared to for instance a team"},exports:{getPrivateList:getPrivateList}}}),remoteStorage[moduleName]}),define("modules/bookmarks",["../remoteStorage"],function(remoteStorage){var moduleName="bookmarks";remoteStorage.defineModule(moduleName,function(privateClient,publicClient){return{name:moduleName,dataHints:{module:"Store URLs which you do not wish to forget"},exports:{on:privateClient.on,listUrls:function(){var keys=privateClient.getListing(""),urls=[];return keys.forEach(function(key){urls.push(privateClient.get(key).url)}),urls},listBookmarks:function(){var keys=privateClient.getListing(""),bms=[];return keys.forEach(function(key){bms.push(privateClient.getObject(key))}),bms},addUrl:function(url){return privateClient.storeObject("bookmark",encodeURIComponent(url),{url:url,createdAt:new Date})},getPublicListing:function(){var listing=publicClient.getObject("publishedItems");return listing||{items:[]}},publish:function(url){var key=encodeURIComponent(url),bookmark=privateClient.getObject(key);publicClient.storeObject("bookmark",key,bookmark);var listing=publicClient.getListing("");delete listing.published,publicClient.storeObject("bookmark-list","published",listing)}}}})}),define("remoteStorage-modules",["./remoteStorage","./modules/root","./modules/calendar","./modules/contacts","./modules/documents","./modules/money","./modules/tasks","./modules/bookmarks"],function(remoteStorage){return remoteStorage}),remoteStorage=require("remoteStorage-modules")})()
\ No newline at end of file
+(function(){var requirejs,require,define;(function(undef){function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=map&&map["*"]||{};if(name&&name.charAt(0)==="."&&baseName){baseParts=baseParts.slice(0,baseParts.length-1),name=baseParts.concat(name.split("/"));for(i=0;i<name.length;i+=1){part=name[i];if(part===".")name.splice(i,1),i-=1;else if(part===".."){if(i===1&&(name[2]===".."||name[0]===".."))break;i>0&&(name.splice(i-1,2),i-=2)}}name=name.join("/")}if((baseParts||starMap)&&map){nameParts=name.split("/");for(i=nameParts.length;i>0;i-=1){nameSegment=nameParts.slice(0,i).join("/");if(baseParts)for(j=baseParts.length;j>0;j-=1){mapValue=map[baseParts.slice(0,j).join("/")];if(mapValue){mapValue=mapValue[nameSegment];if(mapValue){foundMap=mapValue,foundI=i;break}}}if(foundMap)break;!foundStarMap&&starMap&&starMap[nameSegment]&&(foundStarMap=starMap[nameSegment],starI=i)}!foundMap&&foundStarMap&&(foundMap=foundStarMap,foundI=starI),foundMap&&(nameParts.splice(0,foundI,foundMap),name=nameParts.join("/"))}return name}function makeRequire(relName,forceSync){return function(){return req.apply(undef,aps.call(arguments,0).concat([relName,forceSync]))}}function makeNormalize(relName){return function(name){return normalize(name,relName)}}function makeLoad(depName){return function(value){defined[depName]=value}}function callDep(name){if(waiting.hasOwnProperty(name)){var args=waiting[name];delete waiting[name],defining[name]=!0,main.apply(undef,args)}if(!defined.hasOwnProperty(name))throw new Error("No "+name);return defined[name]}function makeMap(name,relName){var prefix,plugin,index=name.indexOf("!");return index!==-1?(prefix=normalize(name.slice(0,index),relName),name=name.slice(index+1),plugin=callDep(prefix),plugin&&plugin.normalize?name=plugin.normalize(name,makeNormalize(relName)):name=normalize(name,relName)):name=normalize(name,relName),{f:prefix?prefix+"!"+name:name,n:name,p:plugin}}function makeConfig(name){return function(){return config&&config.config&&config.config[name]||{}}}var main,req,defined={},waiting={},config={},defining={},aps=[].slice;main=function(name,deps,callback,relName){var cjsModule,depName,ret,map,i,args=[],usingExports;relName=relName||name;if(typeof callback=="function"){deps=!deps.length&&callback.length?["require","exports","module"]:deps;for(i=0;i<deps.length;i+=1){map=makeMap(deps[i],relName),depName=map.f;if(depName==="require")args[i]=makeRequire(name);else if(depName==="exports")args[i]=defined[name]={},usingExports=!0;else if(depName==="module")cjsModule=args[i]={id:name,uri:"",exports:defined[name],config:makeConfig(name)};else if(defined.hasOwnProperty(depName)||waiting.hasOwnProperty(depName))args[i]=callDep(depName);else if(map.p)map.p.load(map.n,makeRequire(relName,!0),makeLoad(depName),{}),args[i]=defined[depName];else if(!defining[depName])throw new Error(name+" missing "+depName)}ret=callback.apply(defined[name],args);if(name)if(cjsModule&&cjsModule.exports!==undef&&cjsModule.exports!==defined[name])defined[name]=cjsModule.exports;else if(ret!==undef||!usingExports)defined[name]=ret}else name&&(defined[name]=callback)},requirejs=require=req=function(deps,callback,relName,forceSync,alt){return typeof deps=="string"?callDep(makeMap(deps,callback).f):(deps.splice||(config=deps,callback.splice?(deps=callback,callback=relName,relName=null):deps=undef),callback=callback||function(){},typeof relName=="function"&&(relName=forceSync,forceSync=alt),forceSync?main(undef,deps,callback,relName):setTimeout(function(){main(undef,deps,callback,relName)},15),req)},req.config=function(cfg){return config=cfg,req},define=function(name,deps,callback){deps.splice||(callback=deps,deps=[]),waiting[name]=[name,deps,callback]},define.amd={jQuery:!0}})(),define("../build/lib/almond",function(){}),define("lib/assets",[],function(){return{remoteStorageIcon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANoAAACACAYAAABtCHdKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z132OZE1f8/w25YdnFh6U0QEBWXKshPYFdB0KWEpbyuCC+CoIjiCy9VEETFFylKky5iY4WlidSAIE1hAUF67yBVOixtiTzz++MkPHnmmZlMcud+2uZ7XbnuZHIymeSek3PmzDlnlNaaEYc4mhvYA9gROAb4PUnaM6htajFHQ404RoujqcDRwArAm8B8wO3AniTpDYPZtBZzLkYOo8XRROBY4EuF0heAxQvH5wL7k6T/GsimtWgx/BktjhYAfgJ8FxhtnH0cWN4oexc4EjiKJH2n+w1s0WI4M1ocjQJ2QZhsIQfVfcBKjnNPAweSpGd3oXUtWvTB8GS0ONoAMXJMLKH8J/DZEpqbgL1I0tubaFqLFjYML0aLo+WBXwCbF0p9D/B34Aue86pQx3TgRyTpCx21sUULC4YHo8XReOAHwO7AGOOs7wGuADbynFfG8SzgCOB4kvT9qs1s0cKFuQa7AV7EkSKOdkDGWvsiTKYrbO94zmEpGw8cCtyVTRO0aNEIhi6jxdE6wEzgNGBRqjFMCKP5tuWAPxFHl2fTBi1adIShx2hxtBRxdDpwLbAG9RilU0bLty8CtxJHxxFHC3b5yVuMYAydMVocjQX2QlTEcfQde7n2fWUAJwH/Yyk3x2a2MmXsvwr8DPg1Sfofx/1atLBiaEi0OJoG3AX8GBiLXyW0lbtoO5VoxboXQKYUbiWONmzw6VvMATA9KQYWcbQ64pc4if6dm8B9X9k7lnLloA2lWRFIiKNLEXeux0rqatFikCRaHC1CHJ0M3Egvk2H81pU8xe3dDq510eS/mwF3EEeHE0fzdfhGWoxwDCyjxVFEHO0J3At8k17J0QRTdUN1LLtPhIwr7yWOdiKOhoYq3mLIYeA6RhxtAtyBTAjPT/WOTkV6G6PVqSNkWxQ4BbiROJpU/yW1GKnovtUxjlYEjgK+jFsNM8vM82aZuY+jfEfgD4Vjm7XRLLftV/lVwHnAASTp0477tZjD0D1Gi6MJwI+Q8JVRWamPucp+zX3bsVm+LXBWth/CZOZxVQYr7r+LGHqObsNxWjSvOsbRKOLoO8D9wG70ZbI6KloonXkNiOpIB3V0QjcPcBAyftsm5NW1GLloVqLF0frIXNPKlI+zcPxWURnLGr8R4ljsQ6jamO9XkWrF/TYcZw5GM4wWR8sBPwe2IsyYYdsP+TX3bcdFfAEJlXGhW2qjb386cFAbjjNnoTNGi6OPIOEre9Lfsx7PMQFlxV9Xme24iP8H3OI572K0UIYL3TeP3wIOA45rw3HmDNRjtDhSwNeBw5HkN2VjFkr2fWV4ymzHOXqANZEpBRe6qTaGHD8O7EuSXuxpY4sRgOqMFkdrA78E1qLcMOA7tu2H/Pr2i3gfSWNwt+P8QKiNtmNb2dXA3iTpvY62thjmCGe0OFoKmWz+76ykihRrcrxm7tuOAd5GPgb3O56oU0brlNnM8h7gVODHJOmrjja3GKYoZ7Q4mgfYBziA3vCVMtO2We47JqAMT5ntGOANZIz2kOPJqo7POmW2UIZ7DTgYOKUNxxk58M+jSfjKA0gc1jgLhck8rvIQyVYm1UIYvLi9D6QBdKHtqFqP7x3ZrsuxIHA8kk7hy7QYEbBLtDhaDTgOWK9QWqWThjBI2b7v19y3Hb8ArA082f8Bu6o2diLNzHKAS5Dx26OW52gxTNBXokn4yq+QXPU2JrPB9XX2lYXsd7qlmepV5Zqy+4e2O/S92N6pWT4VuI84+kUbjjN8IYwm4St7AY8A38GtUvo6oI3GVRba4etcm2/5/JSpPobUad4fB71rP5Sxyt5ljrmB7wMPE0ffasNxhh/mysJX7kFcp+a30IR0hipf7xAJESJpfHVphMFAGC6UOets5jPY2lX2nlw0JhYDfoOkU5jsuL7FEMRo4BxkeaMqKGO+MsazHfv2bb/mvnn8n8Kvq1NXgSrUU9x3HdvaVxx7udpkjh9tWAQJ/1nhw4uU2gIZV9swG3gJMWxdBlystf7AenOl7gy4v4nJWuu3lFJ7IIGwOTbVWrumV2z33gw4sVC0u9b6Egvd/MBXgQ2BjwPzAs8CtwHTtdYPGPQ7AP8X2g4PDkX4xefWZ0PPaCRpKMik6ZLApwsEvq+4CR9dHalm28fY9zHa+4VfX6c2mcf166K31VUss7WzeM6EjznvBF5HjDxvGHTzAh9z1AnwSSRtxM7AQ0qpnbXWtvXiVvPU4UIeoTHBaEOMex7Thi2N6+c1CZRSOyHLc5na10Qk5nE/pdT+WuujCufmw/9uQjEfIpyqvqOeXNcfj3wd3kKCNJ8ouTCUAasynU81s9H66stVx9RDX2fDU5/r/fjeS8hH7D5kqam5gfWREJxO8CngKqXUlA7rKcMmFek39p1USu0G/A77ECfHXMCRSqlTK967qzAH1WshDsIXIPkVnyOsI+QIlWpVJFvdzcZoTTCXra228yHvxIWc7nFkvYGZyP/RZNbkMcAflFLdtGROVkqNLycDpdSqwFKe8xMQ1S0UuyilhkxaCVu6udHA3sCjwK6IKrkvohZA9a9xCONRYb/4a+4Xy0xGs6l2OVxqYNPjMl+bi3gBcdh+DYnSXrKE3obrEG8eEKZaDEntUJQySwDfAE7w1LMevWq4C285yiNkBdYLSq6Hcum3J6K65UiR8dwlwAfA54D96btW3k+AKUhqiX866v0O8l5yzMD9Pp6ylM1GtAwftCuvo0ZWyrwQiZ9aB9gB+braPESK15UxoI/pbOfLfs39/NhkNBOuMZWvrMq4zNYuG00ROWNdhCxPNdVDW4ZXtdY3G2XnKqVmICkecmyDn9H+obWeXbMNIAzUBKPtbhwfrrX+SeH470qp+4FLC2VfVkp9Smv9EPBvW6WZAaaI5yzvrUhvpob/wEefo2w+RiPhMDcgEm5F5Csym+5KNdtxVVWvaN7vpC5b3WXPUqYimnRvIQ7bE5FcIzcjhoSQuqrCtL6trpQaZaVsBqXjtEx9XddzfmHENS3Hu0g8Xx9orRPgVqP4k2HN7C5CJz4XQuZvpiNp1VYFzkBEtomqUq2MyXx1+rbQMZrr3r422J4j9D0UaWcDJyMM9mdEDToa+IilvqbwEL3vBkRDWbyL9/uoUmqVEpoNETXThWWM46c8UvbBkmsHBTZG83WQ9ZAvxteQxDtrIeplD+4O56vXdo6SffPXtZnzaFUlle3+traWPZsNHyAfqtWRccReiMGjbPWcjqHFudVMozDBRtsgyqRa2fl+jOahfbzk2kFBHVeeeZAwjpnABJJ0e2QweE12vkpH8XXasrrKmMTHaCHtLJN4daRZD/Jh+hxJuiuiit8K7EHvXNRAwJQG3b53p4xmjote8dC+ZBwvZKUaYHTiMzcRuIo4OgZ4jCT9LyQfvakjF1FHqlVlunyrY973tdHFWKGS5xrgiyTpN4DXiaPfIerixxz03cRixrE5+d00JrmmEZRSKwMfLbneNAg1It0HEiajVe3MAN9CfO82J0lnkqQbIVHY9znoTYR0anPf/K3LaL56bO1w0fme6R/AZiTpNODubKngW4CveNrla29HyKxmxbmtD3BY5BpEbua3oeqk9rBEU17giwOnE0dnEkdLkqRXIOrkrvT1MgnpQGVMFiqNXIxWpR5Xm0Ke5z5gO5I0JklvIo4+gRg7jqP+mKgJZvu2cfyg1vq9Buotg4uh5ghGq7I+WsgXd2NgMnH0M+C3JOn5xNFFyLzNXvRXWVx128qx7GOhz5GP0VzzaCaqzpfl5SYeR9ylLiJJNXE0NzIG24velHy+67uCzEQ+BUkPWMSlFvIiJiilvPNoWuvXA5rQj6Eyr5HhHoWgMq8VH7wT1nXVlnmROY5pxNHeJOl9wB+Jo3OBnZClbieU1O9jOrAzHsZ+6IS1j4l8TGFe8zySHeycD3N9SMawo5G5nDoeIq57h2CKUio3dc+HeIGYeB84raSe0kSvSqkJWuuycd5SSqlVtdbFrGRlZv3hgLGIo4EPPUVGa3QsAHwGuDKL2D6KJH0X+BVxdCawCzK2K3pnNyHVbIxWJUwm1K2qeO5VZK3s6SSpfPnjaH5kmeDtaEY9N+8fwngfQZyHfThcaz2QK5ZuSt/0f3OE2giddYIQVXIU8D3gWuJoPQCSdBZJejTweWQSvOhl4qs/5J5FGlN19NUB/dvg+/BoxJvjWGASSXpagcm2QOKVbGn5OtEUmkYP0O3EraaPpMlY5vGIzdocymiddpBlgBnE0YnEkcxrJOkrJOkhiNHkHMT65btPVaarYnW01el69veQD8TnSdJfkqRvAxBHHyWO/oh4eixS4d0MFvPNBVyolOoX82VgdsDmwvXG8bpZ0CZKqZWApQvnPkAWAhmOKHs/74V6hnSCYj1bINJt6w/PJunzJOkByMovieV+Icxho6szYe26H0hHOBuZCzuMJBW9XJap2oV8nqwZNPH+r0OcwddBTOvfpb8H+9KIh48P82ut5ynZXOOz2+g7dTAaCc6E/tLsJsrHOkMR7wS8n3mLjNbJn1pFNZoAHEkcnZ2tQiNI0idI0j0QZrzOU0eoVLOlMghhLvNePYhZfiOS9CCStLfjxNEqiPr1Q8RjpltqYp3rX9Va35xtV2utT0VCSc416HbsoF1l0MBfjLJNjN8cl3WxHYOOnNGq/olNdKC1gb8QR7sTR72WpyR9gCTdBTEk3Oa5n49RQlRHsw7bfa4DtiRJ9yFJe/3r4mgccXQQEv6xUoVn7pQBO3rnWuseJK6rp1C8olKqm/6AJgNt7DDrzxGMFoJO/mRXB4uQP/4S4mjNPlck6W0k6deRwDwz70SIZLIZQ0KYFMSN7L9J0l1J0r4pxePoi8hXeifk/XUqrcz2dBVa6+eBZ4ziMheoTnAlvf8FSBDr3khahhzPaq3v6mIbBh0hE9Z1OkHVL/YKwFnE0dnAkSTprA/PJOn1xNENyGTrbohhxSaFMH5DzftFk/79wPEk6Y39qOJoEWRN7k0InxOrOv9VrKObk9nP0NerfYFu3Uhr/bpS6ibEypxjP4OsTJr1GMc+ATEk/SJ9De6EwepAIeE3lxNHfZO0JKnO3Lq2QCIHXqA/I5vHRYlmO188fgJZyGPbfkwWRypbg/pySpLHWNCJit3NDmLGEXY7IavJSGaUfhmjvWgcL+qhNWPrzGsHBb6MxFXQhNTLr18YOJY4Opk46uvNkKQ9JOkFwOaIm9OrRl3FfZvV0aR9HokH+wpJehVJ2vcZ4mgFJG7sJ8gEcKdj07pjsuEOHyO9D1xVcv2/jGPfmHL5kmsHBabq2O2OUKWTrg+sRRwdD5xJkvaqD7Ic7Qzi6ELEaLIdvV/JvG6X6qiQeCYJU0nSYrSxII7GIN4rO+N3Eaqr6uXXhV6jK9Y/pKC1vlsp9Qz2seD1WmtXcp8c/RhNKTVOa/2OhfbTxvGQYLS6KsNAfZnHIvr8DOJoxX5nk/QdkvQ0RKU8A5lMzu+Vq0dFifYmMqG8JUl6joPJ1gLORxitrtN11Wuaph2KuNxRXmptzObpni4UjQF+atIppb6KRK3n6EGiKAYdpq9j0+hE4hWvm4gYS8TzIkn7hnUk6RvA8cTRDMSHcip9Vcd3kZRjf+xjaClC/BP3QZjW5uM4p0qsKUqp/h+kvrhKa122aOJl9A/RyctD8Av6ZuvaWym1FMLA/0HmCL9lXHOO1rrbEm2UUqps7P6h935VZmiSLpR+LiTl3YbE0WEk6cx+FEn6MvBz4uiMQn23AdNIUnf4exxtiuSuNEPmXe0bTAYaaKYM8YecQHmU9lXIeKxo1n9Ca20m03HhN0ieyjzH5VxI+NW2Dvoe4JDAujvBGNzS+sO2VFGNYGhIvSUQ6XUFEhXQf73nJH22sG8ma+mFrMt9IDJ5PthLIQ1lqdYxskUw/k7fSOvgSWqt9XtZ3v3z6JtI1YYeYD9zsYvBRD7h2jS6IfVMhpQMtHG0BXFUrYOKf+I3EGfmz9VsSzdoRzpMxqrkDaK1vhLx3fStfvomsJXW+uiKbesqqg72Bwuue8+H+BluQhwd3sdNyoU4WgmRYp/APrk5HMZVtvfxPHBF4fgOz/W3AEWLXXGu6W812pOPzx412vCQQSc+o4Ie4Frj/B2IASzH8+aNtNb3K6VWRD60GyCWzLnpXbbp/AArZhEPl7TZREr1d9Sj9KajizkZfVsoXRXaJuneR1TJi5yPG0c7A99E4uRs60YrRMq7ztWlbZpOAS+SpLao6RZDEFXGJYM5fii7dwqchfjV+XAe8lV1ScgqzzjY72PEjudGIkbjX2WlLkLrrHJvV1qBWxH/yCcBiKP5SNK+K5hKgpy5smmAw4mji5GVR4qTm91iskFlCKXUaGCRzJnYRfMp6rfzaa312456P1KmximlxtHf00MDL2qta8enZXkkeyqqkcXrQ9o+HstiiRZ8UNXq2C2mpEK9Of2LwDEk6V+BnJmmATsSR7ExGb04cBJx9GsgIUnvI452BP4LSRbkW9huoNAoQyqldkHSKawFjFNKvQzcDhyltf6rQX4/9a2uMQWjhlJqGyTGbTVgcaXUS8BdwNla699arl8HhwuWUur5rG0naK3dQwI7zkOyFn899AKl1HeQPrQasIhS6oWs7dO11jMslxyMRCKU4emc0apKlqalVRX6PG/9r0nSdzKL45eR3CS5Q+lY+i7kMBZJL/BDYFvi6HiS9GbgT8TR1Ug6uM3xd/bi+CgU3ZBm3jozCXYCEl50NuJZ8xRi/NkA+ItS6jDgx1kefrJyW73jkKj3HyCJYG24O7vvGCRJ0Tez+x4OPAYsh1h2T1NKbQjs7HCd2pK+c3ELIetTr42kXDgD2EVr/a7v+bO2jEIY+OUy2ox+PsQlb0vg9Gx7CUmPOBU4Uyn1RWA3y+IaDyL5S314ryjRhpK0ymFedxtwGEkqmZviaA2ESSbS1zAyD2LmzZEvRauQkJwTiKNbgONI0oeBg4mjCxBrZNHVqw5zFa+rQt8Ufo4sLvhVrfX5xrljs6/2rxDpdgGA1tpqRSus1nmP1vq6kvvuikiPr2itzfXQTlRKTUeiu/fFvnD7TK21lTGUUlORj+u9yPOVYVUkG/N4pdQSPrU5ww+RDF1rGOnwAKYrpTZCJqUfAI4xzs8KeDe11YU6HalOZ8qvewU4kCT9Fkn6GHG0bJbz/zT6Rjjn9OYaz/PQn2k+B5xJHB1MHC1Kkt6FeBn8HHi7RnvrSrxQ+lJapdRCiCT7qYXJAMhSGlyGdK5GkEnRvYDfW5gsv+9fkaxheyilKi1LpbXOMzx/P3Cp3snI9IUGvMvrZslPd0VS75lMlt//CmS5sv2UUmNtNGUwGa3bDFS1M+Zq4lSSNCGOFiSODgT+RO9ypjbTt4/RiteMQlTGi4mj3YCxJOkMZLGOS7rwPOZ1VehD8G1EZT6lhO5IYE2l1GoV2uDDhohB46gSupMQ48GWNe7xS0RKbRpAOwlZ7ehBPAscZtgKMQoeWUJ3MBIHNzXg/v3gkmjd7jjFa1yd9XbER/EIICWOvo2MF75Gr7XUZJx832S0sQ7aIr3UL0Ger2eZuXYAHnG0tRMJ3S361YBrtdZvltDluViWq1C3D8sDr5QlY9Vav4KErXy86g201q8iHvwfCyCfjDDaTEokGvIObi5bf0Br/RIyuV3rnZWFhA8Ew5nXv4o4j24PPEocbYmoOv9LX1Oq2eGLx6Z4t6mONoZZEFGpLiKONiBJb0Msk0cg6mSd5+lE6lXFsvgX6QNAaz0LGcMuXUYbiKXpn4fEheeRdtaBmYKhH5RSywJLIUx2A/CZEnVvacJX03mOmu8sZIzWhLQKQQ9wJrAxSXohYjU6HzgUsf646gxRHcc66GxMp5Cv1gnE0XRgIkn6B8R1yLcgRJMSr+7H6qNY3JYceI5eT/hOsVRWXwj+TX0Gf5HyZYAnI0OOfyDMFiFTHC4sSfhH9A1qvrOqniFNdCDbdiewFUn6U2Bx4ug3iLl1Rcc9yxjGJ9Fw7NvusRZwbmZ4GUOS7o1I2scc96+LJuoAmEW4WrYz8IcG7gnSmcti1nL8h/oLWyxIucl+EnC31nqW1vpRhLF947TR9E/+48J+iLZVGTmjDYTEsuE1ZI7mq8DLxNFhSPzT5w06H1OZ5yFMopl1+O4TIzkof4CYeGNEnbTNB/ngk6pVr7fhEfpGGDuhtZ6ptS5zoB1qWIry1ASTgWKCpZBxWhC01o/UfWdFidYJ0/iklQ09wAxkovRSJLfjNcDW2B1+bffy3ddmdXTRm+Wu5xqDSIFrESPJ7xFr22Ulz9/EByn0+vOA1TPv9hGFbJy1DJ4xqFJqAWS6pxgUPBNYRynVhMZQGzbVsckOYqvvHsS8+yPEVPs3YHf6q3uu67Hsm3RmXaZEs9XrKjcxP3AQcDXwWZL0e4irU5PLH9V9/2choSbTs7mtkYRdkHkxn+P4usj7KjLaDYiXSdkSVl1F6BitCeZ7A9FvpyIp5a5EFixcOPA+IYySb2bewHGeusskm+u6pYETs0xcsxE3sCOQ/CRV0NiHTWv9AeIVsgpwuVKqKWPHoEIp9QlkfHRKZmZ3YTLwjJEn5A7kP2lEfayLTr56oR1CI75vP0OsYmcjFkVbCgNfXo6QQMucpmwezfXrY2wc59YA/owEDx6GuDUdgkjrbqqTVmitH1JKTUGk2z1KqWOBkzrxhB8gzKOUKv5vCyNSaF3kA/0w5e5X+UT1h9Bap0qpW7J6bE7NnWK8Umr9Epp+vo45mvJ5vAcxdjyPpAfbylO/jbFs7QphQJfqSOBvqFQrYmNEqp0BfD/7PYz+CT3roBJzaq2vV0qtjjD8AcD+SqnfAkdrrZ/2Xz1o8LXrGmAzn0OxUmpuxEpsphsHUR+nddY8J1akf6S4iad9niGdfHnfRP7gaUiu+pnAVxz12ur3dXawM0VxKxujhdTjaoetjfkWId7rNyPq20bIV9jldRAi8WpJPa31y1rrXREV91Dkv7g/S3AzFLELvVmttkWcxU9F0iOsh52Bivgsosn0z44mZZ/KfEGbxp1IwijftmYV1TH0Dz8HURNjZNKwuDA81JdmVRAi0bCU+ZisCgOMRyIBdkLGbZMR6ZYvkNEVtdGGzHXpCKXUMcj/8hul1Apa68acihvCBTbv/UxSHQj8WCn1sNb6LMf1k5GJZ9uqNDcilu51CfBhVUo9hli/bbhKa71z4TjVWr9QVmeTlqn7kRCIhYGLgGXpPw5zdS4XTVEtLBujFc+7jCHmPTodr5VJoCWR2LD7kPz90xHGW87zHD7UZk6t9fuI9/ljwClKqRu01mX5CAcdWbsPVkotDhynlPqrI5xmEvCPzCBk1vGGUuq+jCbEWfx07IbCrfEvsOGEyWh1/shZiGpyB+LhvBbuXI2h0qyM2cxfEz6JZt7TJc2KZb7xmg0mzSqIkeQaJJvuRkhYic81rBEV0oTW+tQsvup3SqlltNahHh2Djdz/dUskmaqJScBlSqm1Hdc/RbknPwBaa1u8HEqpVajp1dKpRDsXseR8F1GNypKh2jpLiNGjamq3uoyW/4aokljKyxhiQ2SS/kykw+xN9aWgmsCJiGFqChIRMeShtX5NKfUAsLJ5LnMkXghhxO091bynlIoG4+NSN/DzQWQFl5cRUbxF4VyVL7JPYpTV5RtDlc2jhbTTx2RVnsvcRiFzXRcgWsDONLTiiVJqm0CvkFuRMUuVZYGHAh7A3uZ1kXSDy+AxSCDGkjUGpKUGbBLN90V+Cwnu60GCC+ejvxSrksqtTJrVURuhXKIV7+ljcrOseOxTJ0Ok7zhEHXoJCY9fDAkFGuOoL6TOI4GjkQ+hE1rrWUqpJxFDVRP4D9LuEMxNuAOyidfpvywTCKPdUTJ18UKW7GcSffOfzCa87WOo7pAAVJNof0YSruyEjMVcmaNCOkmZRMJzLmTrZTTJjuVLmOq6t68NtucIfQ8m7aLIFMCmiFta2aJ8PjyDLJgYgkUID20pw5uIw28IFkecyZvEusBNAXQ303+c9gzhoS9LIhmRK6OM0RQyI38EsCwyDvsY4Z2oWE9IR62i3vm2ouo4tsO6QhjTVb8LNtqJyNJEESKZngmsqwjXYn99by7Ot+ORJYWbwIuEx5gtgSyN3AiUUvMiyXj6rzveHzfR3xXracLbvjT+iXUnfBPW7yLeDU8hKs6aAfVVlWZmmasOHL+ua4qqo8uyZ7uurMzW/tBnDWWa9RHPktuROckqatajwIYBnuqbIOr/PRXq9mEmML9SalUfkVJqCaSz3tzQfUGSLI0iXKItrpQqeus8Aixf5heajX0Xxr/AhhMuRrsRuA7YBrFM9bmnZ7O20UET0pnL7udqw2jiKDfD2vKFhEipqkxW9ry+d2Lbtsi2v9Cb46MMv0I0jm+6CJRScyHpGs5ucJG+65EOWOa9sSfiXN7k/N06SLbkkFQK/0Q+XEX18UIkfcZeJdfuBzxOTSutyWjPIUy2CuLZEVHta+xjvtDOXZfBXFKt6lxVFUb0fThC3okLxWfYHFgW+WL7PNfRWj+FTLcckc359K1U0rydhfhfWueK6iCbVN4V+JpS6ns2GqXUdsBuwL6Zt0pTCB2fkflK3kVBfcyS8hwH/I9SyrqoYfZM2wOHBqxsakVudXwfYbLxhE3quTqLaXFUlnNmWVnH81kZffNtY5FBesgcWnHf9xsi5cwy2/OVMbWJhZAv978RVd5neNgbGaPeqZQ6H5GG7yAZsr6E/OdfaDq6Wmt9lVLqKOAEpdTWyAe7mKn4S0jex9ObumemIq+DZT1rD24GvmCUHYVYfWcopXZAJN+TSFqISYh718FIsK+JBbM06D68PRphstnIV9NEKEO5aKtORoe4XIVOXo8r/LqYyzzulMlCpbmv/T66xbLfN5H/rR+yr/Y3lFJXIGOx7RDL5h2IC9jJIb55BcxGkt2UQmt9gFLqPCQw76RmPAAABX9JREFUdhpimHkOcc+brLW2Ofz2ZPcIQUrf514RWIBAiZbhJuB7Sqn58rR82QT2nkqpa5C0GlsgUv8RRAL+n9b6akd9H0e0BB+eVnrT0ZsgGWRdEai2tchc5WXnzXJK9n2/5r55vDFJ+gBxNAXJaJyjLqPlvyFMZh6XlZfVZeJ2YA+S9AbH+RZDDHORpJcjY7K9sS/4HfI1Dv2Sm2V4zoVIC99xLtGaGKOFMobtuUPek4vGxL8RT5K1WiYbXhBjSJKmJOmxyIojp+JOv+XrbDYaV1lo561zbb65jCEhdZr3x0Hv2i/72LjOuZjvfWRu7ZMk6W9J0tD0aC2GCPpaHZP0JZL0u4g/2N8KZ0K/wGVf9aqdtZOtjtWx7P6h7Q59L7Z3apZfAqxEku7Xb4HFFsMG9nm0JL2LJF0fGRg+WTjj+wKHMlw3GMx2fc5otsQ8Td7P94xlHx5XO0AMCFNI0s1J0lqTpC2GDvwuWEn6J8SJ8yDsyUJDOo/v2DxXLDN/qzKKaXWsyqi++4cyoOsduT5KIJOn/wus9uFqpi2GPcqdipP0PZL0UMQqeWZWGtJxqjJGGU1IHXUZLeQ+WM6H7IcwmELGxScDnyBJTyBJa02MthiaCPfeT9JnSdLtkQm8WynvSL5j136dzXV9k54hZff1PY+tfeb7uhr4DEm6G0napNdEiyGC6oGfsvbzOsiC4C9Qzlw4zpu0Nqnho+lUooXWU0bre6ay9/E4srjHFJL0XlqMWNSLsE5STZL+EZmZPwKZ2Q+Vbua5JqRaHUYLaYPrOULa63sHbyERESuTpBfTYsSjbioDQZK+RZIeRG/ymarME0JTlxFzRpu3xrV12uXbp7B/OvBpkvRIktTqRtVi5KGZdHNJ+gSwNXG0PhKWnydQqerHWDxXxeHYBpevowkbMxT3zTKbZLOdM/dvAvYiSW/3tKXFCEVnEs1Ekl6HpJvbHXgFf8drQh0LkWhVrI6+9oW01/aszwI7kKTrtUw256JZRgNI0g9I0lOR0PwT6fX8Hki1EfpaHevW0Qnde0hm4JVJ0rMD316LEYrmGS1Hkr5Oku6DpEC4iuakWlkHz8ttqmNTjFxWz3nAKiTpISRp1VVBW4xAdH+xuiR9ENiMONoEcYxdoXC205gzH+Yt/JrMbEJV2Hd9GEAWPNiHJLXFXbWYg9E9iWZCwnE+gyzj9AbVpQQV6U1Gq1NH6PYiEsq/bstkLWwYOEaDPBznl4hV8nf0Sq5O1DTXVtcFq8p9UiRodmWS9Pdt+EoLF5TWTa05WANxtDqSWXcS5RHUZdmQzbIXEIY2Vx5pSn28FNifJG1y7eoWIxSDy2g54mgakpx1GewM5UtZ4Cp7E7F82tKQ2ZjNLLON6xSS/31fktSVQ6JFi34YWNXRBQnHWQ1JgfYufrXNVm4rG0dnaqNZ92tIuoe1WiZrURVDQ6IVEUdLIdLta4XSqmpjjjVxJx8tk2r5/gfIelw/bT3rW9TF0GO0HHG0DjJ+W5P6jDYFuNJxLoTRrkHM9ff7G9uihR9DQ3W0IUnzBQm+jZjP61gGF/Kc821PANNI0k1aJmvRBIYuo0EejjMdWXzuKPqG44Rsi3jOYSmbheSlX40kDVnruEWLIAxtRsuRpLNI0h8CqyNZoUIZbeFAOpAsviuTpEe14Sstmkb3XbCaRJI+DkwjjjZAwnEm4p4Xg15G86ENX2nRdQwPiWYiSa9BjCR7IFmj6qiOz9CGr7QYIAxPRoM8HOcUJB3eSYgZPoTR3gMOoQ1faTGAGLrm/aqIo4mI3+GXCqW3I1mXc5yLuE01tQBfixZBGDmMliOOpiLzbysA/0Lcum4H9mwXhmgxWBh5jAYQR3Mj47ftgBOA1rO+xaDi/wO7COZkDAUh8gAAAABJRU5ErkJggg==",remoteStorageCube:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAR2SURBVFiFtddfqGVVHQfwz2/vfZ28c2WgP6hMoYkUV4qIYnSKmaQYwaaJ3oLeUnpJmDCmUhCaIhhKGelhelCqN9+ECKdAxR6kgnJASBN9KTGwP2oKTtyZs8/+9bDXPufcfe51xju6YLHX2fu3ft/v+q7fWb/fisy0o3brez6qmt4Luvo7frvx/E7cxNsmcCj2WGnuEb6JaXlbSz8zaX/ksXzj3SHwg6j8aeU28jjeh8TZ8nU3Aq8Sx+2b/ML3s3vnCHxp5YB0Hz6OTkgpMax2jxBSoMJfhGMemTx5aQQOxzWsnCC/gm6hZ+mvFMv36xUYCJQev2Jyt9P54tsj8OVYNW2+izuxIkzlAoGUQuLlMuNqKcQCgVBJNSa4X93+xK/zfxcmcLj5GtUJ8ipMC/i0gA/PQYF/lFkfHClQFxJ1IVET/6S72+n2oa0JHL7s0+RPsR9tAZuOxuNtGKS9xpL8A7BmNP4j8S2nzz+lGJaWDxB7RyCbV54DkZiSrbAhbJBt/25LtUbEY2+P1bdmQY1V8mr8DruET5Z9n4NHTOmmZK9A2ihzp3RdL3tVy+z16OeG0ElncI48yGzeogIzQgexByelp2fMZ+CDAtFK56XzxFwBXSE6C9incbL4PDha9BKBPrjCddJRVT5DHsMLczkLUGhFbPR9iJNYjJUXyGOqfEY6KlxnHrybVjwm0JVDJmV8FZ8TeZysZdyBK9FKXb/6mdTZ+4uXRXcKUxnHpavKdqV58G5JYJFdLvT3yuok3ROiuY3JZ3Rxu7CH7lxvHlPpNVX+nJU/yMk9VJ8nm5GvMc42W6Bwnhl2KRyQ7cOyaqy1R0ScEvFq6aestUdk1cj2YeEA3RwwtwbfSoHtxxmJXeS3nV25RR0/9KnJL8GZyz7i7MoD5MfQ9LZ5YZ+WY+AiW16vc8if/av8PkRevxNPiwTiLceRISPIM3iUOGxa/wfUbiTvxy3ETb3tRfi0HAMx+xgLY1XIeAUPYoO4S+YNqupyVXW5zBuIu/pvHuxtq5j5DLHkfxsFxoaBlN1vVKbEN2TQ5wdYLc8++YibhZvJx3VZizgy8rVEYhwDfUKZFxd/Jf8m4gsydtENJ17TZ8lcLbOGrFfJrKmOiDxHPk58GJ8oPqu3UmDOLr2B5/AhYt08K9Z9AMdAsCeQml6BnKdiriC+iP/iKWkdH7gQgSRfQoi4SWoLcMqsRaUcZiX1xu4yrZmpp6p721lavlLYK/PfeIm4djsCE7xZDNqSVocV9evNJCKIjq6TuTbbAlWvQGZfiCwWJqkqqb7pMUwG0IV/QXwdz1ouKjZXOP021EQjqt2i2k00/Tv1Evj8OfRnC1aPeokl2e/LrM/aYUk2Pgc43T6knqzjBCZytqqhpGpK0DXCmrC26d1Qgs3BJzihnqyPwbdWYJMaFyzLnyuW6yMFLrEsH7ftLyZ/LxbX7vRisrwFW7VHJk/a1+4njuL1udx5Rd9nW/A6cdS+dv/FgHPpl9PhorH67l9Ox62/nv8YdPX3dno9/z+G+TGrzjgPKwAAAABJRU5ErkJggg==",widgetCss:"#remotestorage-state { position:fixed; top:15px; right:15px; height:32px; width:275px; font:normal 16px/100% sans-serif; z-index:99999; background:rgba(0,0,0,.3); padding:5px; border-radius:7px; box-shadow:0 1px rgba(255,255,255,.05), inset 0 1px rgba(0,0,0,.05); transition:width 500ms, background 500ms; }\n#remotestorage-state.connected, #remotestorage-state.busy, #remotestorage-state.offline { width:32px; background:none; box-shadow:none; }\n.remotestorage-button { margin:0; padding:.3em; font-size:14px; height:26px !important; background:#ddd; color:#333; border:1px solid #ccc; border-radius:3px; box-shadow:0 1px 1px #fff inset; }\n#remotestorage-register-button { position:absolute; left:25px; top:8px; max-height:16px; text-decoration:none; font-weight:normal; }\n#remotestorage-connect-button { position:absolute; right:8px; top:8px; padding:0 0 0 17px; width:90px; cursor:pointer; text-align:left; border-radius:0 3px 3px 0; font-weight:normal; }\n#remotestorage-connect-button:hover, #remotestorage-connect-button:focus, .remotestorage-button:hover, .remotestorage-button:focus { background:#eee; color:#000; text-decoration:none; }\n#remotestorage-useraddress { position:absolute; left:25px; top:8px; margin:0; padding:0 17px 0 3px; height:25px; width:142px; background:#eee; color:#333; border:0; border-radius:3px 0 0 3px; box-shadow:0 1px #fff, inset 0 1px #999; font-weight:normal; font-size:14px;}\n#remotestorage-useraddress:hover, #remotestorage-useraddress:focus { background:#fff; color:#000; }\n#remotestorage-cube { position:absolute; right:84px; -webkit-transition:right 500ms; -moz-transition:right 500ms; transition:right 500ms; z-index:99997; }\n#remotestorage-questionmark { position:absolute; left:0; padding:9px 8px; color:#fff; text-decoration:none; z-index:99999; font-weight:normal; }\n.infotext { position:absolute; left:0; top:0; width:255px; height:32px; padding:6px 5px 4px 25px; font-size:10px; background:black; color:white; border-radius:7px; opacity:.85; text-decoration:none; white-space:nowrap; z-index:99998; }\n#remotestorage-questiomark:hover { color:#fff; }\n#remotestorage-questionmark:hover+#remotestorage-infotext { display:inline; }\n#remotestorage-state.busy #remotestorage-cube, #remotestorage-state.connecting #remotestorage-cube {   -webkit-animation-name:remotestorage-loading; -webkit-animation-duration:2s; -webkit-animation-iteration-count:infinite; -webkit-animation-timing-function:linear;\n   -moz-animation-name:remotestorage-loading; -moz-animation-duration:2s; -moz-animation-iteration-count:infinite; -moz-animation-timing-function:linear;\n   -o-animation-name:remotestorage-loading; -o-animation-duration:2s; -o-animation-iteration-count:infinite; -o-animation-timing-function:linear;\n   -ms-animation-name:remotestorage-loading; -ms-animation-duration:2s; -ms-animation-iteration-count:infinite; -ms-animation-timing-function:linear; }\n   @-webkit-keyframes remotestorage-loading { from{-webkit-transform:rotate(0deg)} to{-webkit-transform:rotate(360deg)} }\n   @-moz-keyframes remotestorage-loading { from{-moz-transform:rotate(0deg)} to{-moz-transform:rotate(360deg)} }\n   @-o-keyframes remotestorage-loading { from{-o-transform:rotate(0deg)} to{-o-transform:rotate(360deg)} }\n   @-ms-keyframes remotestorage-loading { from{-ms-transform:rotate(0deg)} to{ -ms-transform:rotate(360deg)} }\n#remotestorage-connect-button, #remotestorage-questionmark, #remotestorage-register-button, #remotestorage-cube, #remotestorage-useraddress, #remotestorage-infotext, #remotestorage-devsonly, #remotestorage-disconnect { display:none }\n#remotestorage-state.anonymous #remotestorage-cube, #remotestorage-state.anonymous #remotestorage-connect-button, #remotestorage-state.anonymous #remotestorage-register-button, #remotestorage-state.anonymous #remotestorage-questionmark { display: block }\n#remotestorage-state.registering #remotestorage-cube, #remotestorage-state.registering #remotestorage-connect-button, #remotestorage-state.registering #remotestorage-register-button, #remotestorage-state.registering #remotestorage-questionmark { display: block }\n#remotestorage-state.interrupted #remotestorage-cube, #remotestorage-state.interrupted #remotestorage-connect-button, #remotestorage-state.interrupted #remotestorage-register-button, #remotestorage-state.interrupted #remotestorage-questionmark { display: block }\n#remotestorage-state.failed #remotestorage-cube, #remotestorage-state.failed #remotestorage-connect-button, #remotestorage-state.failed #remotestorage-register-button, #remotestorage-state.failed #remotestorage-questionmark { display: block }\n#remotestorage-state.typing #remotestorage-cube, #remotestorage-state.typing #remotestorage-connect-button, #remotestorage-state.typing #remotestorage-useraddress, #remotestorage-state.typing #remotestorage-questionmark { display: block }\n#remotestorage-state.connected #remotestorage-cube, #remotestorage-state.busy #remotestorage-cube, #remotestorage-state.offline #remotestorage-cube { right:0; opacity:.5; cursor:pointer; display: block }\n#remotestorage-state.devsonly #remotestorage-devsonly { display: block }\n#remotestorage-disconnect { position:absolute; right:6px; top:9px; padding:5px 28px 2px 6px; height:17px; white-space:nowrap; font-size:10px; background:#000; color:#fff; border-radius:5px; opacity:.5; text-decoration:none; z-index:99996; }\n#remotestorage-disconnect strong { font-weight:bold; }\n#remotestorage-state.connected #remotestorage-cube:hover, #remotestorage-state.busy #remotestorage-cube:hover, #remotestorage-state.offline #remotestorage-cube:hover { opacity:1; }\n#remotestorage-state.connected #remotestorage-disconnect:hover, #remotestorage-state.busy #remotestorage-disconnect:hover, #remotestorage-state.offline #remotestorage-disconnect:hover { display:inline; }\n#remotestorage-state.connected #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.busy #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.offline #remotestorage-cube:hover+#remotestorage-disconnect { display:inline; }\n"}}),define("lib/util",[],function(){var loggers={},silentLogger={},knownLoggers=["sync","webfinger","getputdelete","platform","baseClient"],util={toArray:function(enumerable){var a=[];for(var i in enumerable)a.push(enumerable[i]);return a},getLogger:function(name){return loggers[name]||(loggers[name]={info:function(){this.log("info",util.toArray(arguments))},debug:function(){this.log("debug",util.toArray(arguments),"debug")},error:function(){this.log("error",util.toArray(arguments),"error")},log:function(level,args,type){if(silentLogger[name])return;type||(type="log"),args.unshift("["+name.toUpperCase()+"] -- "+level+" "),(console[type]||console.log).apply(console,args)}}),loggers[name]},silenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)silentLogger[names[i]]=!0},unsilenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)delete silentLogger[names[i]]},silenceAllLoggers:function(){this.silenceLogger.apply(this,knownLoggers)},unsilenceAllLoggers:function(){this.unsilenceLogger.apply(this,knownLoggers)}};return util}),define("lib/platform",["./util"],function(util){function browserParseHeaders(rawHeaders){var headers={},lines=rawHeaders.split(/\r?\n/),lastKey=null,md,key,value;for(var i=0;i<lines.length;i++){if(lines[i].length==0)continue;(md=lines[i].match(/^([^:]+):\s*(.+)$/))?(key=md[1],value=md[2],headers[key]=value,lastKey=key):(md=lines[i].match(/^\s+(.+)$/))?(key=lastKey,value=md[1],headers[key]=headers[key]+value):logger.error("Failed to parse header line: "+lines[i])}return headers}function ajaxBrowser(params){var timedOut=!1,timer;params.timeout&&(timer=window.setTimeout(function(){timedOut=!0,params.error("timeout")},params.timeout));var xhr=new XMLHttpRequest;params.method||(params.method="GET"),xhr.open(params.method,params.url,!0);if(params.headers)for(var header in params.headers)xhr.setRequestHeader(header,params.headers[header]);logger.debug("A "+params.url),xhr.onreadystatechange=function(){xhr.readyState==4&&!timedOut&&(logger.debug("B "+params.url),timer&&window.clearTimeout(timer),logger.debug("xhr cb "+params.url),xhr.status==200||xhr.status==201||xhr.status==204||xhr.status==207?params.success(xhr.responseText,browserParseHeaders(xhr.getAllResponseHeaders())):params.error(xhr.status))},logger.debug("xhr "+params.url),typeof params.data=="string"?xhr.send(params.data):xhr.send()}function ajaxExplorer(params){var xdr=new XDomainRequest;xdr.timeout=params.timeout||3e3,xdr.open(params.method,params.url),xdr.onload=function(){xdr.status==200||xdr.status==201||xdr.status==204?params.success(xhr.responseText):params.error(xhr.status)},xdr.onerror=function(){err("unknown error")},xdr.ontimeout=function(){err(timeout)},params.data?xdr.send(params.data):xdr.send()}function ajaxNode(params){function normalizeHeaders(headers){var h={};for(var key in headers)h[key.replace(/(?:^|\-)[a-z]/g,function(match){return match.toUpperCase()})]=headers[key];return h}var http=require("http"),https=require("https"),url=require("url");params.method||(params.method="GET"),params.data?params.headers["content-length"]=params.data.length:params.data=null;var urlObj=url.parse(params.url),options={method:params.method,host:urlObj.hostname,path:urlObj.path,port:urlObj.port?port:urlObj.protocol=="https:"?443:80,headers:params.headers},timer,timedOut;params.timeout&&(timer=setTimeout(function(){params.error("timeout"),timedOut=!0},params.timeout));var lib=urlObj.protocol=="https:"?https:http,request=lib.request(options,function(response){var str="";response.setEncoding("utf8"),response.on("data",function(chunk){str+=chunk}),response.on("end",function(){timer&&clearTimeout(timer),timedOut||(response.statusCode==200||response.statusCode==201||response.statusCode==204?params.success(str,normalizeHeaders(response.headers)):params.error(response.statusCode))})});request.on("error",function(e){timer&&clearTimeout(timer),params.error(e.message)}),params.data?request.end(params.data):request.end()}function parseXmlBrowser(str,cb){var tree=(new DOMParser).parseFromString(str,"text/xml"),nodes=tree.getElementsByTagName("Link"),obj={Link:[]};for(var i=0;i<nodes.length;i++){var link={};if(nodes[i].attributes)for(var j=0;j<nodes[i].attributes.length;j++)link[nodes[i].attributes[j].name]=nodes[i].attributes[j].value;var props=nodes[i].getElementsByTagName("Property");link.properties={},xyz=props;for(var k=0;k<props.length;k++)link.properties[props[k].getAttribute("type")]=props[k].childNodes[0].nodeValue;link.rel&&obj.Link.push({"@":link})}cb(null,obj)}function parseXmlNode(str,cb){var xml2js=require("xml2js");(new xml2js.Parser).parseString(str,cb)}function harvestParamNode(){}function harvestParamBrowser(param){if(location.hash.length){var pairs=location.hash.substring(1).split("&");for(var i=0;i<pairs.length;i++)if(pairs[i].substring(0,(param+"=").length)==param+"="){var ret=decodeURIComponent(pairs[i].substring((param+"=").length));return delete pairs[i],location="#"+pairs.join("&"),ret}}}function setElementHtmlNode(eltName,html){}function setElementHtmlBrowser(eltName,html){var elt=eltName;elt instanceof Element||(elt=document.getElementById(eltName)),elt.innerHTML=html}function getElementValueNode(eltName){}function getElementValueBrowser(eltName){return document.getElementById(eltName).value}function eltOnNode(eltName,eventType,cb){}function eltOnBrowser(eltName,eventType,cb){eventType=="click"?document.getElementById(eltName).onclick=cb:eventType=="hover"?document.getElementById(eltName).onmouseover=cb:eventType=="type"&&(document.getElementById(eltName).onkeyup=cb)}function getLocationBrowser(){return window.location.href.split("#")[0]}function getLocationNode(){}function setLocationBrowser(location){window.location=location}function setLocationNode(){}function alertBrowser(str){alert(str)}function alertNode(str){console.log(str)}var logger=util.getLogger("platform");return typeof window=="undefined"?{ajax:ajaxNode,parseXml:parseXmlNode,harvestParam:harvestParamNode,setElementHTML:setElementHtmlNode,getElementValue:getElementValueNode,eltOn:eltOnNode,getLocation:getLocationNode,setLocation:setLocationNode,alert:alertNode}:window.XDomainRequest?{ajax:ajaxExplorer,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}:{ajax:ajaxBrowser,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}}),define("lib/webfinger",["./platform","./util"],function(platform,util){function userAddress2hostMetas(userAddress,cb){var parts=userAddress.toLowerCase().split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9a-z\-\_]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9a-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{var query="?resource=acct:"+encodeURIComponent(userAddress);cb(null,["https://"+parts[1]+"/.well-known/host-meta.json"+query,"https://"+parts[1]+"/.well-known/host-meta"+query,"http://"+parts[1]+"/.well-known/host-meta.json"+query,"http://"+parts[1]+"/.well-known/host-meta"+query])}}function fetchXrd(addresses,timeout,cb){var firstAddress=addresses.shift();firstAddress?platform.ajax({url:firstAddress,success:function(data){parseAsJrd(data,function(err,obj){err?parseAsXrd(data,function(err,obj){err?fetchXrd(addresses,timeout,cb):cb(null,obj)}):cb(null,obj)})},error:function(data){fetchXrd(addresses,timeout,cb)},timeout:timeout}):cb("could not fetch xrd")}function parseAsXrd(str,cb){platform.parseXml(str,function(err,obj){if(err)cb(err);else if(obj&&obj.Link){var links={};if(obj.Link&&obj.Link["@"])obj.Link["@"].rel&&(links[obj.Link["@"].rel]=obj.Link["@"]);else for(var i=0;i<obj.Link.length;i++)obj.Link[i]["@"]&&obj.Link[i]["@"].rel&&(links[obj.Link[i]["@"].rel]=obj.Link[i]["@"]);cb(null,links)}else cb("found valid xml but with no Link elements in there")})}function parseAsJrd(str,cb){var obj;try{obj=JSON.parse(str)}catch(e){cb("not valid JSON");return}obj.links||cb("JRD contains no links");var links={};for(var i=0;i<obj.links.length;i++)obj.links[i].rel&&(links[obj.links[i].rel]=obj.links[i]);cb(null,links)}function parseRemoteStorageLink(obj,cb){obj&&obj.href&&obj.type&&obj.properties&&obj.properties["auth-endpoint"]?cb(null,obj):cb("could not extract storageInfo from lrdd")}function getStorageInfo(userAddress,options,cb){userAddress2hostMetas(userAddress,function(err1,hostMetaAddresses){logger.debug("HOST META ADDRESSES",hostMetaAddresses,"(error: ",err1,")"),err1?cb(err1):fetchXrd(hostMetaAddresses,options.timeout,function(err2,hostMetaLinks){if(err2)cb("could not fetch host-meta for "+userAddress);else if(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage)parseRemoteStorageLink(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage,cb);else if(hostMetaLinks.lrdd&&hostMetaLinks.lrdd.template){var parts=hostMetaLinks.lrdd.template.split("{uri}"),lrddAddresses=[parts.join("acct:"+userAddress),parts.join(userAddress)];fetchXrd(lrddAddresses,options.timeout,function(err4,lrddLinks){err4?cb("could not fetch lrdd for "+userAddress):lrddLinks.remoteStorage?parseRemoteStorageLink(lrddLinks.remoteStorage,cb):lrddLinks.remotestorage?parseRemoteStorageLink(lrddLinks.remotestorage,cb):cb("could not extract storageInfo from lrdd")})}else cb("could not extract lrdd template from host-meta")})})}var logger=util.getLogger("webfinger");return{getStorageInfo:getStorageInfo}}),define("lib/hardcoded",["./platform"],function(platform){function testIrisCouch(userAddress,options,cb){platform.ajax({url:"http://proxy.unhosted.org/irisCouchCheck?q=acct:"+userAddress,success:function(data){var obj;try{obj=JSON.parse(data)}catch(e){}obj?cb(null,obj):cb("err: unparsable response from IrisCouch check")},error:function(err){cb("err: during IrisCouch test:"+err)},timeout:options.timeout})}function mapToIrisCouch(userAddress){var parts=userAddress.split("@");return["libredocs","mail","browserid","me"].indexOf(parts[0])==-1?parts[0]+"@iriscouch.com":parts[2].substring(0,parts[2].indexOf("."))+"@iriscouch.com"}function guessStorageInfo(userAddress,options,cb){var parts=userAddress.split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9A-Za-z]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9A-Za-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{while(parts[1].indexOf(".")!=-1){if(guesses[parts[1]]){blueprint=guesses[parts[1]],cb(null,{rel:"https://www.w3.org/community/unhosted/wiki/personal-data-service-00",type:blueprint.type,href:blueprint.hrefPrefix+"/"+(blueprint.pathFormat=="user@host"?userAddress:parts[1]+"/"+parts[0]),properties:{"access-methods":["http://oauth.net/core/1.0/parameters/auth-header"],"auth-methods":["http://oauth.net/discovery/1.0/consumer-identity/static"],"auth-endpoint":blueprint.authPrefix+userAddress}});return}parts[1]=parts[1].substring(parts[1].indexOf(".")+1)}new Date<new Date("9/9/2012")?testIrisCouch(userAddress,options,cb):cb("err: not a guessable domain, and fakefinger-migration has ended")}}var guesses={"iriscouch.com":{type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#couchdb",authPrefix:"http://proxy.unhosted.org/OAuth.html?userAddress=",hrefPrefix:"http://proxy.unhosted.org/CouchDb",pathFormat:"host/user"}};return function(){var surfnetSaml={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/saml/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/saml",pathFormat:"user@host"},surfnetBrowserId={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/browserid/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/browserid",pathFormat:"user@host"},dutchUniversitiesNoSaml=["leidenuniv.nl","leiden.edu","uva.nl","vu.nl","eur.nl","maastrichtuniversity.nl","ru.nl","rug.nl","uu.nl","tudelft.nl","utwente.nl","tue.nl","tilburguniversity.edu","uvt.nl","wur.nl","wageningenuniversity.nl","ou.nl","lumc.nl","amc.nl","ahk.nl","cah.nl","driestar.nl","che.nl","chn.nl","hen.nl","huygens.nl","diedenoort.nl","efa.nl","dehaagsehogeschool.nl","hasdenbosch.nl","inholland.nl","hsbrabant.nl","dehorst.nl","kempel.nl","domstad.nl","hsdrenthe.nl","edith.nl","hsleiden.nl","interport.nl","schumann.nl","hsbos.nl","hva.nl","han.nl","hvu.nl","hesasd.nl","hes-rdam.nl","hku.nl","hmtr.nl","hzeeland.nl","hotelschool.nl","ichtus-rdam.nl","larenstein.nl","iselinge.nl","koncon.nl","kabk.nl","lhump.nl","msm.nl","hsmarnix.nl","nhtv.nl","nth.nl","nhl.nl","sandberg.nl","hsij.nl","stoas.nl","thrijswijk.nl","tio.nl","vhall.nl","chw.nl","hogeschoolrotterdam.nl"],dutchUniversitiesSaml=["surfnet.nl","fontys.nl"];for(var i=0;i<dutchUniversitiesSaml.length;i++)guesses[dutchUniversitiesSaml[i]]=surfnetSaml;for(var i=0;i<dutchUniversitiesNoSaml.length;i++)guesses[dutchUniversitiesNoSaml[i]]=surfnetBrowserId}(),{guessStorageInfo:guessStorageInfo}}),define("lib/getputdelete",["./platform","./util"],function(platform,util){function doCall(method,url,value,mimeType,token,cb,deadLine){var platformObj={url:url,method:method,error:function(err){cb(err)},success:function(data,headers){logger.debug("doCall cb "+url,"headers:",headers),cb(null,data,headers["Content-Type"]||defaultContentType)},timeout:3e3};platformObj.headers={Authorization:"Bearer "+token},mimeType&&(platformObj.headers["Content-Type"]=mimeType),platformObj.fields={withCredentials:"true"},method!="GET"&&(platformObj.data=value),logger.debug("platform.ajax "+url),platform.ajax(platformObj)}function get(url,token,cb){doCall("GET",url,null,null,token,function(err,data,mimetype){if(err==404)cb(null,undefined);else{if(url.substr(-1)=="/")try{data=JSON.parse(data)}catch(e){cb("unparseable directory index");return}cb(err,data,mimetype)}})}function put(url,value,mimeType,token,cb){logger.info("calling PUT "+url),doCall("PUT",url,value,mimeType,token,function(err,data){logger.debug("cb from PUT "+url),err==404?doPut(url,value,token,1,cb):cb(err,data)})}function set(url,valueStr,mimeType,token,cb){typeof valueStr=="undefined"?doCall("DELETE",url,null,null,token,cb):put(url,valueStr,mimeType,token,cb)}var logger=util.getLogger("getputdelete"),defaultContentType="application/octet-stream";return{get:get,set:set}}),define("lib/wireClient",["./getputdelete"],function(getputdelete){function set(key,value){localStorage.setItem(prefix+key,JSON.stringify(value))}function remove(key){localStorage.removeItem(prefix+key)}function get(key){var valStr=localStorage.getItem(prefix+key);if(typeof valStr=="string")try{return JSON.parse(valStr)}catch(e){localStorage.removeItem(prefix+key)}return null}function disconnectRemote(){remove("storageType"),remove("storageHref"),remove("bearerToken")}function getState(){return get("storageType")&&get("storageHref")?get("bearerToken")?"connected":"authing":"anonymous"}function on(eventType,cb){eventType=="error"&&(errorHandler=cb)}function resolveKey(storageType,storageHref,basePath,relPath){var item=(basePath.length?basePath+"/":"")+relPath;return storageHref+item}function setChain(driver,hashMap,mimeType,token,cb,timestamp){var i;for(i in hashMap)break;if(i){var thisOne=hashMap[i];delete hashMap[i],driver.set(i,thisOne,mimeType,token,function(err,timestamp){err?cb(err):setChain(driver,hashMap,mimeType,token,cb,timestamp)})}else cb(null,timestamp)}var prefix="remote_storage_wire_",errorHandler=function(){};return{get:function(path,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.get(resolveKey(storageType,storageHref,"",path),token,cb)},set:function(path,valueStr,mimeType,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.set(resolveKey(storageType,storageHref,"",path),valueStr,mimeType,token,cb)},setStorageInfo:function(type,href){set("storageType",type),set("storageHref",href)},getStorageHref:function(){return get("storageHref")},setBearerToken:function(bearerToken){set("bearerToken",bearerToken)},disconnectRemote:disconnectRemote,on:on,getState:getState}}),define("lib/store",["./util"],function(util){function fireChange(e){for(var i=0;i<onChange.length;i++)onChange[i](e)}function getNode(path){var valueStr=localStorage.getItem(prefixNodes+path),value;if(valueStr)try{value=JSON.parse(valueStr)}catch(e){}return value||(value={startAccess:null,startForce:null,timestamp:0,keep:!0,diff:{}}),value}function isDir(path){return typeof path!="string"&&(logger.error("Given path is not a string: ",path),doSomething()),path.substr(-1)=="/"}function getContainingDir(path){var parts=path.split("/");return parts[parts.length-1].length||parts.pop(),parts.length?(parts.pop(),parts.join("/")+(parts.length?"/":"")):undefined}function getFileName(path){var parts=path.split("/");return isDir(path)?parts[parts.length-2]+"/":parts[parts.length-1]}function getCurrTimestamp(){return(new Date).getTime()}function updateNode(path,node,outgoing,meta,timestamp){node?localStorage.setItem(prefixNodes+path,JSON.stringify(node)):localStorage.removeItem(prefixNodes+path);var containingDir=getContainingDir(path);if(containingDir){var parentNode=getNode(containingDir),parentData=getNodeData(parentNode)||{};if(meta){if(!parentData||!parentData[getFileName(path)])parentData[getFileName(path)]=0;updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!0)}else if(outgoing)node?parentData[getFileName(path)]=(new Date).getTime():delete parentData[getFileName(path)],parentNode.diff[getFileName(path)]=(new Date).getTime(),updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!0);else{if(node){if(!parentData[getFileName(path)]||parentData[getFileName(path)]<timestamp)parentData[getFileName(path)]=timestamp,delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp)}else parentData[getFileName(path)]&&(delete parentData[getFileName(path)],delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp));path.substr(-1)!="/"&&fireChange({path:path,origin:"remote",oldValue:undefined,newValue:node?getNodeData(node):undefined,timestamp:timestamp})}}}function forget(path){localStorage.removeItem(prefixNodes+path)}function forgetAll(){for(var i=0;i<localStorage.length;i++)localStorage.key(i).substr(0,prefixNodes.length)==prefixNodes&&(localStorage.removeItem(localStorage.key(i)),i--)}function on(eventName,cb){if(eventName!="change")throw"Unknown event: "+eventName;onChange.push(cb)}function getState(path){return"disconnected"}function updateNodeData(path,data){if(!path)throw console.trace(),"Path is required!";var encodedData;try{encodedData=JSON.stringify(data)}catch(exc){encodedData=data}localStorage.setItem(prefixNodesData+path,encodedData)}function setNodeData(path,data,outgoing,timestamp,mimeType){var node=getNode(path);mimeType||(mimeType="application/json"),node.mimeType=mimeType,timestamp||(timestamp=(new Date).getTime()),updateNodeData(path,data),updateNode(path,data?node:undefined,outgoing,!1,timestamp)}function getNodeData(path){typeof path=="object"&&(path=path.path);var valueStr=localStorage.getItem(prefixNodesData+path);if(!valueStr)return undefined;try{return JSON.parse(valueStr)}catch(exc){return valueStr}}function setNodeAccess(path,claim){var node=getNode(path);claim!=node.startAccess&&(claim=="rw"||node.startAccess==null)&&(node.startAccess=claim,updateNode(path,node,!1,!0))}function setNodeForce(path,force){var node=getNode(path);node.startForce=force,updateNode(path,node,!1,!0)}function clearDiff(path,i){var node=getNode(path);delete node.diff[i],updateNode(path,node,!1,!0)}var logger=util.getLogger("store"),onChange=[],prefixNodes="remote_storage_nodes:",prefixNodesData="remote_storage_node_data:";return typeof window!="undefined"&&window.addEventListener("storage",function(e){e.key.substring(0,prefixNodes.length==prefixNodes)&&(e.path=e.key.substring(prefixNodes.length),isDir(e.path)||(e.origin="device",fireChange(e)))}),{on:on,getNode:getNode,getNodeData:getNodeData,setNodeData:setNodeData,setNodeAccess:setNodeAccess,setNodeForce:setNodeForce,clearDiff:clearDiff,forget:forget,forgetAll:forgetAll}}),define("lib/sync",["./wireClient","./store","./util"],function(wireClient,store,util){function getState(path){return busy?"busy":"connected"}function setBusy(val){busy=val;for(var i=0;i<stateCbs.length;i++)stateCbs[i](val?"busy":"connected")}function on(eventType,cb){eventType=="state"&&stateCbs.push(cb)}function dirMerge(dirPath,remote,cached,diff,force,access,startOne,finishOne,clearCb){for(var i in remote)(!cached[i]&&!diff[i]||cached[i]<remote[i])&&pullNode(dirPath+i,force,access,startOne,finishOne);for(var i in cached)if(!remote[i]||cached[i]>remote[i])if(i.substr(-1)=="/")pullNode(dirPath+i,force,access,startOne,finishOne);else{var childNode=store.getNode(dirPath+i),childData=store.getNodeData(dirPath+i);startOne(),typeof childData=="object"&&(childData=JSON.stringify(childData)),wireClient.set(dirPath+i,childData,"application/json",function(err){finishOne()})}for(var i in diff)cached[i]?remote[i]===cached[i]&&clearCb(i):remote[i]?(startOne(),wireClient.set(dirPath+i,undefined,undefined,function(err){finishOne()})):clearCb(i)}function pullNode(path,force,access,startOne,finishOne){var thisNode=store.getNode(path),thisData=store.getNodeData(path);!thisData&&path.substr(-1)=="/"&&(thisData={}),logger.debug("pullNode "+path,thisNode);if(thisNode.startAccess=="rw"||!access)access=thisNode.startAccess;thisNode.startForce&&(force=thisNode.startForce);if(access)startOne(),wireClient.get(path,function(err,data){!err&&data&&(path.substr(-1)=="/"?dirMerge(path,data,thisData,thisNode.diff,force,access,startOne,finishOne,function(i){store.clearDiff(path,i)}):store.setNodeData(path,data,!1)),finishOne(err)});else for(var i in thisData)i.substr(-1)=="/"&&pullNode(path+i,force,access,startOne,finishOne)}function fetchNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(err),outstanding--,outstanding==0&&(setBusy(!1),callback(errors||null,store.getNode(path)))}var outstanding=0,errors=[];setBusy(!0),pullNode(path,!1,!0,startOne,finishOne)}function syncNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(path),outstanding--,outstanding==0&&(setBusy(!1),callback&&callback(errors.length>0?errors:null))}if(wireClient.getState()=="anonymous"){callback&&callback(["not connected"]);return}var outstanding=0,errors=[];logger.info("syncNow "+path),setBusy(!0),pullNode(path,!1,!1,startOne,finishOne)}var prefix="_remoteStorage_",busy=!1,stateCbs=[],logger=util.getLogger("sync");return{syncNow:syncNow,fetchNow:fetchNow,getState:getState,on:on}}),define("lib/widget",["./assets","./webfinger","./hardcoded","./wireClient","./sync","./store","./platform"],function(assets,webfinger,hardcoded,wireClient,sync,store,platform){function translate(text){return text}function isRegistering(){return localStorage.getItem("remote_storage_registering")}function setRegistering(value){value===!1?localStorage.removeItem("remote_storage_registering"):localStorage.setItem("remote_storage_registering","true")}function calcWidgetStateOnLoad(){wc=wireClient;if(isRegistering())return"registering";var wireClientState=wireClient.getState();return wireClientState=="connected"?sync.getState():wireClientState}function setWidgetStateOnLoad(){setWidgetState(calcWidgetStateOnLoad())}function setWidgetState(state){widgetState=state,displayWidgetState(state,userAddress)}function getWidgetState(){return widgetState}function displayWidgetState(state,userAddress){var userAddress=localStorage.remote_storage_widget_useraddress,html="<style>"+assets.widgetCss+"</style>"+'<div id="remotestorage-state" class="'+state+'">'+'  <input id="remotestorage-connect-button" class="remotestorage-button" type="submit" value="'+translate("connect")+'"/>'+'  <span id="remotestorage-register-button" class="remotestorage-button">'+translate("get remoteStorage")+"</span>"+'  <img id="remotestorage-cube" src="'+assets.remoteStorageCube+'"/>'+'  <span id="remotestorage-disconnect">Disconnect '+(userAddress?"<strong>"+userAddress+"</strong>":"")+"</span>"+'  <a id="remotestorage-questionmark" href="http://unhosted.org/#remotestorage" target="_blank">?</a>'+'  <span class="infotext" id="remotestorage-infotext">This app allows you to use your own data storage!<br/>Click for more info on the Unhosted movement.</span>'+'  <input id="remotestorage-useraddress" type="text" value="me@local.dev" placeholder="you@remotestorage" autofocus="" />'+'  <a class="infotext" href="http://remotestoragejs.com/" target="_blank" id="remotestorage-devsonly">RemoteStorageJs is still in developer preview!<br/>Click for more info.</a>'+"</div>";platform.setElementHTML(connectElement,html),platform.eltOn("remotestorage-register-button","click",handleRegisterButtonClick),platform.eltOn("remotestorage-connect-button","click",handleConnectButtonClick),platform.eltOn("remotestorage-disconnect","click",handleDisconnectClick),platform.eltOn("remotestorage-cube","click",handleCubeClick),platform.eltOn("remotestorage-useraddress","type",handleWidgetTypeUserAddress)}function handleRegisterButtonClick(){setRegistering();var win=window.open("http://unhosted.org/en/a/register.html","Get your remote storage","resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=820,height=800,top=0,left=0");setWidgetState("registering")}function redirectUriToClientId(loc){if(loc.substring(0,"http://".length)=="http://")loc=loc.substring("http://".length);else{if(loc.substring(0,"https://".length)!="https://")return loc;loc=loc.substring("https://".length)}var hostParts=loc.split("/")[0].split("@");return hostParts.length>2?loc:(hostParts.length==2&&hostParts.shift(),hostParts[0])}function dance(endpoint){var endPointParts=endpoint.split("?"),queryParams=[];endPointParts.length==2?queryParams=endPointParts[1].split("&"):endPointParts.length>2&&errorHandler("more than one questionmark in auth-endpoint - ignoring");var loc=platform.getLocation(),scopesArr=[];for(var i in scopesObj)scopesArr.push(i+":"+scopesObj[i]);queryParams.push("response_type=token"),queryParams.push("scope="+encodeURIComponent(scopesArr.join(" "))),queryParams.push("redirect_uri="+encodeURIComponent(loc)),queryParams.push("client_id="+encodeURIComponent(redirectUriToClientId(loc))),platform.setLocation(endPointParts[0]+"?"+queryParams.join("&"))}function discoverStorageInfo(userAddress,cb){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?hardcoded.guessStorageInfo(userAddress,{timeout:3e3},function(err2,data2){err2?cb(err2):data2.type&&data2.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data2.type,data2.href),cb(null,data2.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from webfinger")}):data.type&&data.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data.type,data.href),cb(null,data.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from hardcoded")})}function handleConnectButtonClick(){widgetState=="typing"?(userAddress=platform.getElementValue("remotestorage-useraddress"),localStorage.remote_storage_widget_useraddress=userAddress,setWidgetState("connecting"),discoverStorageInfo(userAddress,function(err,auth){err?(alert("webfinger discovery failed! (sorry this is still a developer preview! developers, point local.dev to 127.0.0.1, then run sudo node server/nodejs-example.js from the repo)"),setWidgetState("failed")):dance(auth)})):setWidgetState("typing")}function handleDisconnectClick(){widgetState=="connected"?(wireClient.disconnectRemote(),store.forgetAll(),setWidgetState("anonymous")):alert("you cannot disconnect now, please wait until the cloud is up to date...")}function handleCubeClick(){sync.syncNow("/",function(errors){})}function handleWidgetTypeUserAddress(){setRegistering(!1),console.log("handleWidgetTypeUserAddress")}function handleWidgetHover(){console.log("handleWidgetHover")}function display(setConnectElement,setLocale){var tokenHarvested=platform.harvestParam("access_token"),storageRootHarvested=platform.harvestParam("storage_root"),storageApiHarvested=platform.harvestParam("storage_api"),authorizeEndpointHarvested=platform.harvestParam("authorize_endpoint");tokenHarvested&&wireClient.setBearerToken(tokenHarvested),storageRootHarvested&&wireClient.setStorageInfo(storageApiHarvested?storageApiHarvested:"2012.04",storageRootHarvested),authorizeEndpointHarvested&&dance(authorizeEndpointHarvested),connectElement=setConnectElement,locale=setLocale,wireClient.on("error",function(err){platform.alert(translate(err))}),sync.on("state",setWidgetState),setWidgetStateOnLoad(),window.onkeydown=function(evt){if(evt.ctrlKey&&evt.which==83)return evt.preventDefault(),console.log("CTRL+S - SYNCING"),sync.syncNow("/",function(errors){}),!1}}function addScope(module,mode){if(!scopesObj[module]||mode=="rw")scopesObj[module]=mode}var locale="en",connectElement,widgetState,userAddress,scopesObj={};return{display:display,addScope:addScope,getState:getWidgetState}}),define("lib/baseClient",["./sync","./store","./util"],function(sync,store,util){function bindContext(callback,context){return context?function(){return callback.apply(context,arguments)}:callback}function extractModuleName(path){if(path&&typeof path=="string"){var parts=path.split("/");if(parts.length>3&&parts[1]=="public")return parts[2];if(parts.length>2)return parts[1]}}function fireChange(moduleName,eventObj){if(moduleName&&moduleChangeHandlers[moduleName])for(var i=0;i<moduleChangeHandlers[moduleName].length;i++)moduleChangeHandlers[moduleName][i](eventObj)}function fireError(str){for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](str)}function set(path,absPath,valueStr){if(isDir(absPath)){fireError("attempt to set a value to a directory "+absPath);return}var node=store.getNode(absPath),changeEvent={origin:"window",oldValue:store.getNodeData(node),newValue:valueStr,path:path},ret=store.setNodeData(absPath,valueStr,!0),moduleName=extractModuleName(absPath);return fireChange(moduleName,changeEvent),fireChange("root",changeEvent),ret}function claimAccess(path,claim){store.setNodeAccess(path,claim)}function isDir(path){return typeof path!="string"&&doSomething(),path.substr(-1)=="/"}var moduleChangeHandlers={},errorHandlers=[],logger=util.getLogger("baseClient");return store.on("change",function(e){var moduleName=extractModuleName(e.path);fireChange(moduleName,e),fireChange("root",e)}),{claimAccess:claimAccess,getInstance:function(moduleName,isPublic){function makePath(path){return moduleName=="root"?path:(isPublic?"/public/":"/")+moduleName+"/"+path}function nodeGivesAccess(path,mode){var node=store.getNode(path);logger.debug("check node access",path,mode,node);var access=(new RegExp(mode)).test(node.startAccess);if(access)return!0;if(path.length>0)return nodeGivesAccess(path.replace(/[^\/]+\/?$/,""))}function ensureAccess(mode){var path=makePath(moduleName=="root"?"/":"");if(!nodeGivesAccess(path,mode))throw"Not sufficient access claimed for node at "+path}return{on:function(eventType,cb,context){eventType=="change"?moduleName&&(moduleChangeHandlers[moduleName]||(moduleChangeHandlers[moduleName]=[]),moduleChangeHandlers[moduleName].push(bindContext(cb,context))):eventType=="error"&&errorHandlers.push(bindContext(cb,context))},getObject:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath);return data&&typeof data=="object"&&delete data["@type"],data}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node);data&&typeof data=="object"&&delete data["@type"],bindContext(cb,context)(data)})},getListing:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath),arr=[];for(var i in data)arr.push(i);return arr}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node),arr=[];for(var i in data)arr.push(i);bindContext(cb,context)(arr)})},getDocument:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath);return{mimeType:node.mimeType,data:store.getNodeData(node)}}sync.fetchNow(absPath,function(err,node){bindContext(cb,context)({mimeType:node.mimeType,data:store.getNodeData(node)})})},remove:function(path,cb,context){ensureAccess("w");var ret=set(path,makePath(path));return this.syncNow(cb,context),ret},storeObject:function(type,path,obj,cb,context){ensureAccess("w");if(typeof obj!="object")throw"storeObject needs to get an object as value!";obj["@type"]="https://remotestoragejs.com/spec/modules/"+moduleName+"/"+type;var ret=set(path,makePath(path),obj,"application/json");return this.sync(path),this.syncNow(cb,context),ret},storeDocument:function(mimeType,path,data,cb,context){ensureAccess("w");var ret=set(path,makePath(path),data,mimeType);return this.syncNow(cb,context),ret},getItemURL:function(path){var base=remoteStorage.getStorageHref();return base?(base.substr(-1)!="/"&&(base+="/"),base+makePath(path)):null},getCurrentWebRoot:function(){return"https://example.com/this/is/an/example/"+(isPublic?"public/":"")+moduleName+"/"},sync:function(path,switchVal){var absPath=makePath(path);store.setNodeForce(absPath,switchVal!=0)},syncNow:function(cb,context){sync.syncNow(makePath(""),cb?bindContext(cb,context):function(errors){errors&&errors.length>0&&(logger.error("Error syncing: ",errors),fireError(errors))})},getState:function(path){}}}}}),define("lib/nodeConnect",["./wireClient","./webfinger"],function(wireClient,webfinger){return{setUserAddress:function(userAddress,callback){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?console.error("Failed to look up storage info for user "+userAddress+": ",err):wireClient.setStorageInfo(data.type,data.href),callback(err)})},setStorageInfo:wireClient.setStorageInfo,setBearerToken:wireClient.setBearerToken}}),define("remoteStorage",["require","./lib/widget","./lib/baseClient","./lib/store","./lib/sync","./lib/wireClient","./lib/nodeConnect","./lib/util"],function(require,widget,baseClient,store,sync,wireClient,nodeConnect,util){function deprecate(oldFn,newFn){logger.error("DEPRECATION: "+oldFn+" is deprecated! Use "+newFn+" instead.")}var claimedModules={},modules={},logger=util.getLogger("base"),remoteStorage={defineModule:function(moduleName,builder){logger.debug("DEFINE MODULE",moduleName);var module=builder(baseClient.getInstance(moduleName,!1),baseClient.getInstance(moduleName,!0));modules[moduleName]=module,this[moduleName]=module.exports,logger.debug("Module defined: "+moduleName,module,this)},getModuleList:function(){return Object.keys(modules)},getClaimedModuleList:function(){return Object.keys(claimedModules)},getModuleInfo:function(moduleName){return modules[moduleName]},claimAccess:function(claimed){if(typeof claimed!="object"||claimed instanceof Array){claimed instanceof Array||(claimed=Array.prototype.slice.call(arguments));var _modules=claimed,mode="rw";claimed={};var lastArg=arguments[arguments.length-1];typeof lastArg=="string"&&lastArg.match(/^rw?$/)&&(mode=lastArg,delete arguments[arguments.length-1]);for(var i in _modules)claimed[_modules[i]]=mode}for(var moduleName in claimed)this.claimModuleAccess(moduleName,claimed[moduleName])},claimModuleAccess:function(moduleName,mode){logger.debug("claimModuleAccess",moduleName,mode);if(!moduleName in modules)throw"Module not defined: "+moduleName;if(moduleName in claimedModules)return;mode||(mode="r"),moduleName=="root"?(moduleName="",widget.addScope("",mode),baseClient.claimAccess("/",mode)):(widget.addScope(moduleName,mode),baseClient.claimAccess("/"+moduleName+"/",mode),baseClient.claimAccess("/public/"+moduleName+"/",mode)),claimedModules[moduleName]=!0},loadModule:function(){deprecate("remoteStorage.loadModule","remoteStorage.claimAccess"),this.claimModuleAccess.apply(this,arguments)},setBearerToken:function(bearerToken,claimedScopes){wireClient.setBearerToken(bearerToken),baseClient.claimScopes(claimedScopes)},disconnectRemote:wireClient.disconnectRemote,flushLocal:store.forgetAll,syncNow:sync.syncNow,displayWidget:widget.display,getWidgetState:widget.getState,setStorageInfo:wireClient.setStorageInfo,getStorageHref:wireClient.getStorageHref,nodeConnect:nodeConnect,util:util};return remoteStorage}),define("modules/root",["../remoteStorage"],function(remoteStorage){return remoteStorage.defineModule("public",function(client){function getPublicItems(){return client.getObject("publishedItems")}return{exports:{getPublicItems:getPublicItems,getObject:client.getObject}}}),remoteStorage.defineModule("root",function(myPrivateBaseClient,myPublicBaseClient){function setOnChange(cb){myPrivateBaseClient.on("change",function(e){console.log(e),cb(e)}),myPublicBaseClient.on("change",function(e){console.log(e),cb(e)})}function addToPublicItems(path){var data=myPublicBaseClient.getObject("publishedItems");path[0]=="/"&&(path=path.substr(1)),data?data.indexOf(path)==-1&&data.unshift(path):(data=[],data.push(path)),myPublicBaseClient.storeObject("array","publishedItems",data)}function removeFromPublicItems(path){var data=myPublicBaseClient.getObject("publishedItems");path[0]=="/"&&(path=path.substr(1)),data?data.indexOf(path)!=-1&&data.pop(path):data=[],myPublicBaseClient.storeObject("array","publishedItems",data)}function publishObject(path){if(pathIsPublic(path))return"Object has already been made public";var data=myPrivateBaseClient.getObject(path),publicPath="/public"+path;return addToPublicItems(publicPath),myPrivateBaseClient.remove(path),myPrivateBaseClient.storeObject(data["@type"],publicPath,data),"Object "+path+" has been published to "+publicPath}function archiveObject(path){if(!pathIsPublic(path))return"Object has already been made private";var data=myPrivateBaseClient.getObject(path),privatePath=path.substring(7,path.length);return removeFromPublicItems(path),myPrivateBaseClient.remove(path),myPrivateBaseClient.storeObject(data["@type"],privatePath,data),"Object "+path+" has been archived to "+privatePath}function pathIsPublic(path){return path.substring(0,8)=="/public/"?!0:!1}function getClient(path){return pathIsPublic(path)?myPublicBaseClient:myPrivateBaseClient}function getObject(path,cb,context){var client=getClient(path);return client.getObject(path,cb,context)}function setObject(type,path,obj){var client=getClient(path);typeof obj=="object"?client.storeObject(type,path,obj):client.storeDocument(type,path,obj)}function removeObject(path){var client=getClient(path);client.remove(path)}function getListing(path,cb,context){var client=getClient(path);return client.getListing(path,cb,context)}return{exports:{getListing:getListing,getObject:getObject,setObject:setObject,removeObject:removeObject,archiveObject:archiveObject,publishObject:publishObject,setOnChange:setOnChange}}}),remoteStorage.root}),define("modules/calendar",["../remoteStorage"],function(remoteStorage){var moduleName="calendar";return remoteStorage.defineModule(moduleName,function(privateBaseClient){function getEventsForDay(day){var ids=privateBaseClient.getListing(day+"/"),list=[];for(var i=0;i<ids.length;i++){var obj=privateBaseClient.getObject(day+"/"+ids[i]);list.push({itemId:ids[i],itemValue:obj.text})}return list}function addEvent(itemId,day,value){privateBaseClient.storeObject("event",day+"/"+itemId,{text:value})}function removeEvent(itemId,day){privateBaseClient.remove(day+"/"+itemId)}return{exports:{getEventsForDay:getEventsForDay,addEvent:addEvent,removeEvent:removeEvent}}}),remoteStorage[moduleName]}),define("modules/deps/vcardjs-0.2",[],function(){(function(){var CHARS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");Math.uuid=function(len,radix){var chars=CHARS,uuid=[],i;radix=radix||chars.length;if(len)for(i=0;i<len;i++)uuid[i]=chars[0|Math.random()*radix];else{var r;uuid[8]=uuid[13]=uuid[18]=uuid[23]="-",uuid[14]="4";for(i=0;i<36;i++)uuid[i]||(r=0|Math.random()*16,uuid[i]=chars[i==19?r&3|8:r])}return uuid.join("")},Math.uuidFast=function(){var chars=CHARS,uuid=new Array(36),rnd=0,r;for(var i=0;i<36;i++)i==8||i==13||i==18||i==23?uuid[i]="-":i==14?uuid[i]="4":(rnd<=2&&(rnd=33554432+Math.random()*16777216|0),r=rnd&15,rnd>>=4,uuid[i]=chars[i==19?r&3|8:r]);return uuid.join("")},Math.uuidCompact=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=="x"?r:r&3|8;return v.toString(16)})}})();var VCard;(function(){VCard=function(attributes){this.changed=!1;if(typeof attributes=="object")for(var key in attributes)this[key]=attributes[key],this.changed=!0},VCard.prototype={validate:function(){function addError(attribute,type){errors.push([attribute,type])}function validateCompoundWithType(attribute,values){for(var i in values){var value=values[i];typeof value!="object"?errors.push([attribute+"-"+i,"not-an-object"]):value.type?value.value||errors.push([attribute+"-"+i,"missing-value"]):errors.push([attribute+"-"+i,"missing-type"])}}var errors=[];this.fn||addError("fn","required");for(var key in VCard.multivaluedKeys)this[key]&&!(this[key]instanceof Array)&&(this[key]=[this[key]]);return this.email&&validateCompoundWithType("email",this.email),this.tel&&validateCompoundWithType("email",this.tel),this.uid||this.addAttribute("uid",this.generateUID()),this.rev||this.addAttribute("rev",this.generateRev()),this.errors=errors,!(errors.length>0)},generateUID:function(){return"uuid:"+Math.uuid()},generateRev:function(){return(new Date).toISOString().replace(/[\.\:\-]/g,"")},setAttribute:function(key,value){this[key]=value,this.changed=!0},addAttribute:function(key,value){console.log("add attribute",key,value);if(!value)return;VCard.multivaluedKeys[key]?this[key]?(console.log("multivalued push"),this[key].push(value)):(console.log("multivalued set"),this.setAttribute(key,[value])):this.setAttribute(key,value)},toJSON:function(){return JSON.stringify(this.toJCard())},toJCard:function(){var jcard={};for(var k in VCard.allKeys){var key=VCard.allKeys[k];this[key]&&(jcard[key]=this[key])}return jcard},merge:function(other){function mergeProperty(key){other[key]?other[key]==this[key]?result.setAttribute(this[key]):(result.addAttribute(this[key]),result.addAttribute(other[key])):result[key]=this[key]}if(typeof other.uid!="undefined"&&typeof this.uid!="undefined"&&other.uid!==this.uid)throw"Won't merge vcards without matching UIDs.";var result=new VCard;for(key in this)mergeProperty(key);for(key in other)result[key]||mergeProperty(key)}},VCard.enums={telType:["text","voice","fax","cell","video","pager","textphone"],relatedType:["contact","acquaintance","friend","met","co-worker","colleague","co-resident","neighbor","child","parent","sibling","spouse","kin","muse","crush","date","sweetheart","me","agent","emergency"],emailType:["work","home","internet"],langType:["work","home"]},VCard.allKeys=["fn","n","nickname","photo","bday","anniversary","gender","tel","email","impp","lang","tz","geo","title","role","logo","org","member","related","categories","note","prodid","rev","sound","uid"],VCard.multivaluedKeys={email:!0,tel:!0,geo:!0,title:!0,role:!0,logo:!0,org:!0,member:!0,related:!0,categories:!0,note:!0}})();var VCF;return function(){VCF={simpleKeys:["VERSION","FN","PHOTO","GEO","TITLE","ROLE","LOGO","MEMBER","NOTE","PRODID","SOUND","UID"],csvKeys:["NICKNAME","CATEGORIES"],dateAndOrTimeKeys:["BDAY","ANNIVERSARY","REV"],parse:function(input,callback,context){var vcard=null;context||(context=this),this.lex(input,function(key,value,attrs){function setAttr(val){vcard&&vcard.addAttribute(key.toLowerCase(),val)}if(key=="BEGIN")vcard=new VCard;else if(key=="END")vcard&&(callback.apply(context,[vcard]),vcard=null);else if(this.simpleKeys.indexOf(key)!=-1)setAttr(value);else if(this.csvKeys.indexOf(key)!=-1)setAttr(value.split(","));else if(this.dateAndOrTimeKeys.indexOf(key)!=-1)attrs.VALUE=="text"?setAttr(value):(!attrs.CALSCALE||attrs.CALSCALE=="gregorian")&&setAttr(this.parseDateAndOrTime(value));else if(key=="N")setAttr(this.parseName(value));else if(key=="GENDER")setAttr(this.parseGender(value));else if(key=="TEL")setAttr({type:attrs.TYPE||"voice",pref:attrs.PREF,value:value});else if(key=="EMAIL")setAttr({type:attrs.TYPE,pref:attrs.PREF,value:value});else if(key=="IMPP")setAttr({value:value});else if(key=="LANG")setAttr({type:attrs.TYPE,pref:attrs.PREF,value:value});else if(key=="TZ")attrs.VALUE=="utc-offset"?setAttr({"utc-offset":this.parseTimezone(value)}):setAttr({name:value});else if(key=="ORG"){var parts=value.split(";");setAttr({"organization-name":parts[0],"organization-unit":parts[1]})}else key=="RELATED"?setAttr({type:attrs.TYPE,pref:attrs.PREF,value:attrs.VALUE}):console.log("WARNING: unhandled key: ",key)})},nameParts:["family-name","given-name","additional-name","honorific-prefix","honorific-suffix"],parseName:function(name){var parts=name.split(";"),n={};for(var i in parts)parts[i]&&(n[this.nameParts[i]]=parts[i].split(","));return n},parseGender:function(value){var gender={},parts=value.split(";");switch(parts[0]){case"M":gender.sex="male";break;case"F":gender.sex="female";break;case"O":gender.sex="other"}return parts[1]&&(gender.identity=parts[1]),gender},dateRE:/^(\d{4})(\d{2})(\d{2})$/,dateReducedARE:/^(\d{4})\-(\d{2})$/,dateReducedBRE:/^(\d{4})$/,dateTruncatedMDRE:/^\-{2}(\d{2})(\d{2})$/,dateTruncatedDRE:/^\-{3}(\d{2})$/,timeRE:/^(\d{2})(\d{2})(\d{2})([+\-]\d+|Z|)$/,timeReducedARE:/^(\d{2})(\d{2})([+\-]\d+|Z|)$/,timeReducedBRE:/^(\d{2})([+\-]\d+|Z|)$/,timeTruncatedMSRE:/^\-{2}(\d{2})(\d{2})([+\-]\d+|Z|)$/,timeTruncatedSRE:/^\-{3}(\d{2})([+\-]\d+|Z|)$/,parseDate:function(data){var md,y,m,d;if(md=data.match(this.dateRE))y=md[1],m=md[2],d=md[3];else if(md=data.match(this.dateReducedARE))y=md[1],m=md[2];else if(md=data.match(this.dateReducedBRE))y=md[1];else if(md=data.match(this.dateTruncatedMDRE))m=md[1],d=md[2];else{if(!(md=data.match(this.dateTruncatedDRE)))return console.error("WARNING: failed to parse date: ",data),null;d=md[1]}var dt=new Date(0);return typeof y!="undefined"&&dt.setUTCFullYear(y),typeof m!="undefined"&&dt.setUTCMonth(m-1),typeof d!="undefined"&&dt.setUTCDate(d),dt},parseTime:function(data){var md,h,m,s,tz;if(md=data.match(this.timeRE))h=md[1],m=md[2],s=md[3],tz=md[4];else if(md=data.match(this.timeReducedARE))h=md[1],m=md[2],tz=md[3];else if(md=data.match(this.timeReducedBRE))h=md[1],tz=md[2];else if(md=data.match(this.timeTruncatedMSRE))m=md[1],s=md[2],tz=md[3];else{if(!(md=data.match(this.timeTruncatedSRE)))return console.error("WARNING: failed to parse time: ",data),null;s=md[1],tz=md[2]}var dt=new Date(0);return typeof h!="undefined"&&dt.setUTCHours(h),typeof m!="undefined"&&dt.setUTCMinutes(m),typeof s!="undefined"&&dt.setUTCSeconds(s),tz&&(dt=this.applyTimezone(dt,tz)),dt},addDates:function(aDate,bDate,addSub){typeof addSub=="undefined"&&(addSub=!0);if(!aDate)return bDate;if(!bDate)return aDate;var a=Number(aDate),b=Number(bDate),c=addSub?a+b:a-b;return new Date(c)},parseTimezone:function(tz){var md;if(md=tz.match(/^([+\-])(\d{2})(\d{2})?/)){var offset=new Date(0);return offset.setUTCHours(md[2]),offset.setUTCMinutes(md[3]||0),Number(offset)*(md[1]=="+"?1:-1)}return null},applyTimezone:function(date,tz){var offset=this.parseTimezone(tz);return offset?new Date(Number(date)+offset):date},parseDateTime:function(data){var parts=data.split("T"),t=this.parseDate(parts[0]),d=this.parseTime(parts[1]);return this.addDates(t,d)},parseDateAndOrTime:function(data){switch(data.indexOf("T")){case 0:return this.parseTime(data.slice(1));case-1:return this.parseDate(data);default:return this.parseDateTime(data)}},lineRE:/^([^\s].*)(?:\r?\n|$)/,foldedLineRE:/^\s(.+)(?:\r?\n|$)/,lex:function(input,callback){var md,line=null,length=0;for(;;){(md=input.match(this.lineRE))?(line&&this.lexLine(line,callback),line=md[1],length=md[0].length):(md=input.match(this.foldedLineRE))?line&&(line+=md[1],length=md[0].length):console.error("Unmatched line: "+line),input=input.slice(length);if(!input)break}line&&this.lexLine(line,callback),line=null},lexLine:function(line,callback){function finalizeKeyOrAttr(){if(key){if(!attrKey){console.error("Invalid attribute: ",tmp,"Line dropped.");return}attrs[attrKey]=tmp}else key=tmp}var tmp="",key=null,attrs={},value=null,attrKey=null;for(var i in line){var c=line[i];switch(c){case":":finalizeKeyOrAttr(),value=line.slice(Number(i)+1),callback.apply(this,[key,value,attrs]);return;case";":finalizeKeyOrAttr(),tmp="";break;case"=":attrKey=tmp,tmp="";break;default:tmp+=c}}}}}(),{VCard:VCard,VCF:VCF}}),define("modules/contacts",["../remoteStorage","../modules/deps/vcardjs-0.2"],function(remoteStorage,vCardJS){var moduleName="contacts",VCard=vCardJS.VCard,VCF=vCardJS.VCF;return remoteStorage.defineModule(moduleName,function(base){function extend(destination,source){var keys=Object.keys(source);for(var i=0;i<keys.length;i++){var key=keys[i];destination[key]=source[key]}return destination}function extend(){var destination=arguments[0],source;for(var i=1;i<arguments.length;i++){source=arguments[i];var keys=Object.keys(source);for(var j=0;j<keys.length;j++){var key=keys[j];destination[key]=source[key]}}return destination}var DEBUG=!0,contacts={},bindContext=typeof function(){}.bind=="function"?function(cb,context){return cb.bind(context)}:function(cb,context){return function(){return cb.apply(context,arguments)}},debug=DEBUG?bindContext(console.log,console):function(){},nodePrototype={isNew:!0,markSaved:function(){return this.isNew=!1,this},save:function(){return this.validate(),this.errors&&this.errors.length>0?!1:(base.storeObject("vcard+"+this.kind,this.uid,this.toJCard()),this.markSaved(),!0)}},Contact=function(){VCard.apply(this,arguments),this.setAttribute("kind","individual")};extend(Contact.prototype,nodePrototype,VCard.prototype,{});var Group=function(name){VCard.apply(this,arguments),this.setAttribute("kind","group")};return extend(Group.prototype,nodePrototype,{getMembers:function(){var members=[];for(var i=0;i<this.member.length;i++)members.push(this.lookupMember(member[i]));return members},lookupMember:function(uri){var md=uri.match(/^([^:]):(.*)$/),scheme=md[1],rest=md[2],key;switch(scheme){case"urn":case"uuid":return contacts.get(uri);case"mailto":case"xmpp":case"sip":case"tel":var query={};query[{mailto:"email",xmpp:"impp",sip:"impp",tel:"tel"}[scheme]]=rest;var results=contacts.search(query);if(results.length>0)return results[0];if(scheme=="tel")break;case"acct":console.error("FIXME: implement contact-lookup via webfinger!");break;case"http":console.error("FIXME: implement contact-lookup via HTTP!");break;default:console.error("FIXME: unknown URI scheme "+scheme)}return undefined}}),extend(contacts,{Contact:Contact,on:function(eventType,callback){base.on(eventType,function(event){event.oldValue&&(event.oldValue=new Contact(event.oldValue)),event.newValue&&(event.newValue=new Contact(event.newValue)),callback(event)})},sync:function(){debug("contacts.sync()"),base.sync("/")},list:function(limit,offset){var list=base.getListing("");offset||(offset=0),limit||(limit=list.length-offset);for(var i=0;i<limit;i++)list[i+offset]&&(list[i+offset]=this.get(list[i+offset]));return list},get:function(uid,cb,context){if(!cb)return this._load(base.getObject(uid));base.getObject(uid,function(data){bindContext(cb,context)(this._load(data))},this)},build:function(attributes){return this._wrap(attributes)},create:function(attributes){var instance=this.build(attributes);return instance.save(),instance},filter:function(cb,context){var list=this.list(),results=[],item;for(var i=0;i<list.length;i++)item=bindContext(cb,context)(list[i]),item&&results.push(item);return results},search:function(filter){var keys=Object.keys(filter);return this.filter(function(item){return this.searchMatch(item,filter,keys)},this)},searchMatch:function(item,filter,filterKeys){filterKeys||(filterKeys=Object.keys(filter));var check=function(value,ref){if(value instanceof Array)for(var i=0;i<value.length;i++)check(value[i],ref);else if(typeof value=="object"&&value.value)check(value.value,ref);else{if(typeof ref=="string"&&ref.length===0)return!0;if(ref instanceof RegExp){if(!ref.test(value))return!1}else if(value!==ref)return!1}};return this.filter(function(item){for(var i=0;i<keys.length;i++){var k=keys[i],v=filter[k];if(!check(item[k],v))return!1}return debug("success"),item})},_load:function(data){return this._wrap(data).markSaved()},_wrap:function(data){return data instanceof Contact?data:new Contact(data)}}),{name:moduleName,dataHints:{},exports:contacts}}),remoteStorage[moduleName]}),define("modules/documents",["../remoteStorage"],function(remoteStorage){var moduleName="documents";return remoteStorage.defineModule(moduleName,function(myBaseClient){function fire(eventType,eventObj){if(eventType=="error")for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](eventObj)}function getUuid(){var uuid="",i,random;for(i=0;i<32;i++){random=Math.random()*16|0;if(i===8||i===12||i===16||i===20)uuid+="-";uuid+=(i===12?4:i===16?random&3|8:random).toString(16)}return uuid}function getPrivateList(listName){function getIds(){return myBaseClient.getListing(listName+"/")}function getContent(id){var obj=myBaseClient.getObject(listName+"/"+id);return obj?obj.content:""}function getTitle(id){return getContent(id).slice(0,50)}function setContent(id,content){content==""?myBaseClient.remove(listName+"/"+id):myBaseClient.storeObject("text",listName+"/"+id,{content:content})}function add(content){var id=getUuid();return myBaseClient.storeObject("text",listName+"/"+id,{content:content}),id}function on(eventType,cb){myBaseClient.on(eventType,cb),eventType=="error"&&errorHandlers.push(cb)}return myBaseClient.sync(listName+"/"),{getIds:getIds,getContent:getContent,getTitle:getTitle,setContent:setContent,add:add,on:on}}var errorHandlers=[];return{name:moduleName,dataHints:{module:"documents can be text documents, or etherpad-lite documents or pdfs or whatever people consider a (text) document. But spreadsheets and diagrams probably not","objectType text":"a human-readable plain-text document in utf-8. No html or markdown etc, they should have their own object types","string text#content":"the content of the text document","directory documents/notes/":"used by litewrite for quick notes","item documents/notes/calendar":"used by docrastinate for the 'calendar' pane","item documents/notes/projects":"used by docrastinate for the 'projects' pane","item documents/notes/personal":"used by docrastinate for the 'personal' pane"},exports:{getPrivateList:getPrivateList}}}),remoteStorage[moduleName]}),define("modules/money",["../remoteStorage"],function(remoteStorage){remoteStorage.defineModule("money",function(myPrivateBaseClient,myPublicBaseClient){return{name:"money",dataHints:{},exports:{setDayBusiness:function(tab,year,month,day,transactions,endBalances){var datePath=year+"/"+month+"/"+day+"/"+tab.substring(1)+"/";for(var i=0;i<transactions.length;i++)myPrivateBaseClient.storeObject("transaction",datePath+"transaction/"+i,transactions[i]);for(var i in endBalances)myPrivateBaseClient.storeObject("balance",datePath+"balance/"+i,endBalances[i])}}}})}),define("modules/tasks",["../remoteStorage"],function(remoteStorage){var moduleName="tasks";return remoteStorage.defineModule(moduleName,function(myPrivateBaseClient,myPublicBaseClient){function fire(eventType,eventObj){if(eventType=="error")for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](eventObj)}function getUuid(){var uuid="",i,random;for(i=0;i<32;i++){random=Math.random()*16|0;if(i===8||i===12||i===16||i===20)uuid+="-";uuid+=(i===12?4:i===16?random&3|8:random).toString(16)}return uuid}function getPrivateList(listName){function getIds(){return myPrivateBaseClient.getListing(listName+"/")}function get(id){return myPrivateBaseClient.getObject(listName+"/"+id)}function set(id,title){var obj=myPrivateBaseClient.getObject(listName+"/"+id);obj.title=title,myPrivateBaseClient.storeObject("task",listName+"/"+id,obj)}function add(title){var id=getUuid();return myPrivateBaseClient.storeObject("task",listName+"/"+id,{title:title,completed:!1}),id}function markCompleted(id,completedVal){typeof completedVal=="undefined"&&(completedVal=!0);var obj=myPrivateBaseClient.getObject(listName+"/"+id);obj&&obj.completed!=completedVal&&(obj.completed=completedVal,myPrivateBaseClient.storeObject("task",listName+"/"+id,obj))}function isCompleted(id){var obj=get(id);return obj&&obj.completed}function getStats(){var ids=getIds(),stat={todoCompleted:0,totalTodo:ids.length};for(var i=0;i<stat.totalTodo;i++)isCompleted(ids[i])&&(stat.todoCompleted+=1);return stat.todoLeft=stat.totalTodo-stat.todoCompleted,stat}function remove(id){myPrivateBaseClient.remove(listName+"/"+id)}function on(eventType,cb){myPrivateBaseClient.on(eventType,cb),eventType=="error"&&errorHandlers.push(cb)}return myPrivateBaseClient.sync(listName+"/"),{getIds:getIds,get:get,set:set,add:add,remove:remove,markCompleted:markCompleted,getStats:getStats,on:on}}var errorHandlers=[];return{name:moduleName,dataHints:{module:"tasks are things that need doing; items on your todo list","objectType task":"something that needs doing, like cleaning the windows or fixing a specific bug in a program","string task#title":"describes what it is that needs doing","boolean task#completed":"whether the task has already been completed or not (yet)","directory tasks/todos/":"default private todo list","directory tasks/:year/":"tasks that need doing during year :year","directory public/tasks/:hash/":"tasks list shared to for instance a team"},exports:{getPrivateList:getPrivateList}}}),remoteStorage[moduleName]}),define("modules/bookmarks",["../remoteStorage"],function(remoteStorage){var moduleName="bookmarks";remoteStorage.defineModule(moduleName,function(privateClient,publicClient){return{name:moduleName,dataHints:{module:"Store URLs which you do not wish to forget"},exports:{on:privateClient.on,listUrls:function(){var keys=privateClient.getListing(""),urls=[];return keys.forEach(function(key){urls.push(privateClient.get(key).url)}),urls},listBookmarks:function(){var keys=privateClient.getListing(""),bms=[];return keys.forEach(function(key){bms.push(privateClient.getObject(key))}),bms},addUrl:function(url){return privateClient.storeObject("bookmark",encodeURIComponent(url),{url:url,createdAt:new Date})},getPublicListing:function(){var listing=publicClient.getObject("publishedItems");return listing||{items:[]}},publish:function(url){var key=encodeURIComponent(url),bookmark=privateClient.getObject(key);publicClient.storeObject("bookmark",key,bookmark);var listing=publicClient.getListing("");delete listing.published,publicClient.storeObject("bookmark-list","published",listing)}}}})}),define("remoteStorage-modules",["./remoteStorage","./modules/root","./modules/calendar","./modules/contacts","./modules/documents","./modules/money","./modules/tasks","./modules/bookmarks"],function(remoteStorage){return remoteStorage}),remoteStorage=require("remoteStorage-modules")})()
\ No newline at end of file
index 075a53e..27ee6d3 100644 (file)
@@ -1523,7 +1523,10 @@ define('lib/sync',['./wireClient', './store', './util'], function(wireClient, st
           var childNode = store.getNode(dirPath+i);
           var childData = store.getNodeData(dirPath + i);
           startOne();
-          wireClient.set(dirPath+i, JSON.stringify(childData), 'application/json', function(err) {
+          if(typeof(childData) === 'object') {
+            childData = JSON.stringify(childData);
+          }
+          wireClient.set(dirPath+i, childData, 'application/json', function(err) {
             finishOne();
           });
         }
index 6cb33da..21b1cc8 100644 (file)
@@ -6,4 +6,4 @@
  * see: http://github.com/jrburke/almond for details
  */
 
-(function(){var requirejs,require,define;(function(undef){function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=map&&map["*"]||{};if(name&&name.charAt(0)==="."&&baseName){baseParts=baseParts.slice(0,baseParts.length-1),name=baseParts.concat(name.split("/"));for(i=0;i<name.length;i+=1){part=name[i];if(part===".")name.splice(i,1),i-=1;else if(part===".."){if(i===1&&(name[2]===".."||name[0]===".."))break;i>0&&(name.splice(i-1,2),i-=2)}}name=name.join("/")}if((baseParts||starMap)&&map){nameParts=name.split("/");for(i=nameParts.length;i>0;i-=1){nameSegment=nameParts.slice(0,i).join("/");if(baseParts)for(j=baseParts.length;j>0;j-=1){mapValue=map[baseParts.slice(0,j).join("/")];if(mapValue){mapValue=mapValue[nameSegment];if(mapValue){foundMap=mapValue,foundI=i;break}}}if(foundMap)break;!foundStarMap&&starMap&&starMap[nameSegment]&&(foundStarMap=starMap[nameSegment],starI=i)}!foundMap&&foundStarMap&&(foundMap=foundStarMap,foundI=starI),foundMap&&(nameParts.splice(0,foundI,foundMap),name=nameParts.join("/"))}return name}function makeRequire(relName,forceSync){return function(){return req.apply(undef,aps.call(arguments,0).concat([relName,forceSync]))}}function makeNormalize(relName){return function(name){return normalize(name,relName)}}function makeLoad(depName){return function(value){defined[depName]=value}}function callDep(name){if(waiting.hasOwnProperty(name)){var args=waiting[name];delete waiting[name],defining[name]=!0,main.apply(undef,args)}if(!defined.hasOwnProperty(name))throw new Error("No "+name);return defined[name]}function makeMap(name,relName){var prefix,plugin,index=name.indexOf("!");return index!==-1?(prefix=normalize(name.slice(0,index),relName),name=name.slice(index+1),plugin=callDep(prefix),plugin&&plugin.normalize?name=plugin.normalize(name,makeNormalize(relName)):name=normalize(name,relName)):name=normalize(name,relName),{f:prefix?prefix+"!"+name:name,n:name,p:plugin}}function makeConfig(name){return function(){return config&&config.config&&config.config[name]||{}}}var main,req,defined={},waiting={},config={},defining={},aps=[].slice;main=function(name,deps,callback,relName){var cjsModule,depName,ret,map,i,args=[],usingExports;relName=relName||name;if(typeof callback=="function"){deps=!deps.length&&callback.length?["require","exports","module"]:deps;for(i=0;i<deps.length;i+=1){map=makeMap(deps[i],relName),depName=map.f;if(depName==="require")args[i]=makeRequire(name);else if(depName==="exports")args[i]=defined[name]={},usingExports=!0;else if(depName==="module")cjsModule=args[i]={id:name,uri:"",exports:defined[name],config:makeConfig(name)};else if(defined.hasOwnProperty(depName)||waiting.hasOwnProperty(depName))args[i]=callDep(depName);else if(map.p)map.p.load(map.n,makeRequire(relName,!0),makeLoad(depName),{}),args[i]=defined[depName];else if(!defining[depName])throw new Error(name+" missing "+depName)}ret=callback.apply(defined[name],args);if(name)if(cjsModule&&cjsModule.exports!==undef&&cjsModule.exports!==defined[name])defined[name]=cjsModule.exports;else if(ret!==undef||!usingExports)defined[name]=ret}else name&&(defined[name]=callback)},requirejs=require=req=function(deps,callback,relName,forceSync,alt){return typeof deps=="string"?callDep(makeMap(deps,callback).f):(deps.splice||(config=deps,callback.splice?(deps=callback,callback=relName,relName=null):deps=undef),callback=callback||function(){},typeof relName=="function"&&(relName=forceSync,forceSync=alt),forceSync?main(undef,deps,callback,relName):setTimeout(function(){main(undef,deps,callback,relName)},15),req)},req.config=function(cfg){return config=cfg,req},define=function(name,deps,callback){deps.splice||(callback=deps,deps=[]),waiting[name]=[name,deps,callback]},define.amd={jQuery:!0}})(),define("../build/lib/almond",function(){}),define("lib/assets",[],function(){return{remoteStorageIcon:"data:image/png;base64,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",remoteStorageCube:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAR2SURBVFiFtddfqGVVHQfwz2/vfZ28c2WgP6hMoYkUV4qIYnSKmaQYwaaJ3oLeUnpJmDCmUhCaIhhKGelhelCqN9+ECKdAxR6kgnJASBN9KTGwP2oKTtyZs8/+9bDXPufcfe51xju6YLHX2fu3ft/v+q7fWb/fisy0o3brez6qmt4Luvo7frvx/E7cxNsmcCj2WGnuEb6JaXlbSz8zaX/ksXzj3SHwg6j8aeU28jjeh8TZ8nU3Aq8Sx+2b/ML3s3vnCHxp5YB0Hz6OTkgpMax2jxBSoMJfhGMemTx5aQQOxzWsnCC/gm6hZ+mvFMv36xUYCJQev2Jyt9P54tsj8OVYNW2+izuxIkzlAoGUQuLlMuNqKcQCgVBJNSa4X93+xK/zfxcmcLj5GtUJ8ipMC/i0gA/PQYF/lFkfHClQFxJ1IVET/6S72+n2oa0JHL7s0+RPsR9tAZuOxuNtGKS9xpL8A7BmNP4j8S2nzz+lGJaWDxB7RyCbV54DkZiSrbAhbJBt/25LtUbEY2+P1bdmQY1V8mr8DruET5Z9n4NHTOmmZK9A2ihzp3RdL3tVy+z16OeG0ElncI48yGzeogIzQgexByelp2fMZ+CDAtFK56XzxFwBXSE6C9incbL4PDha9BKBPrjCddJRVT5DHsMLczkLUGhFbPR9iJNYjJUXyGOqfEY6KlxnHrybVjwm0JVDJmV8FZ8TeZysZdyBK9FKXb/6mdTZ+4uXRXcKUxnHpavKdqV58G5JYJFdLvT3yuok3ROiuY3JZ3Rxu7CH7lxvHlPpNVX+nJU/yMk9VJ8nm5GvMc42W6Bwnhl2KRyQ7cOyaqy1R0ScEvFq6aestUdk1cj2YeEA3RwwtwbfSoHtxxmJXeS3nV25RR0/9KnJL8GZyz7i7MoD5MfQ9LZ5YZ+WY+AiW16vc8if/av8PkRevxNPiwTiLceRISPIM3iUOGxa/wfUbiTvxy3ETb3tRfi0HAMx+xgLY1XIeAUPYoO4S+YNqupyVXW5zBuIu/pvHuxtq5j5DLHkfxsFxoaBlN1vVKbEN2TQ5wdYLc8++YibhZvJx3VZizgy8rVEYhwDfUKZFxd/Jf8m4gsydtENJ17TZ8lcLbOGrFfJrKmOiDxHPk58GJ8oPqu3UmDOLr2B5/AhYt08K9Z9AMdAsCeQml6BnKdiriC+iP/iKWkdH7gQgSRfQoi4SWoLcMqsRaUcZiX1xu4yrZmpp6p721lavlLYK/PfeIm4djsCE7xZDNqSVocV9evNJCKIjq6TuTbbAlWvQGZfiCwWJqkqqb7pMUwG0IV/QXwdz1ouKjZXOP021EQjqt2i2k00/Tv1Evj8OfRnC1aPeokl2e/LrM/aYUk2Pgc43T6knqzjBCZytqqhpGpK0DXCmrC26d1Qgs3BJzihnqyPwbdWYJMaFyzLnyuW6yMFLrEsH7ftLyZ/LxbX7vRisrwFW7VHJk/a1+4njuL1udx5Rd9nW/A6cdS+dv/FgHPpl9PhorH67l9Ox62/nv8YdPX3dno9/z+G+TGrzjgPKwAAAABJRU5ErkJggg==",widgetCss:"#remotestorage-state { position:fixed; top:15px; right:15px; height:32px; width:275px; font:normal 16px/100% sans-serif; z-index:99999; background:rgba(0,0,0,.3); padding:5px; border-radius:7px; box-shadow:0 1px rgba(255,255,255,.05), inset 0 1px rgba(0,0,0,.05); transition:width 500ms, background 500ms; }\n#remotestorage-state.connected, #remotestorage-state.busy, #remotestorage-state.offline { width:32px; background:none; box-shadow:none; }\n.remotestorage-button { margin:0; padding:.3em; font-size:14px; height:26px !important; background:#ddd; color:#333; border:1px solid #ccc; border-radius:3px; box-shadow:0 1px 1px #fff inset; }\n#remotestorage-register-button { position:absolute; left:25px; top:8px; max-height:16px; text-decoration:none; font-weight:normal; }\n#remotestorage-connect-button { position:absolute; right:8px; top:8px; padding:0 0 0 17px; width:90px; cursor:pointer; text-align:left; border-radius:0 3px 3px 0; font-weight:normal; }\n#remotestorage-connect-button:hover, #remotestorage-connect-button:focus, .remotestorage-button:hover, .remotestorage-button:focus { background:#eee; color:#000; text-decoration:none; }\n#remotestorage-useraddress { position:absolute; left:25px; top:8px; margin:0; padding:0 17px 0 3px; height:25px; width:142px; background:#eee; color:#333; border:0; border-radius:3px 0 0 3px; box-shadow:0 1px #fff, inset 0 1px #999; font-weight:normal; font-size:14px;}\n#remotestorage-useraddress:hover, #remotestorage-useraddress:focus { background:#fff; color:#000; }\n#remotestorage-cube { position:absolute; right:84px; -webkit-transition:right 500ms; -moz-transition:right 500ms; transition:right 500ms; z-index:99997; }\n#remotestorage-questionmark { position:absolute; left:0; padding:9px 8px; color:#fff; text-decoration:none; z-index:99999; font-weight:normal; }\n.infotext { position:absolute; left:0; top:0; width:255px; height:32px; padding:6px 5px 4px 25px; font-size:10px; background:black; color:white; border-radius:7px; opacity:.85; text-decoration:none; white-space:nowrap; z-index:99998; }\n#remotestorage-questiomark:hover { color:#fff; }\n#remotestorage-questionmark:hover+#remotestorage-infotext { display:inline; }\n#remotestorage-state.busy #remotestorage-cube, #remotestorage-state.connecting #remotestorage-cube {   -webkit-animation-name:remotestorage-loading; -webkit-animation-duration:2s; -webkit-animation-iteration-count:infinite; -webkit-animation-timing-function:linear;\n   -moz-animation-name:remotestorage-loading; -moz-animation-duration:2s; -moz-animation-iteration-count:infinite; -moz-animation-timing-function:linear;\n   -o-animation-name:remotestorage-loading; -o-animation-duration:2s; -o-animation-iteration-count:infinite; -o-animation-timing-function:linear;\n   -ms-animation-name:remotestorage-loading; -ms-animation-duration:2s; -ms-animation-iteration-count:infinite; -ms-animation-timing-function:linear; }\n   @-webkit-keyframes remotestorage-loading { from{-webkit-transform:rotate(0deg)} to{-webkit-transform:rotate(360deg)} }\n   @-moz-keyframes remotestorage-loading { from{-moz-transform:rotate(0deg)} to{-moz-transform:rotate(360deg)} }\n   @-o-keyframes remotestorage-loading { from{-o-transform:rotate(0deg)} to{-o-transform:rotate(360deg)} }\n   @-ms-keyframes remotestorage-loading { from{-ms-transform:rotate(0deg)} to{ -ms-transform:rotate(360deg)} }\n#remotestorage-connect-button, #remotestorage-questionmark, #remotestorage-register-button, #remotestorage-cube, #remotestorage-useraddress, #remotestorage-infotext, #remotestorage-devsonly, #remotestorage-disconnect { display:none }\n#remotestorage-state.anonymous #remotestorage-cube, #remotestorage-state.anonymous #remotestorage-connect-button, #remotestorage-state.anonymous #remotestorage-register-button, #remotestorage-state.anonymous #remotestorage-questionmark { display: block }\n#remotestorage-state.registering #remotestorage-cube, #remotestorage-state.registering #remotestorage-connect-button, #remotestorage-state.registering #remotestorage-register-button, #remotestorage-state.registering #remotestorage-questionmark { display: block }\n#remotestorage-state.interrupted #remotestorage-cube, #remotestorage-state.interrupted #remotestorage-connect-button, #remotestorage-state.interrupted #remotestorage-register-button, #remotestorage-state.interrupted #remotestorage-questionmark { display: block }\n#remotestorage-state.failed #remotestorage-cube, #remotestorage-state.failed #remotestorage-connect-button, #remotestorage-state.failed #remotestorage-register-button, #remotestorage-state.failed #remotestorage-questionmark { display: block }\n#remotestorage-state.typing #remotestorage-cube, #remotestorage-state.typing #remotestorage-connect-button, #remotestorage-state.typing #remotestorage-useraddress, #remotestorage-state.typing #remotestorage-questionmark { display: block }\n#remotestorage-state.connected #remotestorage-cube, #remotestorage-state.busy #remotestorage-cube, #remotestorage-state.offline #remotestorage-cube { right:0; opacity:.5; cursor:pointer; display: block }\n#remotestorage-state.devsonly #remotestorage-devsonly { display: block }\n#remotestorage-disconnect { position:absolute; right:6px; top:9px; padding:5px 28px 2px 6px; height:17px; white-space:nowrap; font-size:10px; background:#000; color:#fff; border-radius:5px; opacity:.5; text-decoration:none; z-index:99996; }\n#remotestorage-disconnect strong { font-weight:bold; }\n#remotestorage-state.connected #remotestorage-cube:hover, #remotestorage-state.busy #remotestorage-cube:hover, #remotestorage-state.offline #remotestorage-cube:hover { opacity:1; }\n#remotestorage-state.connected #remotestorage-disconnect:hover, #remotestorage-state.busy #remotestorage-disconnect:hover, #remotestorage-state.offline #remotestorage-disconnect:hover { display:inline; }\n#remotestorage-state.connected #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.busy #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.offline #remotestorage-cube:hover+#remotestorage-disconnect { display:inline; }\n"}}),define("lib/util",[],function(){var loggers={},silentLogger={},knownLoggers=["sync","webfinger","getputdelete","platform","baseClient"],util={toArray:function(enumerable){var a=[];for(var i in enumerable)a.push(enumerable[i]);return a},getLogger:function(name){return loggers[name]||(loggers[name]={info:function(){this.log("info",util.toArray(arguments))},debug:function(){this.log("debug",util.toArray(arguments),"debug")},error:function(){this.log("error",util.toArray(arguments),"error")},log:function(level,args,type){if(silentLogger[name])return;type||(type="log"),args.unshift("["+name.toUpperCase()+"] -- "+level+" "),(console[type]||console.log).apply(console,args)}}),loggers[name]},silenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)silentLogger[names[i]]=!0},unsilenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)delete silentLogger[names[i]]},silenceAllLoggers:function(){this.silenceLogger.apply(this,knownLoggers)},unsilenceAllLoggers:function(){this.unsilenceLogger.apply(this,knownLoggers)}};return util}),define("lib/platform",["./util"],function(util){function browserParseHeaders(rawHeaders){var headers={},lines=rawHeaders.split(/\r?\n/),lastKey=null,md,key,value;for(var i=0;i<lines.length;i++){if(lines[i].length==0)continue;(md=lines[i].match(/^([^:]+):\s*(.+)$/))?(key=md[1],value=md[2],headers[key]=value,lastKey=key):(md=lines[i].match(/^\s+(.+)$/))?(key=lastKey,value=md[1],headers[key]=headers[key]+value):logger.error("Failed to parse header line: "+lines[i])}return headers}function ajaxBrowser(params){var timedOut=!1,timer;params.timeout&&(timer=window.setTimeout(function(){timedOut=!0,params.error("timeout")},params.timeout));var xhr=new XMLHttpRequest;params.method||(params.method="GET"),xhr.open(params.method,params.url,!0);if(params.headers)for(var header in params.headers)xhr.setRequestHeader(header,params.headers[header]);logger.debug("A "+params.url),xhr.onreadystatechange=function(){xhr.readyState==4&&!timedOut&&(logger.debug("B "+params.url),timer&&window.clearTimeout(timer),logger.debug("xhr cb "+params.url),xhr.status==200||xhr.status==201||xhr.status==204||xhr.status==207?params.success(xhr.responseText,browserParseHeaders(xhr.getAllResponseHeaders())):params.error(xhr.status))},logger.debug("xhr "+params.url),typeof params.data=="string"?xhr.send(params.data):xhr.send()}function ajaxExplorer(params){var xdr=new XDomainRequest;xdr.timeout=params.timeout||3e3,xdr.open(params.method,params.url),xdr.onload=function(){xdr.status==200||xdr.status==201||xdr.status==204?params.success(xhr.responseText):params.error(xhr.status)},xdr.onerror=function(){err("unknown error")},xdr.ontimeout=function(){err(timeout)},params.data?xdr.send(params.data):xdr.send()}function ajaxNode(params){function normalizeHeaders(headers){var h={};for(var key in headers)h[key.replace(/(?:^|\-)[a-z]/g,function(match){return match.toUpperCase()})]=headers[key];return h}var http=require("http"),https=require("https"),url=require("url");params.method||(params.method="GET"),params.data?params.headers["content-length"]=params.data.length:params.data=null;var urlObj=url.parse(params.url),options={method:params.method,host:urlObj.hostname,path:urlObj.path,port:urlObj.port?port:urlObj.protocol=="https:"?443:80,headers:params.headers},timer,timedOut;params.timeout&&(timer=setTimeout(function(){params.error("timeout"),timedOut=!0},params.timeout));var lib=urlObj.protocol=="https:"?https:http,request=lib.request(options,function(response){var str="";response.setEncoding("utf8"),response.on("data",function(chunk){str+=chunk}),response.on("end",function(){timer&&clearTimeout(timer),timedOut||(response.statusCode==200||response.statusCode==201||response.statusCode==204?params.success(str,normalizeHeaders(response.headers)):params.error(response.statusCode))})});request.on("error",function(e){timer&&clearTimeout(timer),params.error(e.message)}),params.data?request.end(params.data):request.end()}function parseXmlBrowser(str,cb){var tree=(new DOMParser).parseFromString(str,"text/xml"),nodes=tree.getElementsByTagName("Link"),obj={Link:[]};for(var i=0;i<nodes.length;i++){var link={};if(nodes[i].attributes)for(var j=0;j<nodes[i].attributes.length;j++)link[nodes[i].attributes[j].name]=nodes[i].attributes[j].value;var props=nodes[i].getElementsByTagName("Property");link.properties={},xyz=props;for(var k=0;k<props.length;k++)link.properties[props[k].getAttribute("type")]=props[k].childNodes[0].nodeValue;link.rel&&obj.Link.push({"@":link})}cb(null,obj)}function parseXmlNode(str,cb){var xml2js=require("xml2js");(new xml2js.Parser).parseString(str,cb)}function harvestParamNode(){}function harvestParamBrowser(param){if(location.hash.length){var pairs=location.hash.substring(1).split("&");for(var i=0;i<pairs.length;i++)if(pairs[i].substring(0,(param+"=").length)==param+"="){var ret=decodeURIComponent(pairs[i].substring((param+"=").length));return delete pairs[i],location="#"+pairs.join("&"),ret}}}function setElementHtmlNode(eltName,html){}function setElementHtmlBrowser(eltName,html){var elt=eltName;elt instanceof Element||(elt=document.getElementById(eltName)),elt.innerHTML=html}function getElementValueNode(eltName){}function getElementValueBrowser(eltName){return document.getElementById(eltName).value}function eltOnNode(eltName,eventType,cb){}function eltOnBrowser(eltName,eventType,cb){eventType=="click"?document.getElementById(eltName).onclick=cb:eventType=="hover"?document.getElementById(eltName).onmouseover=cb:eventType=="type"&&(document.getElementById(eltName).onkeyup=cb)}function getLocationBrowser(){return window.location.href.split("#")[0]}function getLocationNode(){}function setLocationBrowser(location){window.location=location}function setLocationNode(){}function alertBrowser(str){alert(str)}function alertNode(str){console.log(str)}var logger=util.getLogger("platform");return typeof window=="undefined"?{ajax:ajaxNode,parseXml:parseXmlNode,harvestParam:harvestParamNode,setElementHTML:setElementHtmlNode,getElementValue:getElementValueNode,eltOn:eltOnNode,getLocation:getLocationNode,setLocation:setLocationNode,alert:alertNode}:window.XDomainRequest?{ajax:ajaxExplorer,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}:{ajax:ajaxBrowser,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}}),define("lib/webfinger",["./platform","./util"],function(platform,util){function userAddress2hostMetas(userAddress,cb){var parts=userAddress.toLowerCase().split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9a-z\-\_]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9a-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{var query="?resource=acct:"+encodeURIComponent(userAddress);cb(null,["https://"+parts[1]+"/.well-known/host-meta.json"+query,"https://"+parts[1]+"/.well-known/host-meta"+query,"http://"+parts[1]+"/.well-known/host-meta.json"+query,"http://"+parts[1]+"/.well-known/host-meta"+query])}}function fetchXrd(addresses,timeout,cb){var firstAddress=addresses.shift();firstAddress?platform.ajax({url:firstAddress,success:function(data){parseAsJrd(data,function(err,obj){err?parseAsXrd(data,function(err,obj){err?fetchXrd(addresses,timeout,cb):cb(null,obj)}):cb(null,obj)})},error:function(data){fetchXrd(addresses,timeout,cb)},timeout:timeout}):cb("could not fetch xrd")}function parseAsXrd(str,cb){platform.parseXml(str,function(err,obj){if(err)cb(err);else if(obj&&obj.Link){var links={};if(obj.Link&&obj.Link["@"])obj.Link["@"].rel&&(links[obj.Link["@"].rel]=obj.Link["@"]);else for(var i=0;i<obj.Link.length;i++)obj.Link[i]["@"]&&obj.Link[i]["@"].rel&&(links[obj.Link[i]["@"].rel]=obj.Link[i]["@"]);cb(null,links)}else cb("found valid xml but with no Link elements in there")})}function parseAsJrd(str,cb){var obj;try{obj=JSON.parse(str)}catch(e){cb("not valid JSON");return}obj.links||cb("JRD contains no links");var links={};for(var i=0;i<obj.links.length;i++)obj.links[i].rel&&(links[obj.links[i].rel]=obj.links[i]);cb(null,links)}function parseRemoteStorageLink(obj,cb){obj&&obj.href&&obj.type&&obj.properties&&obj.properties["auth-endpoint"]?cb(null,obj):cb("could not extract storageInfo from lrdd")}function getStorageInfo(userAddress,options,cb){userAddress2hostMetas(userAddress,function(err1,hostMetaAddresses){logger.debug("HOST META ADDRESSES",hostMetaAddresses,"(error: ",err1,")"),err1?cb(err1):fetchXrd(hostMetaAddresses,options.timeout,function(err2,hostMetaLinks){if(err2)cb("could not fetch host-meta for "+userAddress);else if(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage)parseRemoteStorageLink(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage,cb);else if(hostMetaLinks.lrdd&&hostMetaLinks.lrdd.template){var parts=hostMetaLinks.lrdd.template.split("{uri}"),lrddAddresses=[parts.join("acct:"+userAddress),parts.join(userAddress)];fetchXrd(lrddAddresses,options.timeout,function(err4,lrddLinks){err4?cb("could not fetch lrdd for "+userAddress):lrddLinks.remoteStorage?parseRemoteStorageLink(lrddLinks.remoteStorage,cb):lrddLinks.remotestorage?parseRemoteStorageLink(lrddLinks.remotestorage,cb):cb("could not extract storageInfo from lrdd")})}else cb("could not extract lrdd template from host-meta")})})}var logger=util.getLogger("webfinger");return{getStorageInfo:getStorageInfo}}),define("lib/hardcoded",["./platform"],function(platform){function testIrisCouch(userAddress,options,cb){platform.ajax({url:"http://proxy.unhosted.org/irisCouchCheck?q=acct:"+userAddress,success:function(data){var obj;try{obj=JSON.parse(data)}catch(e){}obj?cb(null,obj):cb("err: unparsable response from IrisCouch check")},error:function(err){cb("err: during IrisCouch test:"+err)},timeout:options.timeout})}function mapToIrisCouch(userAddress){var parts=userAddress.split("@");return["libredocs","mail","browserid","me"].indexOf(parts[0])==-1?parts[0]+"@iriscouch.com":parts[2].substring(0,parts[2].indexOf("."))+"@iriscouch.com"}function guessStorageInfo(userAddress,options,cb){var parts=userAddress.split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9A-Za-z]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9A-Za-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{while(parts[1].indexOf(".")!=-1){if(guesses[parts[1]]){blueprint=guesses[parts[1]],cb(null,{rel:"https://www.w3.org/community/unhosted/wiki/personal-data-service-00",type:blueprint.type,href:blueprint.hrefPrefix+"/"+(blueprint.pathFormat=="user@host"?userAddress:parts[1]+"/"+parts[0]),properties:{"access-methods":["http://oauth.net/core/1.0/parameters/auth-header"],"auth-methods":["http://oauth.net/discovery/1.0/consumer-identity/static"],"auth-endpoint":blueprint.authPrefix+userAddress}});return}parts[1]=parts[1].substring(parts[1].indexOf(".")+1)}new Date<new Date("9/9/2012")?testIrisCouch(userAddress,options,cb):cb("err: not a guessable domain, and fakefinger-migration has ended")}}var guesses={"iriscouch.com":{type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#couchdb",authPrefix:"http://proxy.unhosted.org/OAuth.html?userAddress=",hrefPrefix:"http://proxy.unhosted.org/CouchDb",pathFormat:"host/user"}};return function(){var surfnetSaml={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/saml/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/saml",pathFormat:"user@host"},surfnetBrowserId={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/browserid/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/browserid",pathFormat:"user@host"},dutchUniversitiesNoSaml=["leidenuniv.nl","leiden.edu","uva.nl","vu.nl","eur.nl","maastrichtuniversity.nl","ru.nl","rug.nl","uu.nl","tudelft.nl","utwente.nl","tue.nl","tilburguniversity.edu","uvt.nl","wur.nl","wageningenuniversity.nl","ou.nl","lumc.nl","amc.nl","ahk.nl","cah.nl","driestar.nl","che.nl","chn.nl","hen.nl","huygens.nl","diedenoort.nl","efa.nl","dehaagsehogeschool.nl","hasdenbosch.nl","inholland.nl","hsbrabant.nl","dehorst.nl","kempel.nl","domstad.nl","hsdrenthe.nl","edith.nl","hsleiden.nl","interport.nl","schumann.nl","hsbos.nl","hva.nl","han.nl","hvu.nl","hesasd.nl","hes-rdam.nl","hku.nl","hmtr.nl","hzeeland.nl","hotelschool.nl","ichtus-rdam.nl","larenstein.nl","iselinge.nl","koncon.nl","kabk.nl","lhump.nl","msm.nl","hsmarnix.nl","nhtv.nl","nth.nl","nhl.nl","sandberg.nl","hsij.nl","stoas.nl","thrijswijk.nl","tio.nl","vhall.nl","chw.nl","hogeschoolrotterdam.nl"],dutchUniversitiesSaml=["surfnet.nl","fontys.nl"];for(var i=0;i<dutchUniversitiesSaml.length;i++)guesses[dutchUniversitiesSaml[i]]=surfnetSaml;for(var i=0;i<dutchUniversitiesNoSaml.length;i++)guesses[dutchUniversitiesNoSaml[i]]=surfnetBrowserId}(),{guessStorageInfo:guessStorageInfo}}),define("lib/getputdelete",["./platform","./util"],function(platform,util){function doCall(method,url,value,mimeType,token,cb,deadLine){var platformObj={url:url,method:method,error:function(err){cb(err)},success:function(data,headers){logger.debug("doCall cb "+url,"headers:",headers),cb(null,data,headers["Content-Type"]||defaultContentType)},timeout:3e3};platformObj.headers={Authorization:"Bearer "+token},mimeType&&(platformObj.headers["Content-Type"]=mimeType),platformObj.fields={withCredentials:"true"},method!="GET"&&(platformObj.data=value),logger.debug("platform.ajax "+url),platform.ajax(platformObj)}function get(url,token,cb){doCall("GET",url,null,null,token,function(err,data,mimetype){if(err==404)cb(null,undefined);else{if(url.substr(-1)=="/")try{data=JSON.parse(data)}catch(e){cb("unparseable directory index");return}cb(err,data,mimetype)}})}function put(url,value,mimeType,token,cb){logger.info("calling PUT "+url),doCall("PUT",url,value,mimeType,token,function(err,data){logger.debug("cb from PUT "+url),err==404?doPut(url,value,token,1,cb):cb(err,data)})}function set(url,valueStr,mimeType,token,cb){typeof valueStr=="undefined"?doCall("DELETE",url,null,null,token,cb):put(url,valueStr,mimeType,token,cb)}var logger=util.getLogger("getputdelete"),defaultContentType="application/octet-stream";return{get:get,set:set}}),define("lib/wireClient",["./getputdelete"],function(getputdelete){function set(key,value){localStorage.setItem(prefix+key,JSON.stringify(value))}function remove(key){localStorage.removeItem(prefix+key)}function get(key){var valStr=localStorage.getItem(prefix+key);if(typeof valStr=="string")try{return JSON.parse(valStr)}catch(e){localStorage.removeItem(prefix+key)}return null}function disconnectRemote(){remove("storageType"),remove("storageHref"),remove("bearerToken")}function getState(){return get("storageType")&&get("storageHref")?get("bearerToken")?"connected":"authing":"anonymous"}function on(eventType,cb){eventType=="error"&&(errorHandler=cb)}function resolveKey(storageType,storageHref,basePath,relPath){var item=(basePath.length?basePath+"/":"")+relPath;return storageHref+item}function setChain(driver,hashMap,mimeType,token,cb,timestamp){var i;for(i in hashMap)break;if(i){var thisOne=hashMap[i];delete hashMap[i],driver.set(i,thisOne,mimeType,token,function(err,timestamp){err?cb(err):setChain(driver,hashMap,mimeType,token,cb,timestamp)})}else cb(null,timestamp)}var prefix="remote_storage_wire_",errorHandler=function(){};return{get:function(path,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.get(resolveKey(storageType,storageHref,"",path),token,cb)},set:function(path,valueStr,mimeType,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.set(resolveKey(storageType,storageHref,"",path),valueStr,mimeType,token,cb)},setStorageInfo:function(type,href){set("storageType",type),set("storageHref",href)},getStorageHref:function(){return get("storageHref")},setBearerToken:function(bearerToken){set("bearerToken",bearerToken)},disconnectRemote:disconnectRemote,on:on,getState:getState}}),define("lib/store",["./util"],function(util){function fireChange(e){for(var i=0;i<onChange.length;i++)onChange[i](e)}function getNode(path){var valueStr=localStorage.getItem(prefixNodes+path),value;if(valueStr)try{value=JSON.parse(valueStr)}catch(e){}return value||(value={startAccess:null,startForce:null,timestamp:0,keep:!0,diff:{}}),value}function isDir(path){return typeof path!="string"&&(logger.error("Given path is not a string: ",path),doSomething()),path.substr(-1)=="/"}function getContainingDir(path){var parts=path.split("/");return parts[parts.length-1].length||parts.pop(),parts.length?(parts.pop(),parts.join("/")+(parts.length?"/":"")):undefined}function getFileName(path){var parts=path.split("/");return isDir(path)?parts[parts.length-2]+"/":parts[parts.length-1]}function getCurrTimestamp(){return(new Date).getTime()}function updateNode(path,node,outgoing,meta,timestamp){node?localStorage.setItem(prefixNodes+path,JSON.stringify(node)):localStorage.removeItem(prefixNodes+path);var containingDir=getContainingDir(path);if(containingDir){var parentNode=getNode(containingDir),parentData=getNodeData(parentNode)||{};if(meta){if(!parentData||!parentData[getFileName(path)])parentData[getFileName(path)]=0;updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!0)}else if(outgoing)node?parentData[getFileName(path)]=(new Date).getTime():delete parentData[getFileName(path)],parentNode.diff[getFileName(path)]=(new Date).getTime(),updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!0);else{if(node){if(!parentData[getFileName(path)]||parentData[getFileName(path)]<timestamp)parentData[getFileName(path)]=timestamp,delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp)}else parentData[getFileName(path)]&&(delete parentData[getFileName(path)],delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp));path.substr(-1)!="/"&&fireChange({path:path,origin:"remote",oldValue:undefined,newValue:node?getNodeData(node):undefined,timestamp:timestamp})}}}function forget(path){localStorage.removeItem(prefixNodes+path)}function forgetAll(){for(var i=0;i<localStorage.length;i++)localStorage.key(i).substr(0,prefixNodes.length)==prefixNodes&&(localStorage.removeItem(localStorage.key(i)),i--)}function on(eventName,cb){if(eventName!="change")throw"Unknown event: "+eventName;onChange.push(cb)}function getState(path){return"disconnected"}function updateNodeData(path,data){if(!path)throw console.trace(),"Path is required!";var encodedData;try{encodedData=JSON.stringify(data)}catch(exc){encodedData=data}localStorage.setItem(prefixNodesData+path,encodedData)}function setNodeData(path,data,outgoing,timestamp,mimeType){var node=getNode(path);mimeType||(mimeType="application/json"),node.mimeType=mimeType,timestamp||(timestamp=(new Date).getTime()),updateNodeData(path,data),updateNode(path,data?node:undefined,outgoing,!1,timestamp)}function getNodeData(path){typeof path=="object"&&(path=path.path);var valueStr=localStorage.getItem(prefixNodesData+path);if(!valueStr)return undefined;try{return JSON.parse(valueStr)}catch(exc){return valueStr}}function setNodeAccess(path,claim){var node=getNode(path);claim!=node.startAccess&&(claim=="rw"||node.startAccess==null)&&(node.startAccess=claim,updateNode(path,node,!1,!0))}function setNodeForce(path,force){var node=getNode(path);node.startForce=force,updateNode(path,node,!1,!0)}function clearDiff(path,i){var node=getNode(path);delete node.diff[i],updateNode(path,node,!1,!0)}var logger=util.getLogger("store"),onChange=[],prefixNodes="remote_storage_nodes:",prefixNodesData="remote_storage_node_data:";return typeof window!="undefined"&&window.addEventListener("storage",function(e){e.key.substring(0,prefixNodes.length==prefixNodes)&&(e.path=e.key.substring(prefixNodes.length),isDir(e.path)||(e.origin="device",fireChange(e)))}),{on:on,getNode:getNode,getNodeData:getNodeData,setNodeData:setNodeData,setNodeAccess:setNodeAccess,setNodeForce:setNodeForce,clearDiff:clearDiff,forget:forget,forgetAll:forgetAll}}),define("lib/sync",["./wireClient","./store","./util"],function(wireClient,store,util){function getState(path){return busy?"busy":"connected"}function setBusy(val){busy=val;for(var i=0;i<stateCbs.length;i++)stateCbs[i](val?"busy":"connected")}function on(eventType,cb){eventType=="state"&&stateCbs.push(cb)}function dirMerge(dirPath,remote,cached,diff,force,access,startOne,finishOne,clearCb){for(var i in remote)(!cached[i]&&!diff[i]||cached[i]<remote[i])&&pullNode(dirPath+i,force,access,startOne,finishOne);for(var i in cached)if(!remote[i]||cached[i]>remote[i])if(i.substr(-1)=="/")pullNode(dirPath+i,force,access,startOne,finishOne);else{var childNode=store.getNode(dirPath+i),childData=store.getNodeData(dirPath+i);startOne(),wireClient.set(dirPath+i,JSON.stringify(childData),"application/json",function(err){finishOne()})}for(var i in diff)cached[i]?remote[i]===cached[i]&&clearCb(i):remote[i]?(startOne(),wireClient.set(dirPath+i,undefined,undefined,function(err){finishOne()})):clearCb(i)}function pullNode(path,force,access,startOne,finishOne){var thisNode=store.getNode(path),thisData=store.getNodeData(path);!thisData&&path.substr(-1)=="/"&&(thisData={}),logger.debug("pullNode "+path,thisNode);if(thisNode.startAccess=="rw"||!access)access=thisNode.startAccess;thisNode.startForce&&(force=thisNode.startForce);if(access)startOne(),wireClient.get(path,function(err,data){!err&&data&&(path.substr(-1)=="/"?dirMerge(path,data,thisData,thisNode.diff,force,access,startOne,finishOne,function(i){store.clearDiff(path,i)}):store.setNodeData(path,data,!1)),finishOne(err)});else for(var i in thisData)i.substr(-1)=="/"&&pullNode(path+i,force,access,startOne,finishOne)}function fetchNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(err),outstanding--,outstanding==0&&(setBusy(!1),callback(errors||null,store.getNode(path)))}var outstanding=0,errors=[];setBusy(!0),pullNode(path,!1,!0,startOne,finishOne)}function syncNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(path),outstanding--,outstanding==0&&(setBusy(!1),callback&&callback(errors.length>0?errors:null))}if(wireClient.getState()=="anonymous"){callback&&callback(["not connected"]);return}var outstanding=0,errors=[];logger.info("syncNow "+path),setBusy(!0),pullNode(path,!1,!1,startOne,finishOne)}var prefix="_remoteStorage_",busy=!1,stateCbs=[],logger=util.getLogger("sync");return{syncNow:syncNow,fetchNow:fetchNow,getState:getState,on:on}}),define("lib/widget",["./assets","./webfinger","./hardcoded","./wireClient","./sync","./store","./platform"],function(assets,webfinger,hardcoded,wireClient,sync,store,platform){function translate(text){return text}function isRegistering(){return localStorage.getItem("remote_storage_registering")}function setRegistering(value){value===!1?localStorage.removeItem("remote_storage_registering"):localStorage.setItem("remote_storage_registering","true")}function calcWidgetStateOnLoad(){wc=wireClient;if(isRegistering())return"registering";var wireClientState=wireClient.getState();return wireClientState=="connected"?sync.getState():wireClientState}function setWidgetStateOnLoad(){setWidgetState(calcWidgetStateOnLoad())}function setWidgetState(state){widgetState=state,displayWidgetState(state,userAddress)}function getWidgetState(){return widgetState}function displayWidgetState(state,userAddress){var userAddress=localStorage.remote_storage_widget_useraddress,html="<style>"+assets.widgetCss+"</style>"+'<div id="remotestorage-state" class="'+state+'">'+'  <input id="remotestorage-connect-button" class="remotestorage-button" type="submit" value="'+translate("connect")+'"/>'+'  <span id="remotestorage-register-button" class="remotestorage-button">'+translate("get remoteStorage")+"</span>"+'  <img id="remotestorage-cube" src="'+assets.remoteStorageCube+'"/>'+'  <span id="remotestorage-disconnect">Disconnect '+(userAddress?"<strong>"+userAddress+"</strong>":"")+"</span>"+'  <a id="remotestorage-questionmark" href="http://unhosted.org/#remotestorage" target="_blank">?</a>'+'  <span class="infotext" id="remotestorage-infotext">This app allows you to use your own data storage!<br/>Click for more info on the Unhosted movement.</span>'+'  <input id="remotestorage-useraddress" type="text" value="me@local.dev" placeholder="you@remotestorage" autofocus="" />'+'  <a class="infotext" href="http://remotestoragejs.com/" target="_blank" id="remotestorage-devsonly">RemoteStorageJs is still in developer preview!<br/>Click for more info.</a>'+"</div>";platform.setElementHTML(connectElement,html),platform.eltOn("remotestorage-register-button","click",handleRegisterButtonClick),platform.eltOn("remotestorage-connect-button","click",handleConnectButtonClick),platform.eltOn("remotestorage-disconnect","click",handleDisconnectClick),platform.eltOn("remotestorage-cube","click",handleCubeClick),platform.eltOn("remotestorage-useraddress","type",handleWidgetTypeUserAddress)}function handleRegisterButtonClick(){setRegistering();var win=window.open("http://unhosted.org/en/a/register.html","Get your remote storage","resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=820,height=800,top=0,left=0");setWidgetState("registering")}function redirectUriToClientId(loc){if(loc.substring(0,"http://".length)=="http://")loc=loc.substring("http://".length);else{if(loc.substring(0,"https://".length)!="https://")return loc;loc=loc.substring("https://".length)}var hostParts=loc.split("/")[0].split("@");return hostParts.length>2?loc:(hostParts.length==2&&hostParts.shift(),hostParts[0])}function dance(endpoint){var endPointParts=endpoint.split("?"),queryParams=[];endPointParts.length==2?queryParams=endPointParts[1].split("&"):endPointParts.length>2&&errorHandler("more than one questionmark in auth-endpoint - ignoring");var loc=platform.getLocation(),scopesArr=[];for(var i in scopesObj)scopesArr.push(i+":"+scopesObj[i]);queryParams.push("response_type=token"),queryParams.push("scope="+encodeURIComponent(scopesArr.join(" "))),queryParams.push("redirect_uri="+encodeURIComponent(loc)),queryParams.push("client_id="+encodeURIComponent(redirectUriToClientId(loc))),platform.setLocation(endPointParts[0]+"?"+queryParams.join("&"))}function discoverStorageInfo(userAddress,cb){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?hardcoded.guessStorageInfo(userAddress,{timeout:3e3},function(err2,data2){err2?cb(err2):data2.type&&data2.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data2.type,data2.href),cb(null,data2.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from webfinger")}):data.type&&data.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data.type,data.href),cb(null,data.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from hardcoded")})}function handleConnectButtonClick(){widgetState=="typing"?(userAddress=platform.getElementValue("remotestorage-useraddress"),localStorage.remote_storage_widget_useraddress=userAddress,setWidgetState("connecting"),discoverStorageInfo(userAddress,function(err,auth){err?(alert("webfinger discovery failed! (sorry this is still a developer preview! developers, point local.dev to 127.0.0.1, then run sudo node server/nodejs-example.js from the repo)"),setWidgetState("failed")):dance(auth)})):setWidgetState("typing")}function handleDisconnectClick(){widgetState=="connected"?(wireClient.disconnectRemote(),store.forgetAll(),setWidgetState("anonymous")):alert("you cannot disconnect now, please wait until the cloud is up to date...")}function handleCubeClick(){sync.syncNow("/",function(errors){})}function handleWidgetTypeUserAddress(){setRegistering(!1),console.log("handleWidgetTypeUserAddress")}function handleWidgetHover(){console.log("handleWidgetHover")}function display(setConnectElement,setLocale){var tokenHarvested=platform.harvestParam("access_token"),storageRootHarvested=platform.harvestParam("storage_root"),storageApiHarvested=platform.harvestParam("storage_api"),authorizeEndpointHarvested=platform.harvestParam("authorize_endpoint");tokenHarvested&&wireClient.setBearerToken(tokenHarvested),storageRootHarvested&&wireClient.setStorageInfo(storageApiHarvested?storageApiHarvested:"2012.04",storageRootHarvested),authorizeEndpointHarvested&&dance(authorizeEndpointHarvested),connectElement=setConnectElement,locale=setLocale,wireClient.on("error",function(err){platform.alert(translate(err))}),sync.on("state",setWidgetState),setWidgetStateOnLoad(),window.onkeydown=function(evt){if(evt.ctrlKey&&evt.which==83)return evt.preventDefault(),console.log("CTRL+S - SYNCING"),sync.syncNow("/",function(errors){}),!1}}function addScope(module,mode){if(!scopesObj[module]||mode=="rw")scopesObj[module]=mode}var locale="en",connectElement,widgetState,userAddress,scopesObj={};return{display:display,addScope:addScope,getState:getWidgetState}}),define("lib/baseClient",["./sync","./store","./util"],function(sync,store,util){function bindContext(callback,context){return context?function(){return callback.apply(context,arguments)}:callback}function extractModuleName(path){if(path&&typeof path=="string"){var parts=path.split("/");if(parts.length>3&&parts[1]=="public")return parts[2];if(parts.length>2)return parts[1]}}function fireChange(moduleName,eventObj){if(moduleName&&moduleChangeHandlers[moduleName])for(var i=0;i<moduleChangeHandlers[moduleName].length;i++)moduleChangeHandlers[moduleName][i](eventObj)}function fireError(str){for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](str)}function set(path,absPath,valueStr){if(isDir(absPath)){fireError("attempt to set a value to a directory "+absPath);return}var node=store.getNode(absPath),changeEvent={origin:"window",oldValue:store.getNodeData(node),newValue:valueStr,path:path},ret=store.setNodeData(absPath,valueStr,!0),moduleName=extractModuleName(absPath);return fireChange(moduleName,changeEvent),fireChange("root",changeEvent),ret}function claimAccess(path,claim){store.setNodeAccess(path,claim)}function isDir(path){return typeof path!="string"&&doSomething(),path.substr(-1)=="/"}var moduleChangeHandlers={},errorHandlers=[],logger=util.getLogger("baseClient");return store.on("change",function(e){var moduleName=extractModuleName(e.path);fireChange(moduleName,e),fireChange("root",e)}),{claimAccess:claimAccess,getInstance:function(moduleName,isPublic){function makePath(path){return moduleName=="root"?path:(isPublic?"/public/":"/")+moduleName+"/"+path}function nodeGivesAccess(path,mode){var node=store.getNode(path);logger.debug("check node access",path,mode,node);var access=(new RegExp(mode)).test(node.startAccess);if(access)return!0;if(path.length>0)return nodeGivesAccess(path.replace(/[^\/]+\/?$/,""))}function ensureAccess(mode){var path=makePath(moduleName=="root"?"/":"");if(!nodeGivesAccess(path,mode))throw"Not sufficient access claimed for node at "+path}return{on:function(eventType,cb,context){eventType=="change"?moduleName&&(moduleChangeHandlers[moduleName]||(moduleChangeHandlers[moduleName]=[]),moduleChangeHandlers[moduleName].push(bindContext(cb,context))):eventType=="error"&&errorHandlers.push(bindContext(cb,context))},getObject:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath);return data&&typeof data=="object"&&delete data["@type"],data}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node);data&&typeof data=="object"&&delete data["@type"],bindContext(cb,context)(data)})},getListing:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath),arr=[];for(var i in data)arr.push(i);return arr}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node),arr=[];for(var i in data)arr.push(i);bindContext(cb,context)(arr)})},getDocument:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath);return{mimeType:node.mimeType,data:store.getNodeData(node)}}sync.fetchNow(absPath,function(err,node){bindContext(cb,context)({mimeType:node.mimeType,data:store.getNodeData(node)})})},remove:function(path,cb,context){ensureAccess("w");var ret=set(path,makePath(path));return this.syncNow(cb,context),ret},storeObject:function(type,path,obj,cb,context){ensureAccess("w");if(typeof obj!="object")throw"storeObject needs to get an object as value!";obj["@type"]="https://remotestoragejs.com/spec/modules/"+moduleName+"/"+type;var ret=set(path,makePath(path),obj,"application/json");return this.sync(path),this.syncNow(cb,context),ret},storeDocument:function(mimeType,path,data,cb,context){ensureAccess("w");var ret=set(path,makePath(path),data,mimeType);return this.syncNow(cb,context),ret},getItemURL:function(path){var base=remoteStorage.getStorageHref();return base?(base.substr(-1)!="/"&&(base+="/"),base+makePath(path)):null},getCurrentWebRoot:function(){return"https://example.com/this/is/an/example/"+(isPublic?"public/":"")+moduleName+"/"},sync:function(path,switchVal){var absPath=makePath(path);store.setNodeForce(absPath,switchVal!=0)},syncNow:function(cb,context){sync.syncNow(makePath(""),cb?bindContext(cb,context):function(errors){errors&&errors.length>0&&(logger.error("Error syncing: ",errors),fireError(errors))})},getState:function(path){}}}}}),define("lib/nodeConnect",["./wireClient","./webfinger"],function(wireClient,webfinger){return{setUserAddress:function(userAddress,callback){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?console.error("Failed to look up storage info for user "+userAddress+": ",err):wireClient.setStorageInfo(data.type,data.href),callback(err)})},setStorageInfo:wireClient.setStorageInfo,setBearerToken:wireClient.setBearerToken}}),define("remoteStorage",["require","./lib/widget","./lib/baseClient","./lib/store","./lib/sync","./lib/wireClient","./lib/nodeConnect","./lib/util"],function(require,widget,baseClient,store,sync,wireClient,nodeConnect,util){function deprecate(oldFn,newFn){logger.error("DEPRECATION: "+oldFn+" is deprecated! Use "+newFn+" instead.")}var claimedModules={},modules={},logger=util.getLogger("base"),remoteStorage={defineModule:function(moduleName,builder){logger.debug("DEFINE MODULE",moduleName);var module=builder(baseClient.getInstance(moduleName,!1),baseClient.getInstance(moduleName,!0));modules[moduleName]=module,this[moduleName]=module.exports,logger.debug("Module defined: "+moduleName,module,this)},getModuleList:function(){return Object.keys(modules)},getClaimedModuleList:function(){return Object.keys(claimedModules)},getModuleInfo:function(moduleName){return modules[moduleName]},claimAccess:function(claimed){if(typeof claimed!="object"||claimed instanceof Array){claimed instanceof Array||(claimed=Array.prototype.slice.call(arguments));var _modules=claimed,mode="rw";claimed={};var lastArg=arguments[arguments.length-1];typeof lastArg=="string"&&lastArg.match(/^rw?$/)&&(mode=lastArg,delete arguments[arguments.length-1]);for(var i in _modules)claimed[_modules[i]]=mode}for(var moduleName in claimed)this.claimModuleAccess(moduleName,claimed[moduleName])},claimModuleAccess:function(moduleName,mode){logger.debug("claimModuleAccess",moduleName,mode);if(!moduleName in modules)throw"Module not defined: "+moduleName;if(moduleName in claimedModules)return;mode||(mode="r"),moduleName=="root"?(moduleName="",widget.addScope("",mode),baseClient.claimAccess("/",mode)):(widget.addScope(moduleName,mode),baseClient.claimAccess("/"+moduleName+"/",mode),baseClient.claimAccess("/public/"+moduleName+"/",mode)),claimedModules[moduleName]=!0},loadModule:function(){deprecate("remoteStorage.loadModule","remoteStorage.claimAccess"),this.claimModuleAccess.apply(this,arguments)},setBearerToken:function(bearerToken,claimedScopes){wireClient.setBearerToken(bearerToken),baseClient.claimScopes(claimedScopes)},disconnectRemote:wireClient.disconnectRemote,flushLocal:store.forgetAll,syncNow:sync.syncNow,displayWidget:widget.display,getWidgetState:widget.getState,setStorageInfo:wireClient.setStorageInfo,getStorageHref:wireClient.getStorageHref,nodeConnect:nodeConnect,util:util};return remoteStorage}),global.localStorage={getItem:function(key){return this[key]},setItem:function(key,value){this[key]=value},removeItem:function(key){delete this[key]}},module.exports=require("remoteStorage")})()
\ No newline at end of file
+(function(){var requirejs,require,define;(function(undef){function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=map&&map["*"]||{};if(name&&name.charAt(0)==="."&&baseName){baseParts=baseParts.slice(0,baseParts.length-1),name=baseParts.concat(name.split("/"));for(i=0;i<name.length;i+=1){part=name[i];if(part===".")name.splice(i,1),i-=1;else if(part===".."){if(i===1&&(name[2]===".."||name[0]===".."))break;i>0&&(name.splice(i-1,2),i-=2)}}name=name.join("/")}if((baseParts||starMap)&&map){nameParts=name.split("/");for(i=nameParts.length;i>0;i-=1){nameSegment=nameParts.slice(0,i).join("/");if(baseParts)for(j=baseParts.length;j>0;j-=1){mapValue=map[baseParts.slice(0,j).join("/")];if(mapValue){mapValue=mapValue[nameSegment];if(mapValue){foundMap=mapValue,foundI=i;break}}}if(foundMap)break;!foundStarMap&&starMap&&starMap[nameSegment]&&(foundStarMap=starMap[nameSegment],starI=i)}!foundMap&&foundStarMap&&(foundMap=foundStarMap,foundI=starI),foundMap&&(nameParts.splice(0,foundI,foundMap),name=nameParts.join("/"))}return name}function makeRequire(relName,forceSync){return function(){return req.apply(undef,aps.call(arguments,0).concat([relName,forceSync]))}}function makeNormalize(relName){return function(name){return normalize(name,relName)}}function makeLoad(depName){return function(value){defined[depName]=value}}function callDep(name){if(waiting.hasOwnProperty(name)){var args=waiting[name];delete waiting[name],defining[name]=!0,main.apply(undef,args)}if(!defined.hasOwnProperty(name))throw new Error("No "+name);return defined[name]}function makeMap(name,relName){var prefix,plugin,index=name.indexOf("!");return index!==-1?(prefix=normalize(name.slice(0,index),relName),name=name.slice(index+1),plugin=callDep(prefix),plugin&&plugin.normalize?name=plugin.normalize(name,makeNormalize(relName)):name=normalize(name,relName)):name=normalize(name,relName),{f:prefix?prefix+"!"+name:name,n:name,p:plugin}}function makeConfig(name){return function(){return config&&config.config&&config.config[name]||{}}}var main,req,defined={},waiting={},config={},defining={},aps=[].slice;main=function(name,deps,callback,relName){var cjsModule,depName,ret,map,i,args=[],usingExports;relName=relName||name;if(typeof callback=="function"){deps=!deps.length&&callback.length?["require","exports","module"]:deps;for(i=0;i<deps.length;i+=1){map=makeMap(deps[i],relName),depName=map.f;if(depName==="require")args[i]=makeRequire(name);else if(depName==="exports")args[i]=defined[name]={},usingExports=!0;else if(depName==="module")cjsModule=args[i]={id:name,uri:"",exports:defined[name],config:makeConfig(name)};else if(defined.hasOwnProperty(depName)||waiting.hasOwnProperty(depName))args[i]=callDep(depName);else if(map.p)map.p.load(map.n,makeRequire(relName,!0),makeLoad(depName),{}),args[i]=defined[depName];else if(!defining[depName])throw new Error(name+" missing "+depName)}ret=callback.apply(defined[name],args);if(name)if(cjsModule&&cjsModule.exports!==undef&&cjsModule.exports!==defined[name])defined[name]=cjsModule.exports;else if(ret!==undef||!usingExports)defined[name]=ret}else name&&(defined[name]=callback)},requirejs=require=req=function(deps,callback,relName,forceSync,alt){return typeof deps=="string"?callDep(makeMap(deps,callback).f):(deps.splice||(config=deps,callback.splice?(deps=callback,callback=relName,relName=null):deps=undef),callback=callback||function(){},typeof relName=="function"&&(relName=forceSync,forceSync=alt),forceSync?main(undef,deps,callback,relName):setTimeout(function(){main(undef,deps,callback,relName)},15),req)},req.config=function(cfg){return config=cfg,req},define=function(name,deps,callback){deps.splice||(callback=deps,deps=[]),waiting[name]=[name,deps,callback]},define.amd={jQuery:!0}})(),define("../build/lib/almond",function(){}),define("lib/assets",[],function(){return{remoteStorageIcon:"data:image/png;base64,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",remoteStorageCube:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAR2SURBVFiFtddfqGVVHQfwz2/vfZ28c2WgP6hMoYkUV4qIYnSKmaQYwaaJ3oLeUnpJmDCmUhCaIhhKGelhelCqN9+ECKdAxR6kgnJASBN9KTGwP2oKTtyZs8/+9bDXPufcfe51xju6YLHX2fu3ft/v+q7fWb/fisy0o3brez6qmt4Luvo7frvx/E7cxNsmcCj2WGnuEb6JaXlbSz8zaX/ksXzj3SHwg6j8aeU28jjeh8TZ8nU3Aq8Sx+2b/ML3s3vnCHxp5YB0Hz6OTkgpMax2jxBSoMJfhGMemTx5aQQOxzWsnCC/gm6hZ+mvFMv36xUYCJQev2Jyt9P54tsj8OVYNW2+izuxIkzlAoGUQuLlMuNqKcQCgVBJNSa4X93+xK/zfxcmcLj5GtUJ8ipMC/i0gA/PQYF/lFkfHClQFxJ1IVET/6S72+n2oa0JHL7s0+RPsR9tAZuOxuNtGKS9xpL8A7BmNP4j8S2nzz+lGJaWDxB7RyCbV54DkZiSrbAhbJBt/25LtUbEY2+P1bdmQY1V8mr8DruET5Z9n4NHTOmmZK9A2ihzp3RdL3tVy+z16OeG0ElncI48yGzeogIzQgexByelp2fMZ+CDAtFK56XzxFwBXSE6C9incbL4PDha9BKBPrjCddJRVT5DHsMLczkLUGhFbPR9iJNYjJUXyGOqfEY6KlxnHrybVjwm0JVDJmV8FZ8TeZysZdyBK9FKXb/6mdTZ+4uXRXcKUxnHpavKdqV58G5JYJFdLvT3yuok3ROiuY3JZ3Rxu7CH7lxvHlPpNVX+nJU/yMk9VJ8nm5GvMc42W6Bwnhl2KRyQ7cOyaqy1R0ScEvFq6aestUdk1cj2YeEA3RwwtwbfSoHtxxmJXeS3nV25RR0/9KnJL8GZyz7i7MoD5MfQ9LZ5YZ+WY+AiW16vc8if/av8PkRevxNPiwTiLceRISPIM3iUOGxa/wfUbiTvxy3ETb3tRfi0HAMx+xgLY1XIeAUPYoO4S+YNqupyVXW5zBuIu/pvHuxtq5j5DLHkfxsFxoaBlN1vVKbEN2TQ5wdYLc8++YibhZvJx3VZizgy8rVEYhwDfUKZFxd/Jf8m4gsydtENJ17TZ8lcLbOGrFfJrKmOiDxHPk58GJ8oPqu3UmDOLr2B5/AhYt08K9Z9AMdAsCeQml6BnKdiriC+iP/iKWkdH7gQgSRfQoi4SWoLcMqsRaUcZiX1xu4yrZmpp6p721lavlLYK/PfeIm4djsCE7xZDNqSVocV9evNJCKIjq6TuTbbAlWvQGZfiCwWJqkqqb7pMUwG0IV/QXwdz1ouKjZXOP021EQjqt2i2k00/Tv1Evj8OfRnC1aPeokl2e/LrM/aYUk2Pgc43T6knqzjBCZytqqhpGpK0DXCmrC26d1Qgs3BJzihnqyPwbdWYJMaFyzLnyuW6yMFLrEsH7ftLyZ/LxbX7vRisrwFW7VHJk/a1+4njuL1udx5Rd9nW/A6cdS+dv/FgHPpl9PhorH67l9Ox62/nv8YdPX3dno9/z+G+TGrzjgPKwAAAABJRU5ErkJggg==",widgetCss:"#remotestorage-state { position:fixed; top:15px; right:15px; height:32px; width:275px; font:normal 16px/100% sans-serif; z-index:99999; background:rgba(0,0,0,.3); padding:5px; border-radius:7px; box-shadow:0 1px rgba(255,255,255,.05), inset 0 1px rgba(0,0,0,.05); transition:width 500ms, background 500ms; }\n#remotestorage-state.connected, #remotestorage-state.busy, #remotestorage-state.offline { width:32px; background:none; box-shadow:none; }\n.remotestorage-button { margin:0; padding:.3em; font-size:14px; height:26px !important; background:#ddd; color:#333; border:1px solid #ccc; border-radius:3px; box-shadow:0 1px 1px #fff inset; }\n#remotestorage-register-button { position:absolute; left:25px; top:8px; max-height:16px; text-decoration:none; font-weight:normal; }\n#remotestorage-connect-button { position:absolute; right:8px; top:8px; padding:0 0 0 17px; width:90px; cursor:pointer; text-align:left; border-radius:0 3px 3px 0; font-weight:normal; }\n#remotestorage-connect-button:hover, #remotestorage-connect-button:focus, .remotestorage-button:hover, .remotestorage-button:focus { background:#eee; color:#000; text-decoration:none; }\n#remotestorage-useraddress { position:absolute; left:25px; top:8px; margin:0; padding:0 17px 0 3px; height:25px; width:142px; background:#eee; color:#333; border:0; border-radius:3px 0 0 3px; box-shadow:0 1px #fff, inset 0 1px #999; font-weight:normal; font-size:14px;}\n#remotestorage-useraddress:hover, #remotestorage-useraddress:focus { background:#fff; color:#000; }\n#remotestorage-cube { position:absolute; right:84px; -webkit-transition:right 500ms; -moz-transition:right 500ms; transition:right 500ms; z-index:99997; }\n#remotestorage-questionmark { position:absolute; left:0; padding:9px 8px; color:#fff; text-decoration:none; z-index:99999; font-weight:normal; }\n.infotext { position:absolute; left:0; top:0; width:255px; height:32px; padding:6px 5px 4px 25px; font-size:10px; background:black; color:white; border-radius:7px; opacity:.85; text-decoration:none; white-space:nowrap; z-index:99998; }\n#remotestorage-questiomark:hover { color:#fff; }\n#remotestorage-questionmark:hover+#remotestorage-infotext { display:inline; }\n#remotestorage-state.busy #remotestorage-cube, #remotestorage-state.connecting #remotestorage-cube {   -webkit-animation-name:remotestorage-loading; -webkit-animation-duration:2s; -webkit-animation-iteration-count:infinite; -webkit-animation-timing-function:linear;\n   -moz-animation-name:remotestorage-loading; -moz-animation-duration:2s; -moz-animation-iteration-count:infinite; -moz-animation-timing-function:linear;\n   -o-animation-name:remotestorage-loading; -o-animation-duration:2s; -o-animation-iteration-count:infinite; -o-animation-timing-function:linear;\n   -ms-animation-name:remotestorage-loading; -ms-animation-duration:2s; -ms-animation-iteration-count:infinite; -ms-animation-timing-function:linear; }\n   @-webkit-keyframes remotestorage-loading { from{-webkit-transform:rotate(0deg)} to{-webkit-transform:rotate(360deg)} }\n   @-moz-keyframes remotestorage-loading { from{-moz-transform:rotate(0deg)} to{-moz-transform:rotate(360deg)} }\n   @-o-keyframes remotestorage-loading { from{-o-transform:rotate(0deg)} to{-o-transform:rotate(360deg)} }\n   @-ms-keyframes remotestorage-loading { from{-ms-transform:rotate(0deg)} to{ -ms-transform:rotate(360deg)} }\n#remotestorage-connect-button, #remotestorage-questionmark, #remotestorage-register-button, #remotestorage-cube, #remotestorage-useraddress, #remotestorage-infotext, #remotestorage-devsonly, #remotestorage-disconnect { display:none }\n#remotestorage-state.anonymous #remotestorage-cube, #remotestorage-state.anonymous #remotestorage-connect-button, #remotestorage-state.anonymous #remotestorage-register-button, #remotestorage-state.anonymous #remotestorage-questionmark { display: block }\n#remotestorage-state.registering #remotestorage-cube, #remotestorage-state.registering #remotestorage-connect-button, #remotestorage-state.registering #remotestorage-register-button, #remotestorage-state.registering #remotestorage-questionmark { display: block }\n#remotestorage-state.interrupted #remotestorage-cube, #remotestorage-state.interrupted #remotestorage-connect-button, #remotestorage-state.interrupted #remotestorage-register-button, #remotestorage-state.interrupted #remotestorage-questionmark { display: block }\n#remotestorage-state.failed #remotestorage-cube, #remotestorage-state.failed #remotestorage-connect-button, #remotestorage-state.failed #remotestorage-register-button, #remotestorage-state.failed #remotestorage-questionmark { display: block }\n#remotestorage-state.typing #remotestorage-cube, #remotestorage-state.typing #remotestorage-connect-button, #remotestorage-state.typing #remotestorage-useraddress, #remotestorage-state.typing #remotestorage-questionmark { display: block }\n#remotestorage-state.connected #remotestorage-cube, #remotestorage-state.busy #remotestorage-cube, #remotestorage-state.offline #remotestorage-cube { right:0; opacity:.5; cursor:pointer; display: block }\n#remotestorage-state.devsonly #remotestorage-devsonly { display: block }\n#remotestorage-disconnect { position:absolute; right:6px; top:9px; padding:5px 28px 2px 6px; height:17px; white-space:nowrap; font-size:10px; background:#000; color:#fff; border-radius:5px; opacity:.5; text-decoration:none; z-index:99996; }\n#remotestorage-disconnect strong { font-weight:bold; }\n#remotestorage-state.connected #remotestorage-cube:hover, #remotestorage-state.busy #remotestorage-cube:hover, #remotestorage-state.offline #remotestorage-cube:hover { opacity:1; }\n#remotestorage-state.connected #remotestorage-disconnect:hover, #remotestorage-state.busy #remotestorage-disconnect:hover, #remotestorage-state.offline #remotestorage-disconnect:hover { display:inline; }\n#remotestorage-state.connected #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.busy #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.offline #remotestorage-cube:hover+#remotestorage-disconnect { display:inline; }\n"}}),define("lib/util",[],function(){var loggers={},silentLogger={},knownLoggers=["sync","webfinger","getputdelete","platform","baseClient"],util={toArray:function(enumerable){var a=[];for(var i in enumerable)a.push(enumerable[i]);return a},getLogger:function(name){return loggers[name]||(loggers[name]={info:function(){this.log("info",util.toArray(arguments))},debug:function(){this.log("debug",util.toArray(arguments),"debug")},error:function(){this.log("error",util.toArray(arguments),"error")},log:function(level,args,type){if(silentLogger[name])return;type||(type="log"),args.unshift("["+name.toUpperCase()+"] -- "+level+" "),(console[type]||console.log).apply(console,args)}}),loggers[name]},silenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)silentLogger[names[i]]=!0},unsilenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)delete silentLogger[names[i]]},silenceAllLoggers:function(){this.silenceLogger.apply(this,knownLoggers)},unsilenceAllLoggers:function(){this.unsilenceLogger.apply(this,knownLoggers)}};return util}),define("lib/platform",["./util"],function(util){function browserParseHeaders(rawHeaders){var headers={},lines=rawHeaders.split(/\r?\n/),lastKey=null,md,key,value;for(var i=0;i<lines.length;i++){if(lines[i].length==0)continue;(md=lines[i].match(/^([^:]+):\s*(.+)$/))?(key=md[1],value=md[2],headers[key]=value,lastKey=key):(md=lines[i].match(/^\s+(.+)$/))?(key=lastKey,value=md[1],headers[key]=headers[key]+value):logger.error("Failed to parse header line: "+lines[i])}return headers}function ajaxBrowser(params){var timedOut=!1,timer;params.timeout&&(timer=window.setTimeout(function(){timedOut=!0,params.error("timeout")},params.timeout));var xhr=new XMLHttpRequest;params.method||(params.method="GET"),xhr.open(params.method,params.url,!0);if(params.headers)for(var header in params.headers)xhr.setRequestHeader(header,params.headers[header]);logger.debug("A "+params.url),xhr.onreadystatechange=function(){xhr.readyState==4&&!timedOut&&(logger.debug("B "+params.url),timer&&window.clearTimeout(timer),logger.debug("xhr cb "+params.url),xhr.status==200||xhr.status==201||xhr.status==204||xhr.status==207?params.success(xhr.responseText,browserParseHeaders(xhr.getAllResponseHeaders())):params.error(xhr.status))},logger.debug("xhr "+params.url),typeof params.data=="string"?xhr.send(params.data):xhr.send()}function ajaxExplorer(params){var xdr=new XDomainRequest;xdr.timeout=params.timeout||3e3,xdr.open(params.method,params.url),xdr.onload=function(){xdr.status==200||xdr.status==201||xdr.status==204?params.success(xhr.responseText):params.error(xhr.status)},xdr.onerror=function(){err("unknown error")},xdr.ontimeout=function(){err(timeout)},params.data?xdr.send(params.data):xdr.send()}function ajaxNode(params){function normalizeHeaders(headers){var h={};for(var key in headers)h[key.replace(/(?:^|\-)[a-z]/g,function(match){return match.toUpperCase()})]=headers[key];return h}var http=require("http"),https=require("https"),url=require("url");params.method||(params.method="GET"),params.data?params.headers["content-length"]=params.data.length:params.data=null;var urlObj=url.parse(params.url),options={method:params.method,host:urlObj.hostname,path:urlObj.path,port:urlObj.port?port:urlObj.protocol=="https:"?443:80,headers:params.headers},timer,timedOut;params.timeout&&(timer=setTimeout(function(){params.error("timeout"),timedOut=!0},params.timeout));var lib=urlObj.protocol=="https:"?https:http,request=lib.request(options,function(response){var str="";response.setEncoding("utf8"),response.on("data",function(chunk){str+=chunk}),response.on("end",function(){timer&&clearTimeout(timer),timedOut||(response.statusCode==200||response.statusCode==201||response.statusCode==204?params.success(str,normalizeHeaders(response.headers)):params.error(response.statusCode))})});request.on("error",function(e){timer&&clearTimeout(timer),params.error(e.message)}),params.data?request.end(params.data):request.end()}function parseXmlBrowser(str,cb){var tree=(new DOMParser).parseFromString(str,"text/xml"),nodes=tree.getElementsByTagName("Link"),obj={Link:[]};for(var i=0;i<nodes.length;i++){var link={};if(nodes[i].attributes)for(var j=0;j<nodes[i].attributes.length;j++)link[nodes[i].attributes[j].name]=nodes[i].attributes[j].value;var props=nodes[i].getElementsByTagName("Property");link.properties={},xyz=props;for(var k=0;k<props.length;k++)link.properties[props[k].getAttribute("type")]=props[k].childNodes[0].nodeValue;link.rel&&obj.Link.push({"@":link})}cb(null,obj)}function parseXmlNode(str,cb){var xml2js=require("xml2js");(new xml2js.Parser).parseString(str,cb)}function harvestParamNode(){}function harvestParamBrowser(param){if(location.hash.length){var pairs=location.hash.substring(1).split("&");for(var i=0;i<pairs.length;i++)if(pairs[i].substring(0,(param+"=").length)==param+"="){var ret=decodeURIComponent(pairs[i].substring((param+"=").length));return delete pairs[i],location="#"+pairs.join("&"),ret}}}function setElementHtmlNode(eltName,html){}function setElementHtmlBrowser(eltName,html){var elt=eltName;elt instanceof Element||(elt=document.getElementById(eltName)),elt.innerHTML=html}function getElementValueNode(eltName){}function getElementValueBrowser(eltName){return document.getElementById(eltName).value}function eltOnNode(eltName,eventType,cb){}function eltOnBrowser(eltName,eventType,cb){eventType=="click"?document.getElementById(eltName).onclick=cb:eventType=="hover"?document.getElementById(eltName).onmouseover=cb:eventType=="type"&&(document.getElementById(eltName).onkeyup=cb)}function getLocationBrowser(){return window.location.href.split("#")[0]}function getLocationNode(){}function setLocationBrowser(location){window.location=location}function setLocationNode(){}function alertBrowser(str){alert(str)}function alertNode(str){console.log(str)}var logger=util.getLogger("platform");return typeof window=="undefined"?{ajax:ajaxNode,parseXml:parseXmlNode,harvestParam:harvestParamNode,setElementHTML:setElementHtmlNode,getElementValue:getElementValueNode,eltOn:eltOnNode,getLocation:getLocationNode,setLocation:setLocationNode,alert:alertNode}:window.XDomainRequest?{ajax:ajaxExplorer,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}:{ajax:ajaxBrowser,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}}),define("lib/webfinger",["./platform","./util"],function(platform,util){function userAddress2hostMetas(userAddress,cb){var parts=userAddress.toLowerCase().split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9a-z\-\_]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9a-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{var query="?resource=acct:"+encodeURIComponent(userAddress);cb(null,["https://"+parts[1]+"/.well-known/host-meta.json"+query,"https://"+parts[1]+"/.well-known/host-meta"+query,"http://"+parts[1]+"/.well-known/host-meta.json"+query,"http://"+parts[1]+"/.well-known/host-meta"+query])}}function fetchXrd(addresses,timeout,cb){var firstAddress=addresses.shift();firstAddress?platform.ajax({url:firstAddress,success:function(data){parseAsJrd(data,function(err,obj){err?parseAsXrd(data,function(err,obj){err?fetchXrd(addresses,timeout,cb):cb(null,obj)}):cb(null,obj)})},error:function(data){fetchXrd(addresses,timeout,cb)},timeout:timeout}):cb("could not fetch xrd")}function parseAsXrd(str,cb){platform.parseXml(str,function(err,obj){if(err)cb(err);else if(obj&&obj.Link){var links={};if(obj.Link&&obj.Link["@"])obj.Link["@"].rel&&(links[obj.Link["@"].rel]=obj.Link["@"]);else for(var i=0;i<obj.Link.length;i++)obj.Link[i]["@"]&&obj.Link[i]["@"].rel&&(links[obj.Link[i]["@"].rel]=obj.Link[i]["@"]);cb(null,links)}else cb("found valid xml but with no Link elements in there")})}function parseAsJrd(str,cb){var obj;try{obj=JSON.parse(str)}catch(e){cb("not valid JSON");return}obj.links||cb("JRD contains no links");var links={};for(var i=0;i<obj.links.length;i++)obj.links[i].rel&&(links[obj.links[i].rel]=obj.links[i]);cb(null,links)}function parseRemoteStorageLink(obj,cb){obj&&obj.href&&obj.type&&obj.properties&&obj.properties["auth-endpoint"]?cb(null,obj):cb("could not extract storageInfo from lrdd")}function getStorageInfo(userAddress,options,cb){userAddress2hostMetas(userAddress,function(err1,hostMetaAddresses){logger.debug("HOST META ADDRESSES",hostMetaAddresses,"(error: ",err1,")"),err1?cb(err1):fetchXrd(hostMetaAddresses,options.timeout,function(err2,hostMetaLinks){if(err2)cb("could not fetch host-meta for "+userAddress);else if(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage)parseRemoteStorageLink(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage,cb);else if(hostMetaLinks.lrdd&&hostMetaLinks.lrdd.template){var parts=hostMetaLinks.lrdd.template.split("{uri}"),lrddAddresses=[parts.join("acct:"+userAddress),parts.join(userAddress)];fetchXrd(lrddAddresses,options.timeout,function(err4,lrddLinks){err4?cb("could not fetch lrdd for "+userAddress):lrddLinks.remoteStorage?parseRemoteStorageLink(lrddLinks.remoteStorage,cb):lrddLinks.remotestorage?parseRemoteStorageLink(lrddLinks.remotestorage,cb):cb("could not extract storageInfo from lrdd")})}else cb("could not extract lrdd template from host-meta")})})}var logger=util.getLogger("webfinger");return{getStorageInfo:getStorageInfo}}),define("lib/hardcoded",["./platform"],function(platform){function testIrisCouch(userAddress,options,cb){platform.ajax({url:"http://proxy.unhosted.org/irisCouchCheck?q=acct:"+userAddress,success:function(data){var obj;try{obj=JSON.parse(data)}catch(e){}obj?cb(null,obj):cb("err: unparsable response from IrisCouch check")},error:function(err){cb("err: during IrisCouch test:"+err)},timeout:options.timeout})}function mapToIrisCouch(userAddress){var parts=userAddress.split("@");return["libredocs","mail","browserid","me"].indexOf(parts[0])==-1?parts[0]+"@iriscouch.com":parts[2].substring(0,parts[2].indexOf("."))+"@iriscouch.com"}function guessStorageInfo(userAddress,options,cb){var parts=userAddress.split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9A-Za-z]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9A-Za-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{while(parts[1].indexOf(".")!=-1){if(guesses[parts[1]]){blueprint=guesses[parts[1]],cb(null,{rel:"https://www.w3.org/community/unhosted/wiki/personal-data-service-00",type:blueprint.type,href:blueprint.hrefPrefix+"/"+(blueprint.pathFormat=="user@host"?userAddress:parts[1]+"/"+parts[0]),properties:{"access-methods":["http://oauth.net/core/1.0/parameters/auth-header"],"auth-methods":["http://oauth.net/discovery/1.0/consumer-identity/static"],"auth-endpoint":blueprint.authPrefix+userAddress}});return}parts[1]=parts[1].substring(parts[1].indexOf(".")+1)}new Date<new Date("9/9/2012")?testIrisCouch(userAddress,options,cb):cb("err: not a guessable domain, and fakefinger-migration has ended")}}var guesses={"iriscouch.com":{type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#couchdb",authPrefix:"http://proxy.unhosted.org/OAuth.html?userAddress=",hrefPrefix:"http://proxy.unhosted.org/CouchDb",pathFormat:"host/user"}};return function(){var surfnetSaml={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/saml/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/saml",pathFormat:"user@host"},surfnetBrowserId={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/browserid/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/browserid",pathFormat:"user@host"},dutchUniversitiesNoSaml=["leidenuniv.nl","leiden.edu","uva.nl","vu.nl","eur.nl","maastrichtuniversity.nl","ru.nl","rug.nl","uu.nl","tudelft.nl","utwente.nl","tue.nl","tilburguniversity.edu","uvt.nl","wur.nl","wageningenuniversity.nl","ou.nl","lumc.nl","amc.nl","ahk.nl","cah.nl","driestar.nl","che.nl","chn.nl","hen.nl","huygens.nl","diedenoort.nl","efa.nl","dehaagsehogeschool.nl","hasdenbosch.nl","inholland.nl","hsbrabant.nl","dehorst.nl","kempel.nl","domstad.nl","hsdrenthe.nl","edith.nl","hsleiden.nl","interport.nl","schumann.nl","hsbos.nl","hva.nl","han.nl","hvu.nl","hesasd.nl","hes-rdam.nl","hku.nl","hmtr.nl","hzeeland.nl","hotelschool.nl","ichtus-rdam.nl","larenstein.nl","iselinge.nl","koncon.nl","kabk.nl","lhump.nl","msm.nl","hsmarnix.nl","nhtv.nl","nth.nl","nhl.nl","sandberg.nl","hsij.nl","stoas.nl","thrijswijk.nl","tio.nl","vhall.nl","chw.nl","hogeschoolrotterdam.nl"],dutchUniversitiesSaml=["surfnet.nl","fontys.nl"];for(var i=0;i<dutchUniversitiesSaml.length;i++)guesses[dutchUniversitiesSaml[i]]=surfnetSaml;for(var i=0;i<dutchUniversitiesNoSaml.length;i++)guesses[dutchUniversitiesNoSaml[i]]=surfnetBrowserId}(),{guessStorageInfo:guessStorageInfo}}),define("lib/getputdelete",["./platform","./util"],function(platform,util){function doCall(method,url,value,mimeType,token,cb,deadLine){var platformObj={url:url,method:method,error:function(err){cb(err)},success:function(data,headers){logger.debug("doCall cb "+url,"headers:",headers),cb(null,data,headers["Content-Type"]||defaultContentType)},timeout:3e3};platformObj.headers={Authorization:"Bearer "+token},mimeType&&(platformObj.headers["Content-Type"]=mimeType),platformObj.fields={withCredentials:"true"},method!="GET"&&(platformObj.data=value),logger.debug("platform.ajax "+url),platform.ajax(platformObj)}function get(url,token,cb){doCall("GET",url,null,null,token,function(err,data,mimetype){if(err==404)cb(null,undefined);else{if(url.substr(-1)=="/")try{data=JSON.parse(data)}catch(e){cb("unparseable directory index");return}cb(err,data,mimetype)}})}function put(url,value,mimeType,token,cb){logger.info("calling PUT "+url),doCall("PUT",url,value,mimeType,token,function(err,data){logger.debug("cb from PUT "+url),err==404?doPut(url,value,token,1,cb):cb(err,data)})}function set(url,valueStr,mimeType,token,cb){typeof valueStr=="undefined"?doCall("DELETE",url,null,null,token,cb):put(url,valueStr,mimeType,token,cb)}var logger=util.getLogger("getputdelete"),defaultContentType="application/octet-stream";return{get:get,set:set}}),define("lib/wireClient",["./getputdelete"],function(getputdelete){function set(key,value){localStorage.setItem(prefix+key,JSON.stringify(value))}function remove(key){localStorage.removeItem(prefix+key)}function get(key){var valStr=localStorage.getItem(prefix+key);if(typeof valStr=="string")try{return JSON.parse(valStr)}catch(e){localStorage.removeItem(prefix+key)}return null}function disconnectRemote(){remove("storageType"),remove("storageHref"),remove("bearerToken")}function getState(){return get("storageType")&&get("storageHref")?get("bearerToken")?"connected":"authing":"anonymous"}function on(eventType,cb){eventType=="error"&&(errorHandler=cb)}function resolveKey(storageType,storageHref,basePath,relPath){var item=(basePath.length?basePath+"/":"")+relPath;return storageHref+item}function setChain(driver,hashMap,mimeType,token,cb,timestamp){var i;for(i in hashMap)break;if(i){var thisOne=hashMap[i];delete hashMap[i],driver.set(i,thisOne,mimeType,token,function(err,timestamp){err?cb(err):setChain(driver,hashMap,mimeType,token,cb,timestamp)})}else cb(null,timestamp)}var prefix="remote_storage_wire_",errorHandler=function(){};return{get:function(path,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.get(resolveKey(storageType,storageHref,"",path),token,cb)},set:function(path,valueStr,mimeType,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.set(resolveKey(storageType,storageHref,"",path),valueStr,mimeType,token,cb)},setStorageInfo:function(type,href){set("storageType",type),set("storageHref",href)},getStorageHref:function(){return get("storageHref")},setBearerToken:function(bearerToken){set("bearerToken",bearerToken)},disconnectRemote:disconnectRemote,on:on,getState:getState}}),define("lib/store",["./util"],function(util){function fireChange(e){for(var i=0;i<onChange.length;i++)onChange[i](e)}function getNode(path){var valueStr=localStorage.getItem(prefixNodes+path),value;if(valueStr)try{value=JSON.parse(valueStr)}catch(e){}return value||(value={startAccess:null,startForce:null,timestamp:0,keep:!0,diff:{}}),value}function isDir(path){return typeof path!="string"&&(logger.error("Given path is not a string: ",path),doSomething()),path.substr(-1)=="/"}function getContainingDir(path){var parts=path.split("/");return parts[parts.length-1].length||parts.pop(),parts.length?(parts.pop(),parts.join("/")+(parts.length?"/":"")):undefined}function getFileName(path){var parts=path.split("/");return isDir(path)?parts[parts.length-2]+"/":parts[parts.length-1]}function getCurrTimestamp(){return(new Date).getTime()}function updateNode(path,node,outgoing,meta,timestamp){node?localStorage.setItem(prefixNodes+path,JSON.stringify(node)):localStorage.removeItem(prefixNodes+path);var containingDir=getContainingDir(path);if(containingDir){var parentNode=getNode(containingDir),parentData=getNodeData(parentNode)||{};if(meta){if(!parentData||!parentData[getFileName(path)])parentData[getFileName(path)]=0;updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!0)}else if(outgoing)node?parentData[getFileName(path)]=(new Date).getTime():delete parentData[getFileName(path)],parentNode.diff[getFileName(path)]=(new Date).getTime(),updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!0);else{if(node){if(!parentData[getFileName(path)]||parentData[getFileName(path)]<timestamp)parentData[getFileName(path)]=timestamp,delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp)}else parentData[getFileName(path)]&&(delete parentData[getFileName(path)],delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp));path.substr(-1)!="/"&&fireChange({path:path,origin:"remote",oldValue:undefined,newValue:node?getNodeData(node):undefined,timestamp:timestamp})}}}function forget(path){localStorage.removeItem(prefixNodes+path)}function forgetAll(){for(var i=0;i<localStorage.length;i++)localStorage.key(i).substr(0,prefixNodes.length)==prefixNodes&&(localStorage.removeItem(localStorage.key(i)),i--)}function on(eventName,cb){if(eventName!="change")throw"Unknown event: "+eventName;onChange.push(cb)}function getState(path){return"disconnected"}function updateNodeData(path,data){if(!path)throw console.trace(),"Path is required!";var encodedData;try{encodedData=JSON.stringify(data)}catch(exc){encodedData=data}localStorage.setItem(prefixNodesData+path,encodedData)}function setNodeData(path,data,outgoing,timestamp,mimeType){var node=getNode(path);mimeType||(mimeType="application/json"),node.mimeType=mimeType,timestamp||(timestamp=(new Date).getTime()),updateNodeData(path,data),updateNode(path,data?node:undefined,outgoing,!1,timestamp)}function getNodeData(path){typeof path=="object"&&(path=path.path);var valueStr=localStorage.getItem(prefixNodesData+path);if(!valueStr)return undefined;try{return JSON.parse(valueStr)}catch(exc){return valueStr}}function setNodeAccess(path,claim){var node=getNode(path);claim!=node.startAccess&&(claim=="rw"||node.startAccess==null)&&(node.startAccess=claim,updateNode(path,node,!1,!0))}function setNodeForce(path,force){var node=getNode(path);node.startForce=force,updateNode(path,node,!1,!0)}function clearDiff(path,i){var node=getNode(path);delete node.diff[i],updateNode(path,node,!1,!0)}var logger=util.getLogger("store"),onChange=[],prefixNodes="remote_storage_nodes:",prefixNodesData="remote_storage_node_data:";return typeof window!="undefined"&&window.addEventListener("storage",function(e){e.key.substring(0,prefixNodes.length==prefixNodes)&&(e.path=e.key.substring(prefixNodes.length),isDir(e.path)||(e.origin="device",fireChange(e)))}),{on:on,getNode:getNode,getNodeData:getNodeData,setNodeData:setNodeData,setNodeAccess:setNodeAccess,setNodeForce:setNodeForce,clearDiff:clearDiff,forget:forget,forgetAll:forgetAll}}),define("lib/sync",["./wireClient","./store","./util"],function(wireClient,store,util){function getState(path){return busy?"busy":"connected"}function setBusy(val){busy=val;for(var i=0;i<stateCbs.length;i++)stateCbs[i](val?"busy":"connected")}function on(eventType,cb){eventType=="state"&&stateCbs.push(cb)}function dirMerge(dirPath,remote,cached,diff,force,access,startOne,finishOne,clearCb){for(var i in remote)(!cached[i]&&!diff[i]||cached[i]<remote[i])&&pullNode(dirPath+i,force,access,startOne,finishOne);for(var i in cached)if(!remote[i]||cached[i]>remote[i])if(i.substr(-1)=="/")pullNode(dirPath+i,force,access,startOne,finishOne);else{var childNode=store.getNode(dirPath+i),childData=store.getNodeData(dirPath+i);startOne(),typeof childData=="object"&&(childData=JSON.stringify(childData)),wireClient.set(dirPath+i,childData,"application/json",function(err){finishOne()})}for(var i in diff)cached[i]?remote[i]===cached[i]&&clearCb(i):remote[i]?(startOne(),wireClient.set(dirPath+i,undefined,undefined,function(err){finishOne()})):clearCb(i)}function pullNode(path,force,access,startOne,finishOne){var thisNode=store.getNode(path),thisData=store.getNodeData(path);!thisData&&path.substr(-1)=="/"&&(thisData={}),logger.debug("pullNode "+path,thisNode);if(thisNode.startAccess=="rw"||!access)access=thisNode.startAccess;thisNode.startForce&&(force=thisNode.startForce);if(access)startOne(),wireClient.get(path,function(err,data){!err&&data&&(path.substr(-1)=="/"?dirMerge(path,data,thisData,thisNode.diff,force,access,startOne,finishOne,function(i){store.clearDiff(path,i)}):store.setNodeData(path,data,!1)),finishOne(err)});else for(var i in thisData)i.substr(-1)=="/"&&pullNode(path+i,force,access,startOne,finishOne)}function fetchNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(err),outstanding--,outstanding==0&&(setBusy(!1),callback(errors||null,store.getNode(path)))}var outstanding=0,errors=[];setBusy(!0),pullNode(path,!1,!0,startOne,finishOne)}function syncNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(path),outstanding--,outstanding==0&&(setBusy(!1),callback&&callback(errors.length>0?errors:null))}if(wireClient.getState()=="anonymous"){callback&&callback(["not connected"]);return}var outstanding=0,errors=[];logger.info("syncNow "+path),setBusy(!0),pullNode(path,!1,!1,startOne,finishOne)}var prefix="_remoteStorage_",busy=!1,stateCbs=[],logger=util.getLogger("sync");return{syncNow:syncNow,fetchNow:fetchNow,getState:getState,on:on}}),define("lib/widget",["./assets","./webfinger","./hardcoded","./wireClient","./sync","./store","./platform"],function(assets,webfinger,hardcoded,wireClient,sync,store,platform){function translate(text){return text}function isRegistering(){return localStorage.getItem("remote_storage_registering")}function setRegistering(value){value===!1?localStorage.removeItem("remote_storage_registering"):localStorage.setItem("remote_storage_registering","true")}function calcWidgetStateOnLoad(){wc=wireClient;if(isRegistering())return"registering";var wireClientState=wireClient.getState();return wireClientState=="connected"?sync.getState():wireClientState}function setWidgetStateOnLoad(){setWidgetState(calcWidgetStateOnLoad())}function setWidgetState(state){widgetState=state,displayWidgetState(state,userAddress)}function getWidgetState(){return widgetState}function displayWidgetState(state,userAddress){var userAddress=localStorage.remote_storage_widget_useraddress,html="<style>"+assets.widgetCss+"</style>"+'<div id="remotestorage-state" class="'+state+'">'+'  <input id="remotestorage-connect-button" class="remotestorage-button" type="submit" value="'+translate("connect")+'"/>'+'  <span id="remotestorage-register-button" class="remotestorage-button">'+translate("get remoteStorage")+"</span>"+'  <img id="remotestorage-cube" src="'+assets.remoteStorageCube+'"/>'+'  <span id="remotestorage-disconnect">Disconnect '+(userAddress?"<strong>"+userAddress+"</strong>":"")+"</span>"+'  <a id="remotestorage-questionmark" href="http://unhosted.org/#remotestorage" target="_blank">?</a>'+'  <span class="infotext" id="remotestorage-infotext">This app allows you to use your own data storage!<br/>Click for more info on the Unhosted movement.</span>'+'  <input id="remotestorage-useraddress" type="text" value="me@local.dev" placeholder="you@remotestorage" autofocus="" />'+'  <a class="infotext" href="http://remotestoragejs.com/" target="_blank" id="remotestorage-devsonly">RemoteStorageJs is still in developer preview!<br/>Click for more info.</a>'+"</div>";platform.setElementHTML(connectElement,html),platform.eltOn("remotestorage-register-button","click",handleRegisterButtonClick),platform.eltOn("remotestorage-connect-button","click",handleConnectButtonClick),platform.eltOn("remotestorage-disconnect","click",handleDisconnectClick),platform.eltOn("remotestorage-cube","click",handleCubeClick),platform.eltOn("remotestorage-useraddress","type",handleWidgetTypeUserAddress)}function handleRegisterButtonClick(){setRegistering();var win=window.open("http://unhosted.org/en/a/register.html","Get your remote storage","resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=820,height=800,top=0,left=0");setWidgetState("registering")}function redirectUriToClientId(loc){if(loc.substring(0,"http://".length)=="http://")loc=loc.substring("http://".length);else{if(loc.substring(0,"https://".length)!="https://")return loc;loc=loc.substring("https://".length)}var hostParts=loc.split("/")[0].split("@");return hostParts.length>2?loc:(hostParts.length==2&&hostParts.shift(),hostParts[0])}function dance(endpoint){var endPointParts=endpoint.split("?"),queryParams=[];endPointParts.length==2?queryParams=endPointParts[1].split("&"):endPointParts.length>2&&errorHandler("more than one questionmark in auth-endpoint - ignoring");var loc=platform.getLocation(),scopesArr=[];for(var i in scopesObj)scopesArr.push(i+":"+scopesObj[i]);queryParams.push("response_type=token"),queryParams.push("scope="+encodeURIComponent(scopesArr.join(" "))),queryParams.push("redirect_uri="+encodeURIComponent(loc)),queryParams.push("client_id="+encodeURIComponent(redirectUriToClientId(loc))),platform.setLocation(endPointParts[0]+"?"+queryParams.join("&"))}function discoverStorageInfo(userAddress,cb){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?hardcoded.guessStorageInfo(userAddress,{timeout:3e3},function(err2,data2){err2?cb(err2):data2.type&&data2.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data2.type,data2.href),cb(null,data2.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from webfinger")}):data.type&&data.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data.type,data.href),cb(null,data.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from hardcoded")})}function handleConnectButtonClick(){widgetState=="typing"?(userAddress=platform.getElementValue("remotestorage-useraddress"),localStorage.remote_storage_widget_useraddress=userAddress,setWidgetState("connecting"),discoverStorageInfo(userAddress,function(err,auth){err?(alert("webfinger discovery failed! (sorry this is still a developer preview! developers, point local.dev to 127.0.0.1, then run sudo node server/nodejs-example.js from the repo)"),setWidgetState("failed")):dance(auth)})):setWidgetState("typing")}function handleDisconnectClick(){widgetState=="connected"?(wireClient.disconnectRemote(),store.forgetAll(),setWidgetState("anonymous")):alert("you cannot disconnect now, please wait until the cloud is up to date...")}function handleCubeClick(){sync.syncNow("/",function(errors){})}function handleWidgetTypeUserAddress(){setRegistering(!1),console.log("handleWidgetTypeUserAddress")}function handleWidgetHover(){console.log("handleWidgetHover")}function display(setConnectElement,setLocale){var tokenHarvested=platform.harvestParam("access_token"),storageRootHarvested=platform.harvestParam("storage_root"),storageApiHarvested=platform.harvestParam("storage_api"),authorizeEndpointHarvested=platform.harvestParam("authorize_endpoint");tokenHarvested&&wireClient.setBearerToken(tokenHarvested),storageRootHarvested&&wireClient.setStorageInfo(storageApiHarvested?storageApiHarvested:"2012.04",storageRootHarvested),authorizeEndpointHarvested&&dance(authorizeEndpointHarvested),connectElement=setConnectElement,locale=setLocale,wireClient.on("error",function(err){platform.alert(translate(err))}),sync.on("state",setWidgetState),setWidgetStateOnLoad(),window.onkeydown=function(evt){if(evt.ctrlKey&&evt.which==83)return evt.preventDefault(),console.log("CTRL+S - SYNCING"),sync.syncNow("/",function(errors){}),!1}}function addScope(module,mode){if(!scopesObj[module]||mode=="rw")scopesObj[module]=mode}var locale="en",connectElement,widgetState,userAddress,scopesObj={};return{display:display,addScope:addScope,getState:getWidgetState}}),define("lib/baseClient",["./sync","./store","./util"],function(sync,store,util){function bindContext(callback,context){return context?function(){return callback.apply(context,arguments)}:callback}function extractModuleName(path){if(path&&typeof path=="string"){var parts=path.split("/");if(parts.length>3&&parts[1]=="public")return parts[2];if(parts.length>2)return parts[1]}}function fireChange(moduleName,eventObj){if(moduleName&&moduleChangeHandlers[moduleName])for(var i=0;i<moduleChangeHandlers[moduleName].length;i++)moduleChangeHandlers[moduleName][i](eventObj)}function fireError(str){for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](str)}function set(path,absPath,valueStr){if(isDir(absPath)){fireError("attempt to set a value to a directory "+absPath);return}var node=store.getNode(absPath),changeEvent={origin:"window",oldValue:store.getNodeData(node),newValue:valueStr,path:path},ret=store.setNodeData(absPath,valueStr,!0),moduleName=extractModuleName(absPath);return fireChange(moduleName,changeEvent),fireChange("root",changeEvent),ret}function claimAccess(path,claim){store.setNodeAccess(path,claim)}function isDir(path){return typeof path!="string"&&doSomething(),path.substr(-1)=="/"}var moduleChangeHandlers={},errorHandlers=[],logger=util.getLogger("baseClient");return store.on("change",function(e){var moduleName=extractModuleName(e.path);fireChange(moduleName,e),fireChange("root",e)}),{claimAccess:claimAccess,getInstance:function(moduleName,isPublic){function makePath(path){return moduleName=="root"?path:(isPublic?"/public/":"/")+moduleName+"/"+path}function nodeGivesAccess(path,mode){var node=store.getNode(path);logger.debug("check node access",path,mode,node);var access=(new RegExp(mode)).test(node.startAccess);if(access)return!0;if(path.length>0)return nodeGivesAccess(path.replace(/[^\/]+\/?$/,""))}function ensureAccess(mode){var path=makePath(moduleName=="root"?"/":"");if(!nodeGivesAccess(path,mode))throw"Not sufficient access claimed for node at "+path}return{on:function(eventType,cb,context){eventType=="change"?moduleName&&(moduleChangeHandlers[moduleName]||(moduleChangeHandlers[moduleName]=[]),moduleChangeHandlers[moduleName].push(bindContext(cb,context))):eventType=="error"&&errorHandlers.push(bindContext(cb,context))},getObject:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath);return data&&typeof data=="object"&&delete data["@type"],data}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node);data&&typeof data=="object"&&delete data["@type"],bindContext(cb,context)(data)})},getListing:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath),arr=[];for(var i in data)arr.push(i);return arr}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node),arr=[];for(var i in data)arr.push(i);bindContext(cb,context)(arr)})},getDocument:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath);return{mimeType:node.mimeType,data:store.getNodeData(node)}}sync.fetchNow(absPath,function(err,node){bindContext(cb,context)({mimeType:node.mimeType,data:store.getNodeData(node)})})},remove:function(path,cb,context){ensureAccess("w");var ret=set(path,makePath(path));return this.syncNow(cb,context),ret},storeObject:function(type,path,obj,cb,context){ensureAccess("w");if(typeof obj!="object")throw"storeObject needs to get an object as value!";obj["@type"]="https://remotestoragejs.com/spec/modules/"+moduleName+"/"+type;var ret=set(path,makePath(path),obj,"application/json");return this.sync(path),this.syncNow(cb,context),ret},storeDocument:function(mimeType,path,data,cb,context){ensureAccess("w");var ret=set(path,makePath(path),data,mimeType);return this.syncNow(cb,context),ret},getItemURL:function(path){var base=remoteStorage.getStorageHref();return base?(base.substr(-1)!="/"&&(base+="/"),base+makePath(path)):null},getCurrentWebRoot:function(){return"https://example.com/this/is/an/example/"+(isPublic?"public/":"")+moduleName+"/"},sync:function(path,switchVal){var absPath=makePath(path);store.setNodeForce(absPath,switchVal!=0)},syncNow:function(cb,context){sync.syncNow(makePath(""),cb?bindContext(cb,context):function(errors){errors&&errors.length>0&&(logger.error("Error syncing: ",errors),fireError(errors))})},getState:function(path){}}}}}),define("lib/nodeConnect",["./wireClient","./webfinger"],function(wireClient,webfinger){return{setUserAddress:function(userAddress,callback){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?console.error("Failed to look up storage info for user "+userAddress+": ",err):wireClient.setStorageInfo(data.type,data.href),callback(err)})},setStorageInfo:wireClient.setStorageInfo,setBearerToken:wireClient.setBearerToken}}),define("remoteStorage",["require","./lib/widget","./lib/baseClient","./lib/store","./lib/sync","./lib/wireClient","./lib/nodeConnect","./lib/util"],function(require,widget,baseClient,store,sync,wireClient,nodeConnect,util){function deprecate(oldFn,newFn){logger.error("DEPRECATION: "+oldFn+" is deprecated! Use "+newFn+" instead.")}var claimedModules={},modules={},logger=util.getLogger("base"),remoteStorage={defineModule:function(moduleName,builder){logger.debug("DEFINE MODULE",moduleName);var module=builder(baseClient.getInstance(moduleName,!1),baseClient.getInstance(moduleName,!0));modules[moduleName]=module,this[moduleName]=module.exports,logger.debug("Module defined: "+moduleName,module,this)},getModuleList:function(){return Object.keys(modules)},getClaimedModuleList:function(){return Object.keys(claimedModules)},getModuleInfo:function(moduleName){return modules[moduleName]},claimAccess:function(claimed){if(typeof claimed!="object"||claimed instanceof Array){claimed instanceof Array||(claimed=Array.prototype.slice.call(arguments));var _modules=claimed,mode="rw";claimed={};var lastArg=arguments[arguments.length-1];typeof lastArg=="string"&&lastArg.match(/^rw?$/)&&(mode=lastArg,delete arguments[arguments.length-1]);for(var i in _modules)claimed[_modules[i]]=mode}for(var moduleName in claimed)this.claimModuleAccess(moduleName,claimed[moduleName])},claimModuleAccess:function(moduleName,mode){logger.debug("claimModuleAccess",moduleName,mode);if(!moduleName in modules)throw"Module not defined: "+moduleName;if(moduleName in claimedModules)return;mode||(mode="r"),moduleName=="root"?(moduleName="",widget.addScope("",mode),baseClient.claimAccess("/",mode)):(widget.addScope(moduleName,mode),baseClient.claimAccess("/"+moduleName+"/",mode),baseClient.claimAccess("/public/"+moduleName+"/",mode)),claimedModules[moduleName]=!0},loadModule:function(){deprecate("remoteStorage.loadModule","remoteStorage.claimAccess"),this.claimModuleAccess.apply(this,arguments)},setBearerToken:function(bearerToken,claimedScopes){wireClient.setBearerToken(bearerToken),baseClient.claimScopes(claimedScopes)},disconnectRemote:wireClient.disconnectRemote,flushLocal:store.forgetAll,syncNow:sync.syncNow,displayWidget:widget.display,getWidgetState:widget.getState,setStorageInfo:wireClient.setStorageInfo,getStorageHref:wireClient.getStorageHref,nodeConnect:nodeConnect,util:util};return remoteStorage}),global.localStorage={getItem:function(key){return this[key]},setItem:function(key,value){this[key]=value},removeItem:function(key){delete this[key]}},module.exports=require("remoteStorage")})()
\ No newline at end of file
index 947c0b8..0c75943 100644 (file)
@@ -6,4 +6,4 @@
  * see: http://github.com/jrburke/almond for details
  */
 
-(function(){var requirejs,require,define;(function(undef){function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=map&&map["*"]||{};if(name&&name.charAt(0)==="."&&baseName){baseParts=baseParts.slice(0,baseParts.length-1),name=baseParts.concat(name.split("/"));for(i=0;i<name.length;i+=1){part=name[i];if(part===".")name.splice(i,1),i-=1;else if(part===".."){if(i===1&&(name[2]===".."||name[0]===".."))break;i>0&&(name.splice(i-1,2),i-=2)}}name=name.join("/")}if((baseParts||starMap)&&map){nameParts=name.split("/");for(i=nameParts.length;i>0;i-=1){nameSegment=nameParts.slice(0,i).join("/");if(baseParts)for(j=baseParts.length;j>0;j-=1){mapValue=map[baseParts.slice(0,j).join("/")];if(mapValue){mapValue=mapValue[nameSegment];if(mapValue){foundMap=mapValue,foundI=i;break}}}if(foundMap)break;!foundStarMap&&starMap&&starMap[nameSegment]&&(foundStarMap=starMap[nameSegment],starI=i)}!foundMap&&foundStarMap&&(foundMap=foundStarMap,foundI=starI),foundMap&&(nameParts.splice(0,foundI,foundMap),name=nameParts.join("/"))}return name}function makeRequire(relName,forceSync){return function(){return req.apply(undef,aps.call(arguments,0).concat([relName,forceSync]))}}function makeNormalize(relName){return function(name){return normalize(name,relName)}}function makeLoad(depName){return function(value){defined[depName]=value}}function callDep(name){if(waiting.hasOwnProperty(name)){var args=waiting[name];delete waiting[name],defining[name]=!0,main.apply(undef,args)}if(!defined.hasOwnProperty(name))throw new Error("No "+name);return defined[name]}function makeMap(name,relName){var prefix,plugin,index=name.indexOf("!");return index!==-1?(prefix=normalize(name.slice(0,index),relName),name=name.slice(index+1),plugin=callDep(prefix),plugin&&plugin.normalize?name=plugin.normalize(name,makeNormalize(relName)):name=normalize(name,relName)):name=normalize(name,relName),{f:prefix?prefix+"!"+name:name,n:name,p:plugin}}function makeConfig(name){return function(){return config&&config.config&&config.config[name]||{}}}var main,req,defined={},waiting={},config={},defining={},aps=[].slice;main=function(name,deps,callback,relName){var cjsModule,depName,ret,map,i,args=[],usingExports;relName=relName||name;if(typeof callback=="function"){deps=!deps.length&&callback.length?["require","exports","module"]:deps;for(i=0;i<deps.length;i+=1){map=makeMap(deps[i],relName),depName=map.f;if(depName==="require")args[i]=makeRequire(name);else if(depName==="exports")args[i]=defined[name]={},usingExports=!0;else if(depName==="module")cjsModule=args[i]={id:name,uri:"",exports:defined[name],config:makeConfig(name)};else if(defined.hasOwnProperty(depName)||waiting.hasOwnProperty(depName))args[i]=callDep(depName);else if(map.p)map.p.load(map.n,makeRequire(relName,!0),makeLoad(depName),{}),args[i]=defined[depName];else if(!defining[depName])throw new Error(name+" missing "+depName)}ret=callback.apply(defined[name],args);if(name)if(cjsModule&&cjsModule.exports!==undef&&cjsModule.exports!==defined[name])defined[name]=cjsModule.exports;else if(ret!==undef||!usingExports)defined[name]=ret}else name&&(defined[name]=callback)},requirejs=require=req=function(deps,callback,relName,forceSync,alt){return typeof deps=="string"?callDep(makeMap(deps,callback).f):(deps.splice||(config=deps,callback.splice?(deps=callback,callback=relName,relName=null):deps=undef),callback=callback||function(){},typeof relName=="function"&&(relName=forceSync,forceSync=alt),forceSync?main(undef,deps,callback,relName):setTimeout(function(){main(undef,deps,callback,relName)},15),req)},req.config=function(cfg){return config=cfg,req},define=function(name,deps,callback){deps.splice||(callback=deps,deps=[]),waiting[name]=[name,deps,callback]},define.amd={jQuery:!0}})(),define("../build/lib/almond",function(){}),define("lib/assets",[],function(){return{remoteStorageIcon:"data:image/png;base64,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",remoteStorageCube:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAR2SURBVFiFtddfqGVVHQfwz2/vfZ28c2WgP6hMoYkUV4qIYnSKmaQYwaaJ3oLeUnpJmDCmUhCaIhhKGelhelCqN9+ECKdAxR6kgnJASBN9KTGwP2oKTtyZs8/+9bDXPufcfe51xju6YLHX2fu3ft/v+q7fWb/fisy0o3brez6qmt4Luvo7frvx/E7cxNsmcCj2WGnuEb6JaXlbSz8zaX/ksXzj3SHwg6j8aeU28jjeh8TZ8nU3Aq8Sx+2b/ML3s3vnCHxp5YB0Hz6OTkgpMax2jxBSoMJfhGMemTx5aQQOxzWsnCC/gm6hZ+mvFMv36xUYCJQev2Jyt9P54tsj8OVYNW2+izuxIkzlAoGUQuLlMuNqKcQCgVBJNSa4X93+xK/zfxcmcLj5GtUJ8ipMC/i0gA/PQYF/lFkfHClQFxJ1IVET/6S72+n2oa0JHL7s0+RPsR9tAZuOxuNtGKS9xpL8A7BmNP4j8S2nzz+lGJaWDxB7RyCbV54DkZiSrbAhbJBt/25LtUbEY2+P1bdmQY1V8mr8DruET5Z9n4NHTOmmZK9A2ihzp3RdL3tVy+z16OeG0ElncI48yGzeogIzQgexByelp2fMZ+CDAtFK56XzxFwBXSE6C9incbL4PDha9BKBPrjCddJRVT5DHsMLczkLUGhFbPR9iJNYjJUXyGOqfEY6KlxnHrybVjwm0JVDJmV8FZ8TeZysZdyBK9FKXb/6mdTZ+4uXRXcKUxnHpavKdqV58G5JYJFdLvT3yuok3ROiuY3JZ3Rxu7CH7lxvHlPpNVX+nJU/yMk9VJ8nm5GvMc42W6Bwnhl2KRyQ7cOyaqy1R0ScEvFq6aestUdk1cj2YeEA3RwwtwbfSoHtxxmJXeS3nV25RR0/9KnJL8GZyz7i7MoD5MfQ9LZ5YZ+WY+AiW16vc8if/av8PkRevxNPiwTiLceRISPIM3iUOGxa/wfUbiTvxy3ETb3tRfi0HAMx+xgLY1XIeAUPYoO4S+YNqupyVXW5zBuIu/pvHuxtq5j5DLHkfxsFxoaBlN1vVKbEN2TQ5wdYLc8++YibhZvJx3VZizgy8rVEYhwDfUKZFxd/Jf8m4gsydtENJ17TZ8lcLbOGrFfJrKmOiDxHPk58GJ8oPqu3UmDOLr2B5/AhYt08K9Z9AMdAsCeQml6BnKdiriC+iP/iKWkdH7gQgSRfQoi4SWoLcMqsRaUcZiX1xu4yrZmpp6p721lavlLYK/PfeIm4djsCE7xZDNqSVocV9evNJCKIjq6TuTbbAlWvQGZfiCwWJqkqqb7pMUwG0IV/QXwdz1ouKjZXOP021EQjqt2i2k00/Tv1Evj8OfRnC1aPeokl2e/LrM/aYUk2Pgc43T6knqzjBCZytqqhpGpK0DXCmrC26d1Qgs3BJzihnqyPwbdWYJMaFyzLnyuW6yMFLrEsH7ftLyZ/LxbX7vRisrwFW7VHJk/a1+4njuL1udx5Rd9nW/A6cdS+dv/FgHPpl9PhorH67l9Ox62/nv8YdPX3dno9/z+G+TGrzjgPKwAAAABJRU5ErkJggg==",widgetCss:"#remotestorage-state { position:fixed; top:15px; right:15px; height:32px; width:275px; font:normal 16px/100% sans-serif; z-index:99999; background:rgba(0,0,0,.3); padding:5px; border-radius:7px; box-shadow:0 1px rgba(255,255,255,.05), inset 0 1px rgba(0,0,0,.05); transition:width 500ms, background 500ms; }\n#remotestorage-state.connected, #remotestorage-state.busy, #remotestorage-state.offline { width:32px; background:none; box-shadow:none; }\n.remotestorage-button { margin:0; padding:.3em; font-size:14px; height:26px !important; background:#ddd; color:#333; border:1px solid #ccc; border-radius:3px; box-shadow:0 1px 1px #fff inset; }\n#remotestorage-register-button { position:absolute; left:25px; top:8px; max-height:16px; text-decoration:none; font-weight:normal; }\n#remotestorage-connect-button { position:absolute; right:8px; top:8px; padding:0 0 0 17px; width:90px; cursor:pointer; text-align:left; border-radius:0 3px 3px 0; font-weight:normal; }\n#remotestorage-connect-button:hover, #remotestorage-connect-button:focus, .remotestorage-button:hover, .remotestorage-button:focus { background:#eee; color:#000; text-decoration:none; }\n#remotestorage-useraddress { position:absolute; left:25px; top:8px; margin:0; padding:0 17px 0 3px; height:25px; width:142px; background:#eee; color:#333; border:0; border-radius:3px 0 0 3px; box-shadow:0 1px #fff, inset 0 1px #999; font-weight:normal; font-size:14px;}\n#remotestorage-useraddress:hover, #remotestorage-useraddress:focus { background:#fff; color:#000; }\n#remotestorage-cube { position:absolute; right:84px; -webkit-transition:right 500ms; -moz-transition:right 500ms; transition:right 500ms; z-index:99997; }\n#remotestorage-questionmark { position:absolute; left:0; padding:9px 8px; color:#fff; text-decoration:none; z-index:99999; font-weight:normal; }\n.infotext { position:absolute; left:0; top:0; width:255px; height:32px; padding:6px 5px 4px 25px; font-size:10px; background:black; color:white; border-radius:7px; opacity:.85; text-decoration:none; white-space:nowrap; z-index:99998; }\n#remotestorage-questiomark:hover { color:#fff; }\n#remotestorage-questionmark:hover+#remotestorage-infotext { display:inline; }\n#remotestorage-state.busy #remotestorage-cube, #remotestorage-state.connecting #remotestorage-cube {   -webkit-animation-name:remotestorage-loading; -webkit-animation-duration:2s; -webkit-animation-iteration-count:infinite; -webkit-animation-timing-function:linear;\n   -moz-animation-name:remotestorage-loading; -moz-animation-duration:2s; -moz-animation-iteration-count:infinite; -moz-animation-timing-function:linear;\n   -o-animation-name:remotestorage-loading; -o-animation-duration:2s; -o-animation-iteration-count:infinite; -o-animation-timing-function:linear;\n   -ms-animation-name:remotestorage-loading; -ms-animation-duration:2s; -ms-animation-iteration-count:infinite; -ms-animation-timing-function:linear; }\n   @-webkit-keyframes remotestorage-loading { from{-webkit-transform:rotate(0deg)} to{-webkit-transform:rotate(360deg)} }\n   @-moz-keyframes remotestorage-loading { from{-moz-transform:rotate(0deg)} to{-moz-transform:rotate(360deg)} }\n   @-o-keyframes remotestorage-loading { from{-o-transform:rotate(0deg)} to{-o-transform:rotate(360deg)} }\n   @-ms-keyframes remotestorage-loading { from{-ms-transform:rotate(0deg)} to{ -ms-transform:rotate(360deg)} }\n#remotestorage-connect-button, #remotestorage-questionmark, #remotestorage-register-button, #remotestorage-cube, #remotestorage-useraddress, #remotestorage-infotext, #remotestorage-devsonly, #remotestorage-disconnect { display:none }\n#remotestorage-state.anonymous #remotestorage-cube, #remotestorage-state.anonymous #remotestorage-connect-button, #remotestorage-state.anonymous #remotestorage-register-button, #remotestorage-state.anonymous #remotestorage-questionmark { display: block }\n#remotestorage-state.registering #remotestorage-cube, #remotestorage-state.registering #remotestorage-connect-button, #remotestorage-state.registering #remotestorage-register-button, #remotestorage-state.registering #remotestorage-questionmark { display: block }\n#remotestorage-state.interrupted #remotestorage-cube, #remotestorage-state.interrupted #remotestorage-connect-button, #remotestorage-state.interrupted #remotestorage-register-button, #remotestorage-state.interrupted #remotestorage-questionmark { display: block }\n#remotestorage-state.failed #remotestorage-cube, #remotestorage-state.failed #remotestorage-connect-button, #remotestorage-state.failed #remotestorage-register-button, #remotestorage-state.failed #remotestorage-questionmark { display: block }\n#remotestorage-state.typing #remotestorage-cube, #remotestorage-state.typing #remotestorage-connect-button, #remotestorage-state.typing #remotestorage-useraddress, #remotestorage-state.typing #remotestorage-questionmark { display: block }\n#remotestorage-state.connected #remotestorage-cube, #remotestorage-state.busy #remotestorage-cube, #remotestorage-state.offline #remotestorage-cube { right:0; opacity:.5; cursor:pointer; display: block }\n#remotestorage-state.devsonly #remotestorage-devsonly { display: block }\n#remotestorage-disconnect { position:absolute; right:6px; top:9px; padding:5px 28px 2px 6px; height:17px; white-space:nowrap; font-size:10px; background:#000; color:#fff; border-radius:5px; opacity:.5; text-decoration:none; z-index:99996; }\n#remotestorage-disconnect strong { font-weight:bold; }\n#remotestorage-state.connected #remotestorage-cube:hover, #remotestorage-state.busy #remotestorage-cube:hover, #remotestorage-state.offline #remotestorage-cube:hover { opacity:1; }\n#remotestorage-state.connected #remotestorage-disconnect:hover, #remotestorage-state.busy #remotestorage-disconnect:hover, #remotestorage-state.offline #remotestorage-disconnect:hover { display:inline; }\n#remotestorage-state.connected #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.busy #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.offline #remotestorage-cube:hover+#remotestorage-disconnect { display:inline; }\n"}}),define("lib/util",[],function(){var loggers={},silentLogger={},knownLoggers=["sync","webfinger","getputdelete","platform","baseClient"],util={toArray:function(enumerable){var a=[];for(var i in enumerable)a.push(enumerable[i]);return a},getLogger:function(name){return loggers[name]||(loggers[name]={info:function(){this.log("info",util.toArray(arguments))},debug:function(){this.log("debug",util.toArray(arguments),"debug")},error:function(){this.log("error",util.toArray(arguments),"error")},log:function(level,args,type){if(silentLogger[name])return;type||(type="log"),args.unshift("["+name.toUpperCase()+"] -- "+level+" "),(console[type]||console.log).apply(console,args)}}),loggers[name]},silenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)silentLogger[names[i]]=!0},unsilenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)delete silentLogger[names[i]]},silenceAllLoggers:function(){this.silenceLogger.apply(this,knownLoggers)},unsilenceAllLoggers:function(){this.unsilenceLogger.apply(this,knownLoggers)}};return util}),define("lib/platform",["./util"],function(util){function browserParseHeaders(rawHeaders){var headers={},lines=rawHeaders.split(/\r?\n/),lastKey=null,md,key,value;for(var i=0;i<lines.length;i++){if(lines[i].length==0)continue;(md=lines[i].match(/^([^:]+):\s*(.+)$/))?(key=md[1],value=md[2],headers[key]=value,lastKey=key):(md=lines[i].match(/^\s+(.+)$/))?(key=lastKey,value=md[1],headers[key]=headers[key]+value):logger.error("Failed to parse header line: "+lines[i])}return headers}function ajaxBrowser(params){var timedOut=!1,timer;params.timeout&&(timer=window.setTimeout(function(){timedOut=!0,params.error("timeout")},params.timeout));var xhr=new XMLHttpRequest;params.method||(params.method="GET"),xhr.open(params.method,params.url,!0);if(params.headers)for(var header in params.headers)xhr.setRequestHeader(header,params.headers[header]);logger.debug("A "+params.url),xhr.onreadystatechange=function(){xhr.readyState==4&&!timedOut&&(logger.debug("B "+params.url),timer&&window.clearTimeout(timer),logger.debug("xhr cb "+params.url),xhr.status==200||xhr.status==201||xhr.status==204||xhr.status==207?params.success(xhr.responseText,browserParseHeaders(xhr.getAllResponseHeaders())):params.error(xhr.status))},logger.debug("xhr "+params.url),typeof params.data=="string"?xhr.send(params.data):xhr.send()}function ajaxExplorer(params){var xdr=new XDomainRequest;xdr.timeout=params.timeout||3e3,xdr.open(params.method,params.url),xdr.onload=function(){xdr.status==200||xdr.status==201||xdr.status==204?params.success(xhr.responseText):params.error(xhr.status)},xdr.onerror=function(){err("unknown error")},xdr.ontimeout=function(){err(timeout)},params.data?xdr.send(params.data):xdr.send()}function ajaxNode(params){function normalizeHeaders(headers){var h={};for(var key in headers)h[key.replace(/(?:^|\-)[a-z]/g,function(match){return match.toUpperCase()})]=headers[key];return h}var http=require("http"),https=require("https"),url=require("url");params.method||(params.method="GET"),params.data?params.headers["content-length"]=params.data.length:params.data=null;var urlObj=url.parse(params.url),options={method:params.method,host:urlObj.hostname,path:urlObj.path,port:urlObj.port?port:urlObj.protocol=="https:"?443:80,headers:params.headers},timer,timedOut;params.timeout&&(timer=setTimeout(function(){params.error("timeout"),timedOut=!0},params.timeout));var lib=urlObj.protocol=="https:"?https:http,request=lib.request(options,function(response){var str="";response.setEncoding("utf8"),response.on("data",function(chunk){str+=chunk}),response.on("end",function(){timer&&clearTimeout(timer),timedOut||(response.statusCode==200||response.statusCode==201||response.statusCode==204?params.success(str,normalizeHeaders(response.headers)):params.error(response.statusCode))})});request.on("error",function(e){timer&&clearTimeout(timer),params.error(e.message)}),params.data?request.end(params.data):request.end()}function parseXmlBrowser(str,cb){var tree=(new DOMParser).parseFromString(str,"text/xml"),nodes=tree.getElementsByTagName("Link"),obj={Link:[]};for(var i=0;i<nodes.length;i++){var link={};if(nodes[i].attributes)for(var j=0;j<nodes[i].attributes.length;j++)link[nodes[i].attributes[j].name]=nodes[i].attributes[j].value;var props=nodes[i].getElementsByTagName("Property");link.properties={},xyz=props;for(var k=0;k<props.length;k++)link.properties[props[k].getAttribute("type")]=props[k].childNodes[0].nodeValue;link.rel&&obj.Link.push({"@":link})}cb(null,obj)}function parseXmlNode(str,cb){var xml2js=require("xml2js");(new xml2js.Parser).parseString(str,cb)}function harvestParamNode(){}function harvestParamBrowser(param){if(location.hash.length){var pairs=location.hash.substring(1).split("&");for(var i=0;i<pairs.length;i++)if(pairs[i].substring(0,(param+"=").length)==param+"="){var ret=decodeURIComponent(pairs[i].substring((param+"=").length));return delete pairs[i],location="#"+pairs.join("&"),ret}}}function setElementHtmlNode(eltName,html){}function setElementHtmlBrowser(eltName,html){var elt=eltName;elt instanceof Element||(elt=document.getElementById(eltName)),elt.innerHTML=html}function getElementValueNode(eltName){}function getElementValueBrowser(eltName){return document.getElementById(eltName).value}function eltOnNode(eltName,eventType,cb){}function eltOnBrowser(eltName,eventType,cb){eventType=="click"?document.getElementById(eltName).onclick=cb:eventType=="hover"?document.getElementById(eltName).onmouseover=cb:eventType=="type"&&(document.getElementById(eltName).onkeyup=cb)}function getLocationBrowser(){return window.location.href.split("#")[0]}function getLocationNode(){}function setLocationBrowser(location){window.location=location}function setLocationNode(){}function alertBrowser(str){alert(str)}function alertNode(str){console.log(str)}var logger=util.getLogger("platform");return typeof window=="undefined"?{ajax:ajaxNode,parseXml:parseXmlNode,harvestParam:harvestParamNode,setElementHTML:setElementHtmlNode,getElementValue:getElementValueNode,eltOn:eltOnNode,getLocation:getLocationNode,setLocation:setLocationNode,alert:alertNode}:window.XDomainRequest?{ajax:ajaxExplorer,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}:{ajax:ajaxBrowser,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}}),define("lib/webfinger",["./platform","./util"],function(platform,util){function userAddress2hostMetas(userAddress,cb){var parts=userAddress.toLowerCase().split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9a-z\-\_]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9a-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{var query="?resource=acct:"+encodeURIComponent(userAddress);cb(null,["https://"+parts[1]+"/.well-known/host-meta.json"+query,"https://"+parts[1]+"/.well-known/host-meta"+query,"http://"+parts[1]+"/.well-known/host-meta.json"+query,"http://"+parts[1]+"/.well-known/host-meta"+query])}}function fetchXrd(addresses,timeout,cb){var firstAddress=addresses.shift();firstAddress?platform.ajax({url:firstAddress,success:function(data){parseAsJrd(data,function(err,obj){err?parseAsXrd(data,function(err,obj){err?fetchXrd(addresses,timeout,cb):cb(null,obj)}):cb(null,obj)})},error:function(data){fetchXrd(addresses,timeout,cb)},timeout:timeout}):cb("could not fetch xrd")}function parseAsXrd(str,cb){platform.parseXml(str,function(err,obj){if(err)cb(err);else if(obj&&obj.Link){var links={};if(obj.Link&&obj.Link["@"])obj.Link["@"].rel&&(links[obj.Link["@"].rel]=obj.Link["@"]);else for(var i=0;i<obj.Link.length;i++)obj.Link[i]["@"]&&obj.Link[i]["@"].rel&&(links[obj.Link[i]["@"].rel]=obj.Link[i]["@"]);cb(null,links)}else cb("found valid xml but with no Link elements in there")})}function parseAsJrd(str,cb){var obj;try{obj=JSON.parse(str)}catch(e){cb("not valid JSON");return}obj.links||cb("JRD contains no links");var links={};for(var i=0;i<obj.links.length;i++)obj.links[i].rel&&(links[obj.links[i].rel]=obj.links[i]);cb(null,links)}function parseRemoteStorageLink(obj,cb){obj&&obj.href&&obj.type&&obj.properties&&obj.properties["auth-endpoint"]?cb(null,obj):cb("could not extract storageInfo from lrdd")}function getStorageInfo(userAddress,options,cb){userAddress2hostMetas(userAddress,function(err1,hostMetaAddresses){logger.debug("HOST META ADDRESSES",hostMetaAddresses,"(error: ",err1,")"),err1?cb(err1):fetchXrd(hostMetaAddresses,options.timeout,function(err2,hostMetaLinks){if(err2)cb("could not fetch host-meta for "+userAddress);else if(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage)parseRemoteStorageLink(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage,cb);else if(hostMetaLinks.lrdd&&hostMetaLinks.lrdd.template){var parts=hostMetaLinks.lrdd.template.split("{uri}"),lrddAddresses=[parts.join("acct:"+userAddress),parts.join(userAddress)];fetchXrd(lrddAddresses,options.timeout,function(err4,lrddLinks){err4?cb("could not fetch lrdd for "+userAddress):lrddLinks.remoteStorage?parseRemoteStorageLink(lrddLinks.remoteStorage,cb):lrddLinks.remotestorage?parseRemoteStorageLink(lrddLinks.remotestorage,cb):cb("could not extract storageInfo from lrdd")})}else cb("could not extract lrdd template from host-meta")})})}var logger=util.getLogger("webfinger");return{getStorageInfo:getStorageInfo}}),define("lib/hardcoded",["./platform"],function(platform){function testIrisCouch(userAddress,options,cb){platform.ajax({url:"http://proxy.unhosted.org/irisCouchCheck?q=acct:"+userAddress,success:function(data){var obj;try{obj=JSON.parse(data)}catch(e){}obj?cb(null,obj):cb("err: unparsable response from IrisCouch check")},error:function(err){cb("err: during IrisCouch test:"+err)},timeout:options.timeout})}function mapToIrisCouch(userAddress){var parts=userAddress.split("@");return["libredocs","mail","browserid","me"].indexOf(parts[0])==-1?parts[0]+"@iriscouch.com":parts[2].substring(0,parts[2].indexOf("."))+"@iriscouch.com"}function guessStorageInfo(userAddress,options,cb){var parts=userAddress.split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9A-Za-z]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9A-Za-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{while(parts[1].indexOf(".")!=-1){if(guesses[parts[1]]){blueprint=guesses[parts[1]],cb(null,{rel:"https://www.w3.org/community/unhosted/wiki/personal-data-service-00",type:blueprint.type,href:blueprint.hrefPrefix+"/"+(blueprint.pathFormat=="user@host"?userAddress:parts[1]+"/"+parts[0]),properties:{"access-methods":["http://oauth.net/core/1.0/parameters/auth-header"],"auth-methods":["http://oauth.net/discovery/1.0/consumer-identity/static"],"auth-endpoint":blueprint.authPrefix+userAddress}});return}parts[1]=parts[1].substring(parts[1].indexOf(".")+1)}new Date<new Date("9/9/2012")?testIrisCouch(userAddress,options,cb):cb("err: not a guessable domain, and fakefinger-migration has ended")}}var guesses={"iriscouch.com":{type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#couchdb",authPrefix:"http://proxy.unhosted.org/OAuth.html?userAddress=",hrefPrefix:"http://proxy.unhosted.org/CouchDb",pathFormat:"host/user"}};return function(){var surfnetSaml={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/saml/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/saml",pathFormat:"user@host"},surfnetBrowserId={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/browserid/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/browserid",pathFormat:"user@host"},dutchUniversitiesNoSaml=["leidenuniv.nl","leiden.edu","uva.nl","vu.nl","eur.nl","maastrichtuniversity.nl","ru.nl","rug.nl","uu.nl","tudelft.nl","utwente.nl","tue.nl","tilburguniversity.edu","uvt.nl","wur.nl","wageningenuniversity.nl","ou.nl","lumc.nl","amc.nl","ahk.nl","cah.nl","driestar.nl","che.nl","chn.nl","hen.nl","huygens.nl","diedenoort.nl","efa.nl","dehaagsehogeschool.nl","hasdenbosch.nl","inholland.nl","hsbrabant.nl","dehorst.nl","kempel.nl","domstad.nl","hsdrenthe.nl","edith.nl","hsleiden.nl","interport.nl","schumann.nl","hsbos.nl","hva.nl","han.nl","hvu.nl","hesasd.nl","hes-rdam.nl","hku.nl","hmtr.nl","hzeeland.nl","hotelschool.nl","ichtus-rdam.nl","larenstein.nl","iselinge.nl","koncon.nl","kabk.nl","lhump.nl","msm.nl","hsmarnix.nl","nhtv.nl","nth.nl","nhl.nl","sandberg.nl","hsij.nl","stoas.nl","thrijswijk.nl","tio.nl","vhall.nl","chw.nl","hogeschoolrotterdam.nl"],dutchUniversitiesSaml=["surfnet.nl","fontys.nl"];for(var i=0;i<dutchUniversitiesSaml.length;i++)guesses[dutchUniversitiesSaml[i]]=surfnetSaml;for(var i=0;i<dutchUniversitiesNoSaml.length;i++)guesses[dutchUniversitiesNoSaml[i]]=surfnetBrowserId}(),{guessStorageInfo:guessStorageInfo}}),define("lib/getputdelete",["./platform","./util"],function(platform,util){function doCall(method,url,value,mimeType,token,cb,deadLine){var platformObj={url:url,method:method,error:function(err){cb(err)},success:function(data,headers){logger.debug("doCall cb "+url,"headers:",headers),cb(null,data,headers["Content-Type"]||defaultContentType)},timeout:3e3};platformObj.headers={Authorization:"Bearer "+token},mimeType&&(platformObj.headers["Content-Type"]=mimeType),platformObj.fields={withCredentials:"true"},method!="GET"&&(platformObj.data=value),logger.debug("platform.ajax "+url),platform.ajax(platformObj)}function get(url,token,cb){doCall("GET",url,null,null,token,function(err,data,mimetype){if(err==404)cb(null,undefined);else{if(url.substr(-1)=="/")try{data=JSON.parse(data)}catch(e){cb("unparseable directory index");return}cb(err,data,mimetype)}})}function put(url,value,mimeType,token,cb){logger.info("calling PUT "+url),doCall("PUT",url,value,mimeType,token,function(err,data){logger.debug("cb from PUT "+url),err==404?doPut(url,value,token,1,cb):cb(err,data)})}function set(url,valueStr,mimeType,token,cb){typeof valueStr=="undefined"?doCall("DELETE",url,null,null,token,cb):put(url,valueStr,mimeType,token,cb)}var logger=util.getLogger("getputdelete"),defaultContentType="application/octet-stream";return{get:get,set:set}}),define("lib/wireClient",["./getputdelete"],function(getputdelete){function set(key,value){localStorage.setItem(prefix+key,JSON.stringify(value))}function remove(key){localStorage.removeItem(prefix+key)}function get(key){var valStr=localStorage.getItem(prefix+key);if(typeof valStr=="string")try{return JSON.parse(valStr)}catch(e){localStorage.removeItem(prefix+key)}return null}function disconnectRemote(){remove("storageType"),remove("storageHref"),remove("bearerToken")}function getState(){return get("storageType")&&get("storageHref")?get("bearerToken")?"connected":"authing":"anonymous"}function on(eventType,cb){eventType=="error"&&(errorHandler=cb)}function resolveKey(storageType,storageHref,basePath,relPath){var item=(basePath.length?basePath+"/":"")+relPath;return storageHref+item}function setChain(driver,hashMap,mimeType,token,cb,timestamp){var i;for(i in hashMap)break;if(i){var thisOne=hashMap[i];delete hashMap[i],driver.set(i,thisOne,mimeType,token,function(err,timestamp){err?cb(err):setChain(driver,hashMap,mimeType,token,cb,timestamp)})}else cb(null,timestamp)}var prefix="remote_storage_wire_",errorHandler=function(){};return{get:function(path,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.get(resolveKey(storageType,storageHref,"",path),token,cb)},set:function(path,valueStr,mimeType,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.set(resolveKey(storageType,storageHref,"",path),valueStr,mimeType,token,cb)},setStorageInfo:function(type,href){set("storageType",type),set("storageHref",href)},getStorageHref:function(){return get("storageHref")},setBearerToken:function(bearerToken){set("bearerToken",bearerToken)},disconnectRemote:disconnectRemote,on:on,getState:getState}}),define("lib/store",["./util"],function(util){function fireChange(e){for(var i=0;i<onChange.length;i++)onChange[i](e)}function getNode(path){var valueStr=localStorage.getItem(prefixNodes+path),value;if(valueStr)try{value=JSON.parse(valueStr)}catch(e){}return value||(value={startAccess:null,startForce:null,timestamp:0,keep:!0,diff:{}}),value}function isDir(path){return typeof path!="string"&&(logger.error("Given path is not a string: ",path),doSomething()),path.substr(-1)=="/"}function getContainingDir(path){var parts=path.split("/");return parts[parts.length-1].length||parts.pop(),parts.length?(parts.pop(),parts.join("/")+(parts.length?"/":"")):undefined}function getFileName(path){var parts=path.split("/");return isDir(path)?parts[parts.length-2]+"/":parts[parts.length-1]}function getCurrTimestamp(){return(new Date).getTime()}function updateNode(path,node,outgoing,meta,timestamp){node?localStorage.setItem(prefixNodes+path,JSON.stringify(node)):localStorage.removeItem(prefixNodes+path);var containingDir=getContainingDir(path);if(containingDir){var parentNode=getNode(containingDir),parentData=getNodeData(parentNode)||{};if(meta){if(!parentData||!parentData[getFileName(path)])parentData[getFileName(path)]=0;updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!0)}else if(outgoing)node?parentData[getFileName(path)]=(new Date).getTime():delete parentData[getFileName(path)],parentNode.diff[getFileName(path)]=(new Date).getTime(),updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!0);else{if(node){if(!parentData[getFileName(path)]||parentData[getFileName(path)]<timestamp)parentData[getFileName(path)]=timestamp,delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp)}else parentData[getFileName(path)]&&(delete parentData[getFileName(path)],delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp));path.substr(-1)!="/"&&fireChange({path:path,origin:"remote",oldValue:undefined,newValue:node?getNodeData(node):undefined,timestamp:timestamp})}}}function forget(path){localStorage.removeItem(prefixNodes+path)}function forgetAll(){for(var i=0;i<localStorage.length;i++)localStorage.key(i).substr(0,prefixNodes.length)==prefixNodes&&(localStorage.removeItem(localStorage.key(i)),i--)}function on(eventName,cb){if(eventName!="change")throw"Unknown event: "+eventName;onChange.push(cb)}function getState(path){return"disconnected"}function updateNodeData(path,data){if(!path)throw console.trace(),"Path is required!";var encodedData;try{encodedData=JSON.stringify(data)}catch(exc){encodedData=data}localStorage.setItem(prefixNodesData+path,encodedData)}function setNodeData(path,data,outgoing,timestamp,mimeType){var node=getNode(path);mimeType||(mimeType="application/json"),node.mimeType=mimeType,timestamp||(timestamp=(new Date).getTime()),updateNodeData(path,data),updateNode(path,data?node:undefined,outgoing,!1,timestamp)}function getNodeData(path){typeof path=="object"&&(path=path.path);var valueStr=localStorage.getItem(prefixNodesData+path);if(!valueStr)return undefined;try{return JSON.parse(valueStr)}catch(exc){return valueStr}}function setNodeAccess(path,claim){var node=getNode(path);claim!=node.startAccess&&(claim=="rw"||node.startAccess==null)&&(node.startAccess=claim,updateNode(path,node,!1,!0))}function setNodeForce(path,force){var node=getNode(path);node.startForce=force,updateNode(path,node,!1,!0)}function clearDiff(path,i){var node=getNode(path);delete node.diff[i],updateNode(path,node,!1,!0)}var logger=util.getLogger("store"),onChange=[],prefixNodes="remote_storage_nodes:",prefixNodesData="remote_storage_node_data:";return typeof window!="undefined"&&window.addEventListener("storage",function(e){e.key.substring(0,prefixNodes.length==prefixNodes)&&(e.path=e.key.substring(prefixNodes.length),isDir(e.path)||(e.origin="device",fireChange(e)))}),{on:on,getNode:getNode,getNodeData:getNodeData,setNodeData:setNodeData,setNodeAccess:setNodeAccess,setNodeForce:setNodeForce,clearDiff:clearDiff,forget:forget,forgetAll:forgetAll}}),define("lib/sync",["./wireClient","./store","./util"],function(wireClient,store,util){function getState(path){return busy?"busy":"connected"}function setBusy(val){busy=val;for(var i=0;i<stateCbs.length;i++)stateCbs[i](val?"busy":"connected")}function on(eventType,cb){eventType=="state"&&stateCbs.push(cb)}function dirMerge(dirPath,remote,cached,diff,force,access,startOne,finishOne,clearCb){for(var i in remote)(!cached[i]&&!diff[i]||cached[i]<remote[i])&&pullNode(dirPath+i,force,access,startOne,finishOne);for(var i in cached)if(!remote[i]||cached[i]>remote[i])if(i.substr(-1)=="/")pullNode(dirPath+i,force,access,startOne,finishOne);else{var childNode=store.getNode(dirPath+i),childData=store.getNodeData(dirPath+i);startOne(),wireClient.set(dirPath+i,JSON.stringify(childData),"application/json",function(err){finishOne()})}for(var i in diff)cached[i]?remote[i]===cached[i]&&clearCb(i):remote[i]?(startOne(),wireClient.set(dirPath+i,undefined,undefined,function(err){finishOne()})):clearCb(i)}function pullNode(path,force,access,startOne,finishOne){var thisNode=store.getNode(path),thisData=store.getNodeData(path);!thisData&&path.substr(-1)=="/"&&(thisData={}),logger.debug("pullNode "+path,thisNode);if(thisNode.startAccess=="rw"||!access)access=thisNode.startAccess;thisNode.startForce&&(force=thisNode.startForce);if(access)startOne(),wireClient.get(path,function(err,data){!err&&data&&(path.substr(-1)=="/"?dirMerge(path,data,thisData,thisNode.diff,force,access,startOne,finishOne,function(i){store.clearDiff(path,i)}):store.setNodeData(path,data,!1)),finishOne(err)});else for(var i in thisData)i.substr(-1)=="/"&&pullNode(path+i,force,access,startOne,finishOne)}function fetchNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(err),outstanding--,outstanding==0&&(setBusy(!1),callback(errors||null,store.getNode(path)))}var outstanding=0,errors=[];setBusy(!0),pullNode(path,!1,!0,startOne,finishOne)}function syncNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(path),outstanding--,outstanding==0&&(setBusy(!1),callback&&callback(errors.length>0?errors:null))}if(wireClient.getState()=="anonymous"){callback&&callback(["not connected"]);return}var outstanding=0,errors=[];logger.info("syncNow "+path),setBusy(!0),pullNode(path,!1,!1,startOne,finishOne)}var prefix="_remoteStorage_",busy=!1,stateCbs=[],logger=util.getLogger("sync");return{syncNow:syncNow,fetchNow:fetchNow,getState:getState,on:on}}),define("lib/widget",["./assets","./webfinger","./hardcoded","./wireClient","./sync","./store","./platform"],function(assets,webfinger,hardcoded,wireClient,sync,store,platform){function translate(text){return text}function isRegistering(){return localStorage.getItem("remote_storage_registering")}function setRegistering(value){value===!1?localStorage.removeItem("remote_storage_registering"):localStorage.setItem("remote_storage_registering","true")}function calcWidgetStateOnLoad(){wc=wireClient;if(isRegistering())return"registering";var wireClientState=wireClient.getState();return wireClientState=="connected"?sync.getState():wireClientState}function setWidgetStateOnLoad(){setWidgetState(calcWidgetStateOnLoad())}function setWidgetState(state){widgetState=state,displayWidgetState(state,userAddress)}function getWidgetState(){return widgetState}function displayWidgetState(state,userAddress){var userAddress=localStorage.remote_storage_widget_useraddress,html="<style>"+assets.widgetCss+"</style>"+'<div id="remotestorage-state" class="'+state+'">'+'  <input id="remotestorage-connect-button" class="remotestorage-button" type="submit" value="'+translate("connect")+'"/>'+'  <span id="remotestorage-register-button" class="remotestorage-button">'+translate("get remoteStorage")+"</span>"+'  <img id="remotestorage-cube" src="'+assets.remoteStorageCube+'"/>'+'  <span id="remotestorage-disconnect">Disconnect '+(userAddress?"<strong>"+userAddress+"</strong>":"")+"</span>"+'  <a id="remotestorage-questionmark" href="http://unhosted.org/#remotestorage" target="_blank">?</a>'+'  <span class="infotext" id="remotestorage-infotext">This app allows you to use your own data storage!<br/>Click for more info on the Unhosted movement.</span>'+'  <input id="remotestorage-useraddress" type="text" value="me@local.dev" placeholder="you@remotestorage" autofocus="" />'+'  <a class="infotext" href="http://remotestoragejs.com/" target="_blank" id="remotestorage-devsonly">RemoteStorageJs is still in developer preview!<br/>Click for more info.</a>'+"</div>";platform.setElementHTML(connectElement,html),platform.eltOn("remotestorage-register-button","click",handleRegisterButtonClick),platform.eltOn("remotestorage-connect-button","click",handleConnectButtonClick),platform.eltOn("remotestorage-disconnect","click",handleDisconnectClick),platform.eltOn("remotestorage-cube","click",handleCubeClick),platform.eltOn("remotestorage-useraddress","type",handleWidgetTypeUserAddress)}function handleRegisterButtonClick(){setRegistering();var win=window.open("http://unhosted.org/en/a/register.html","Get your remote storage","resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=820,height=800,top=0,left=0");setWidgetState("registering")}function redirectUriToClientId(loc){if(loc.substring(0,"http://".length)=="http://")loc=loc.substring("http://".length);else{if(loc.substring(0,"https://".length)!="https://")return loc;loc=loc.substring("https://".length)}var hostParts=loc.split("/")[0].split("@");return hostParts.length>2?loc:(hostParts.length==2&&hostParts.shift(),hostParts[0])}function dance(endpoint){var endPointParts=endpoint.split("?"),queryParams=[];endPointParts.length==2?queryParams=endPointParts[1].split("&"):endPointParts.length>2&&errorHandler("more than one questionmark in auth-endpoint - ignoring");var loc=platform.getLocation(),scopesArr=[];for(var i in scopesObj)scopesArr.push(i+":"+scopesObj[i]);queryParams.push("response_type=token"),queryParams.push("scope="+encodeURIComponent(scopesArr.join(" "))),queryParams.push("redirect_uri="+encodeURIComponent(loc)),queryParams.push("client_id="+encodeURIComponent(redirectUriToClientId(loc))),platform.setLocation(endPointParts[0]+"?"+queryParams.join("&"))}function discoverStorageInfo(userAddress,cb){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?hardcoded.guessStorageInfo(userAddress,{timeout:3e3},function(err2,data2){err2?cb(err2):data2.type&&data2.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data2.type,data2.href),cb(null,data2.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from webfinger")}):data.type&&data.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data.type,data.href),cb(null,data.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from hardcoded")})}function handleConnectButtonClick(){widgetState=="typing"?(userAddress=platform.getElementValue("remotestorage-useraddress"),localStorage.remote_storage_widget_useraddress=userAddress,setWidgetState("connecting"),discoverStorageInfo(userAddress,function(err,auth){err?(alert("webfinger discovery failed! (sorry this is still a developer preview! developers, point local.dev to 127.0.0.1, then run sudo node server/nodejs-example.js from the repo)"),setWidgetState("failed")):dance(auth)})):setWidgetState("typing")}function handleDisconnectClick(){widgetState=="connected"?(wireClient.disconnectRemote(),store.forgetAll(),setWidgetState("anonymous")):alert("you cannot disconnect now, please wait until the cloud is up to date...")}function handleCubeClick(){sync.syncNow("/",function(errors){})}function handleWidgetTypeUserAddress(){setRegistering(!1),console.log("handleWidgetTypeUserAddress")}function handleWidgetHover(){console.log("handleWidgetHover")}function display(setConnectElement,setLocale){var tokenHarvested=platform.harvestParam("access_token"),storageRootHarvested=platform.harvestParam("storage_root"),storageApiHarvested=platform.harvestParam("storage_api"),authorizeEndpointHarvested=platform.harvestParam("authorize_endpoint");tokenHarvested&&wireClient.setBearerToken(tokenHarvested),storageRootHarvested&&wireClient.setStorageInfo(storageApiHarvested?storageApiHarvested:"2012.04",storageRootHarvested),authorizeEndpointHarvested&&dance(authorizeEndpointHarvested),connectElement=setConnectElement,locale=setLocale,wireClient.on("error",function(err){platform.alert(translate(err))}),sync.on("state",setWidgetState),setWidgetStateOnLoad(),window.onkeydown=function(evt){if(evt.ctrlKey&&evt.which==83)return evt.preventDefault(),console.log("CTRL+S - SYNCING"),sync.syncNow("/",function(errors){}),!1}}function addScope(module,mode){if(!scopesObj[module]||mode=="rw")scopesObj[module]=mode}var locale="en",connectElement,widgetState,userAddress,scopesObj={};return{display:display,addScope:addScope,getState:getWidgetState}}),define("lib/baseClient",["./sync","./store","./util"],function(sync,store,util){function bindContext(callback,context){return context?function(){return callback.apply(context,arguments)}:callback}function extractModuleName(path){if(path&&typeof path=="string"){var parts=path.split("/");if(parts.length>3&&parts[1]=="public")return parts[2];if(parts.length>2)return parts[1]}}function fireChange(moduleName,eventObj){if(moduleName&&moduleChangeHandlers[moduleName])for(var i=0;i<moduleChangeHandlers[moduleName].length;i++)moduleChangeHandlers[moduleName][i](eventObj)}function fireError(str){for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](str)}function set(path,absPath,valueStr){if(isDir(absPath)){fireError("attempt to set a value to a directory "+absPath);return}var node=store.getNode(absPath),changeEvent={origin:"window",oldValue:store.getNodeData(node),newValue:valueStr,path:path},ret=store.setNodeData(absPath,valueStr,!0),moduleName=extractModuleName(absPath);return fireChange(moduleName,changeEvent),fireChange("root",changeEvent),ret}function claimAccess(path,claim){store.setNodeAccess(path,claim)}function isDir(path){return typeof path!="string"&&doSomething(),path.substr(-1)=="/"}var moduleChangeHandlers={},errorHandlers=[],logger=util.getLogger("baseClient");return store.on("change",function(e){var moduleName=extractModuleName(e.path);fireChange(moduleName,e),fireChange("root",e)}),{claimAccess:claimAccess,getInstance:function(moduleName,isPublic){function makePath(path){return moduleName=="root"?path:(isPublic?"/public/":"/")+moduleName+"/"+path}function nodeGivesAccess(path,mode){var node=store.getNode(path);logger.debug("check node access",path,mode,node);var access=(new RegExp(mode)).test(node.startAccess);if(access)return!0;if(path.length>0)return nodeGivesAccess(path.replace(/[^\/]+\/?$/,""))}function ensureAccess(mode){var path=makePath(moduleName=="root"?"/":"");if(!nodeGivesAccess(path,mode))throw"Not sufficient access claimed for node at "+path}return{on:function(eventType,cb,context){eventType=="change"?moduleName&&(moduleChangeHandlers[moduleName]||(moduleChangeHandlers[moduleName]=[]),moduleChangeHandlers[moduleName].push(bindContext(cb,context))):eventType=="error"&&errorHandlers.push(bindContext(cb,context))},getObject:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath);return data&&typeof data=="object"&&delete data["@type"],data}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node);data&&typeof data=="object"&&delete data["@type"],bindContext(cb,context)(data)})},getListing:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath),arr=[];for(var i in data)arr.push(i);return arr}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node),arr=[];for(var i in data)arr.push(i);bindContext(cb,context)(arr)})},getDocument:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath);return{mimeType:node.mimeType,data:store.getNodeData(node)}}sync.fetchNow(absPath,function(err,node){bindContext(cb,context)({mimeType:node.mimeType,data:store.getNodeData(node)})})},remove:function(path,cb,context){ensureAccess("w");var ret=set(path,makePath(path));return this.syncNow(cb,context),ret},storeObject:function(type,path,obj,cb,context){ensureAccess("w");if(typeof obj!="object")throw"storeObject needs to get an object as value!";obj["@type"]="https://remotestoragejs.com/spec/modules/"+moduleName+"/"+type;var ret=set(path,makePath(path),obj,"application/json");return this.sync(path),this.syncNow(cb,context),ret},storeDocument:function(mimeType,path,data,cb,context){ensureAccess("w");var ret=set(path,makePath(path),data,mimeType);return this.syncNow(cb,context),ret},getItemURL:function(path){var base=remoteStorage.getStorageHref();return base?(base.substr(-1)!="/"&&(base+="/"),base+makePath(path)):null},getCurrentWebRoot:function(){return"https://example.com/this/is/an/example/"+(isPublic?"public/":"")+moduleName+"/"},sync:function(path,switchVal){var absPath=makePath(path);store.setNodeForce(absPath,switchVal!=0)},syncNow:function(cb,context){sync.syncNow(makePath(""),cb?bindContext(cb,context):function(errors){errors&&errors.length>0&&(logger.error("Error syncing: ",errors),fireError(errors))})},getState:function(path){}}}}}),define("lib/nodeConnect",["./wireClient","./webfinger"],function(wireClient,webfinger){return{setUserAddress:function(userAddress,callback){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?console.error("Failed to look up storage info for user "+userAddress+": ",err):wireClient.setStorageInfo(data.type,data.href),callback(err)})},setStorageInfo:wireClient.setStorageInfo,setBearerToken:wireClient.setBearerToken}}),define("remoteStorage",["require","./lib/widget","./lib/baseClient","./lib/store","./lib/sync","./lib/wireClient","./lib/nodeConnect","./lib/util"],function(require,widget,baseClient,store,sync,wireClient,nodeConnect,util){function deprecate(oldFn,newFn){logger.error("DEPRECATION: "+oldFn+" is deprecated! Use "+newFn+" instead.")}var claimedModules={},modules={},logger=util.getLogger("base"),remoteStorage={defineModule:function(moduleName,builder){logger.debug("DEFINE MODULE",moduleName);var module=builder(baseClient.getInstance(moduleName,!1),baseClient.getInstance(moduleName,!0));modules[moduleName]=module,this[moduleName]=module.exports,logger.debug("Module defined: "+moduleName,module,this)},getModuleList:function(){return Object.keys(modules)},getClaimedModuleList:function(){return Object.keys(claimedModules)},getModuleInfo:function(moduleName){return modules[moduleName]},claimAccess:function(claimed){if(typeof claimed!="object"||claimed instanceof Array){claimed instanceof Array||(claimed=Array.prototype.slice.call(arguments));var _modules=claimed,mode="rw";claimed={};var lastArg=arguments[arguments.length-1];typeof lastArg=="string"&&lastArg.match(/^rw?$/)&&(mode=lastArg,delete arguments[arguments.length-1]);for(var i in _modules)claimed[_modules[i]]=mode}for(var moduleName in claimed)this.claimModuleAccess(moduleName,claimed[moduleName])},claimModuleAccess:function(moduleName,mode){logger.debug("claimModuleAccess",moduleName,mode);if(!moduleName in modules)throw"Module not defined: "+moduleName;if(moduleName in claimedModules)return;mode||(mode="r"),moduleName=="root"?(moduleName="",widget.addScope("",mode),baseClient.claimAccess("/",mode)):(widget.addScope(moduleName,mode),baseClient.claimAccess("/"+moduleName+"/",mode),baseClient.claimAccess("/public/"+moduleName+"/",mode)),claimedModules[moduleName]=!0},loadModule:function(){deprecate("remoteStorage.loadModule","remoteStorage.claimAccess"),this.claimModuleAccess.apply(this,arguments)},setBearerToken:function(bearerToken,claimedScopes){wireClient.setBearerToken(bearerToken),baseClient.claimScopes(claimedScopes)},disconnectRemote:wireClient.disconnectRemote,flushLocal:store.forgetAll,syncNow:sync.syncNow,displayWidget:widget.display,getWidgetState:widget.getState,setStorageInfo:wireClient.setStorageInfo,getStorageHref:wireClient.getStorageHref,nodeConnect:nodeConnect,util:util};return remoteStorage}),remoteStorage=require("remoteStorage")})()
\ No newline at end of file
+(function(){var requirejs,require,define;(function(undef){function normalize(name,baseName){var nameParts,nameSegment,mapValue,foundMap,foundI,foundStarMap,starI,i,j,part,baseParts=baseName&&baseName.split("/"),map=config.map,starMap=map&&map["*"]||{};if(name&&name.charAt(0)==="."&&baseName){baseParts=baseParts.slice(0,baseParts.length-1),name=baseParts.concat(name.split("/"));for(i=0;i<name.length;i+=1){part=name[i];if(part===".")name.splice(i,1),i-=1;else if(part===".."){if(i===1&&(name[2]===".."||name[0]===".."))break;i>0&&(name.splice(i-1,2),i-=2)}}name=name.join("/")}if((baseParts||starMap)&&map){nameParts=name.split("/");for(i=nameParts.length;i>0;i-=1){nameSegment=nameParts.slice(0,i).join("/");if(baseParts)for(j=baseParts.length;j>0;j-=1){mapValue=map[baseParts.slice(0,j).join("/")];if(mapValue){mapValue=mapValue[nameSegment];if(mapValue){foundMap=mapValue,foundI=i;break}}}if(foundMap)break;!foundStarMap&&starMap&&starMap[nameSegment]&&(foundStarMap=starMap[nameSegment],starI=i)}!foundMap&&foundStarMap&&(foundMap=foundStarMap,foundI=starI),foundMap&&(nameParts.splice(0,foundI,foundMap),name=nameParts.join("/"))}return name}function makeRequire(relName,forceSync){return function(){return req.apply(undef,aps.call(arguments,0).concat([relName,forceSync]))}}function makeNormalize(relName){return function(name){return normalize(name,relName)}}function makeLoad(depName){return function(value){defined[depName]=value}}function callDep(name){if(waiting.hasOwnProperty(name)){var args=waiting[name];delete waiting[name],defining[name]=!0,main.apply(undef,args)}if(!defined.hasOwnProperty(name))throw new Error("No "+name);return defined[name]}function makeMap(name,relName){var prefix,plugin,index=name.indexOf("!");return index!==-1?(prefix=normalize(name.slice(0,index),relName),name=name.slice(index+1),plugin=callDep(prefix),plugin&&plugin.normalize?name=plugin.normalize(name,makeNormalize(relName)):name=normalize(name,relName)):name=normalize(name,relName),{f:prefix?prefix+"!"+name:name,n:name,p:plugin}}function makeConfig(name){return function(){return config&&config.config&&config.config[name]||{}}}var main,req,defined={},waiting={},config={},defining={},aps=[].slice;main=function(name,deps,callback,relName){var cjsModule,depName,ret,map,i,args=[],usingExports;relName=relName||name;if(typeof callback=="function"){deps=!deps.length&&callback.length?["require","exports","module"]:deps;for(i=0;i<deps.length;i+=1){map=makeMap(deps[i],relName),depName=map.f;if(depName==="require")args[i]=makeRequire(name);else if(depName==="exports")args[i]=defined[name]={},usingExports=!0;else if(depName==="module")cjsModule=args[i]={id:name,uri:"",exports:defined[name],config:makeConfig(name)};else if(defined.hasOwnProperty(depName)||waiting.hasOwnProperty(depName))args[i]=callDep(depName);else if(map.p)map.p.load(map.n,makeRequire(relName,!0),makeLoad(depName),{}),args[i]=defined[depName];else if(!defining[depName])throw new Error(name+" missing "+depName)}ret=callback.apply(defined[name],args);if(name)if(cjsModule&&cjsModule.exports!==undef&&cjsModule.exports!==defined[name])defined[name]=cjsModule.exports;else if(ret!==undef||!usingExports)defined[name]=ret}else name&&(defined[name]=callback)},requirejs=require=req=function(deps,callback,relName,forceSync,alt){return typeof deps=="string"?callDep(makeMap(deps,callback).f):(deps.splice||(config=deps,callback.splice?(deps=callback,callback=relName,relName=null):deps=undef),callback=callback||function(){},typeof relName=="function"&&(relName=forceSync,forceSync=alt),forceSync?main(undef,deps,callback,relName):setTimeout(function(){main(undef,deps,callback,relName)},15),req)},req.config=function(cfg){return config=cfg,req},define=function(name,deps,callback){deps.splice||(callback=deps,deps=[]),waiting[name]=[name,deps,callback]},define.amd={jQuery:!0}})(),define("../build/lib/almond",function(){}),define("lib/assets",[],function(){return{remoteStorageIcon:"data:image/png;base64,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",remoteStorageCube:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAR2SURBVFiFtddfqGVVHQfwz2/vfZ28c2WgP6hMoYkUV4qIYnSKmaQYwaaJ3oLeUnpJmDCmUhCaIhhKGelhelCqN9+ECKdAxR6kgnJASBN9KTGwP2oKTtyZs8/+9bDXPufcfe51xju6YLHX2fu3ft/v+q7fWb/fisy0o3brez6qmt4Luvo7frvx/E7cxNsmcCj2WGnuEb6JaXlbSz8zaX/ksXzj3SHwg6j8aeU28jjeh8TZ8nU3Aq8Sx+2b/ML3s3vnCHxp5YB0Hz6OTkgpMax2jxBSoMJfhGMemTx5aQQOxzWsnCC/gm6hZ+mvFMv36xUYCJQev2Jyt9P54tsj8OVYNW2+izuxIkzlAoGUQuLlMuNqKcQCgVBJNSa4X93+xK/zfxcmcLj5GtUJ8ipMC/i0gA/PQYF/lFkfHClQFxJ1IVET/6S72+n2oa0JHL7s0+RPsR9tAZuOxuNtGKS9xpL8A7BmNP4j8S2nzz+lGJaWDxB7RyCbV54DkZiSrbAhbJBt/25LtUbEY2+P1bdmQY1V8mr8DruET5Z9n4NHTOmmZK9A2ihzp3RdL3tVy+z16OeG0ElncI48yGzeogIzQgexByelp2fMZ+CDAtFK56XzxFwBXSE6C9incbL4PDha9BKBPrjCddJRVT5DHsMLczkLUGhFbPR9iJNYjJUXyGOqfEY6KlxnHrybVjwm0JVDJmV8FZ8TeZysZdyBK9FKXb/6mdTZ+4uXRXcKUxnHpavKdqV58G5JYJFdLvT3yuok3ROiuY3JZ3Rxu7CH7lxvHlPpNVX+nJU/yMk9VJ8nm5GvMc42W6Bwnhl2KRyQ7cOyaqy1R0ScEvFq6aestUdk1cj2YeEA3RwwtwbfSoHtxxmJXeS3nV25RR0/9KnJL8GZyz7i7MoD5MfQ9LZ5YZ+WY+AiW16vc8if/av8PkRevxNPiwTiLceRISPIM3iUOGxa/wfUbiTvxy3ETb3tRfi0HAMx+xgLY1XIeAUPYoO4S+YNqupyVXW5zBuIu/pvHuxtq5j5DLHkfxsFxoaBlN1vVKbEN2TQ5wdYLc8++YibhZvJx3VZizgy8rVEYhwDfUKZFxd/Jf8m4gsydtENJ17TZ8lcLbOGrFfJrKmOiDxHPk58GJ8oPqu3UmDOLr2B5/AhYt08K9Z9AMdAsCeQml6BnKdiriC+iP/iKWkdH7gQgSRfQoi4SWoLcMqsRaUcZiX1xu4yrZmpp6p721lavlLYK/PfeIm4djsCE7xZDNqSVocV9evNJCKIjq6TuTbbAlWvQGZfiCwWJqkqqb7pMUwG0IV/QXwdz1ouKjZXOP021EQjqt2i2k00/Tv1Evj8OfRnC1aPeokl2e/LrM/aYUk2Pgc43T6knqzjBCZytqqhpGpK0DXCmrC26d1Qgs3BJzihnqyPwbdWYJMaFyzLnyuW6yMFLrEsH7ftLyZ/LxbX7vRisrwFW7VHJk/a1+4njuL1udx5Rd9nW/A6cdS+dv/FgHPpl9PhorH67l9Ox62/nv8YdPX3dno9/z+G+TGrzjgPKwAAAABJRU5ErkJggg==",widgetCss:"#remotestorage-state { position:fixed; top:15px; right:15px; height:32px; width:275px; font:normal 16px/100% sans-serif; z-index:99999; background:rgba(0,0,0,.3); padding:5px; border-radius:7px; box-shadow:0 1px rgba(255,255,255,.05), inset 0 1px rgba(0,0,0,.05); transition:width 500ms, background 500ms; }\n#remotestorage-state.connected, #remotestorage-state.busy, #remotestorage-state.offline { width:32px; background:none; box-shadow:none; }\n.remotestorage-button { margin:0; padding:.3em; font-size:14px; height:26px !important; background:#ddd; color:#333; border:1px solid #ccc; border-radius:3px; box-shadow:0 1px 1px #fff inset; }\n#remotestorage-register-button { position:absolute; left:25px; top:8px; max-height:16px; text-decoration:none; font-weight:normal; }\n#remotestorage-connect-button { position:absolute; right:8px; top:8px; padding:0 0 0 17px; width:90px; cursor:pointer; text-align:left; border-radius:0 3px 3px 0; font-weight:normal; }\n#remotestorage-connect-button:hover, #remotestorage-connect-button:focus, .remotestorage-button:hover, .remotestorage-button:focus { background:#eee; color:#000; text-decoration:none; }\n#remotestorage-useraddress { position:absolute; left:25px; top:8px; margin:0; padding:0 17px 0 3px; height:25px; width:142px; background:#eee; color:#333; border:0; border-radius:3px 0 0 3px; box-shadow:0 1px #fff, inset 0 1px #999; font-weight:normal; font-size:14px;}\n#remotestorage-useraddress:hover, #remotestorage-useraddress:focus { background:#fff; color:#000; }\n#remotestorage-cube { position:absolute; right:84px; -webkit-transition:right 500ms; -moz-transition:right 500ms; transition:right 500ms; z-index:99997; }\n#remotestorage-questionmark { position:absolute; left:0; padding:9px 8px; color:#fff; text-decoration:none; z-index:99999; font-weight:normal; }\n.infotext { position:absolute; left:0; top:0; width:255px; height:32px; padding:6px 5px 4px 25px; font-size:10px; background:black; color:white; border-radius:7px; opacity:.85; text-decoration:none; white-space:nowrap; z-index:99998; }\n#remotestorage-questiomark:hover { color:#fff; }\n#remotestorage-questionmark:hover+#remotestorage-infotext { display:inline; }\n#remotestorage-state.busy #remotestorage-cube, #remotestorage-state.connecting #remotestorage-cube {   -webkit-animation-name:remotestorage-loading; -webkit-animation-duration:2s; -webkit-animation-iteration-count:infinite; -webkit-animation-timing-function:linear;\n   -moz-animation-name:remotestorage-loading; -moz-animation-duration:2s; -moz-animation-iteration-count:infinite; -moz-animation-timing-function:linear;\n   -o-animation-name:remotestorage-loading; -o-animation-duration:2s; -o-animation-iteration-count:infinite; -o-animation-timing-function:linear;\n   -ms-animation-name:remotestorage-loading; -ms-animation-duration:2s; -ms-animation-iteration-count:infinite; -ms-animation-timing-function:linear; }\n   @-webkit-keyframes remotestorage-loading { from{-webkit-transform:rotate(0deg)} to{-webkit-transform:rotate(360deg)} }\n   @-moz-keyframes remotestorage-loading { from{-moz-transform:rotate(0deg)} to{-moz-transform:rotate(360deg)} }\n   @-o-keyframes remotestorage-loading { from{-o-transform:rotate(0deg)} to{-o-transform:rotate(360deg)} }\n   @-ms-keyframes remotestorage-loading { from{-ms-transform:rotate(0deg)} to{ -ms-transform:rotate(360deg)} }\n#remotestorage-connect-button, #remotestorage-questionmark, #remotestorage-register-button, #remotestorage-cube, #remotestorage-useraddress, #remotestorage-infotext, #remotestorage-devsonly, #remotestorage-disconnect { display:none }\n#remotestorage-state.anonymous #remotestorage-cube, #remotestorage-state.anonymous #remotestorage-connect-button, #remotestorage-state.anonymous #remotestorage-register-button, #remotestorage-state.anonymous #remotestorage-questionmark { display: block }\n#remotestorage-state.registering #remotestorage-cube, #remotestorage-state.registering #remotestorage-connect-button, #remotestorage-state.registering #remotestorage-register-button, #remotestorage-state.registering #remotestorage-questionmark { display: block }\n#remotestorage-state.interrupted #remotestorage-cube, #remotestorage-state.interrupted #remotestorage-connect-button, #remotestorage-state.interrupted #remotestorage-register-button, #remotestorage-state.interrupted #remotestorage-questionmark { display: block }\n#remotestorage-state.failed #remotestorage-cube, #remotestorage-state.failed #remotestorage-connect-button, #remotestorage-state.failed #remotestorage-register-button, #remotestorage-state.failed #remotestorage-questionmark { display: block }\n#remotestorage-state.typing #remotestorage-cube, #remotestorage-state.typing #remotestorage-connect-button, #remotestorage-state.typing #remotestorage-useraddress, #remotestorage-state.typing #remotestorage-questionmark { display: block }\n#remotestorage-state.connected #remotestorage-cube, #remotestorage-state.busy #remotestorage-cube, #remotestorage-state.offline #remotestorage-cube { right:0; opacity:.5; cursor:pointer; display: block }\n#remotestorage-state.devsonly #remotestorage-devsonly { display: block }\n#remotestorage-disconnect { position:absolute; right:6px; top:9px; padding:5px 28px 2px 6px; height:17px; white-space:nowrap; font-size:10px; background:#000; color:#fff; border-radius:5px; opacity:.5; text-decoration:none; z-index:99996; }\n#remotestorage-disconnect strong { font-weight:bold; }\n#remotestorage-state.connected #remotestorage-cube:hover, #remotestorage-state.busy #remotestorage-cube:hover, #remotestorage-state.offline #remotestorage-cube:hover { opacity:1; }\n#remotestorage-state.connected #remotestorage-disconnect:hover, #remotestorage-state.busy #remotestorage-disconnect:hover, #remotestorage-state.offline #remotestorage-disconnect:hover { display:inline; }\n#remotestorage-state.connected #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.busy #remotestorage-cube:hover+#remotestorage-disconnect, #remotestorage-state.offline #remotestorage-cube:hover+#remotestorage-disconnect { display:inline; }\n"}}),define("lib/util",[],function(){var loggers={},silentLogger={},knownLoggers=["sync","webfinger","getputdelete","platform","baseClient"],util={toArray:function(enumerable){var a=[];for(var i in enumerable)a.push(enumerable[i]);return a},getLogger:function(name){return loggers[name]||(loggers[name]={info:function(){this.log("info",util.toArray(arguments))},debug:function(){this.log("debug",util.toArray(arguments),"debug")},error:function(){this.log("error",util.toArray(arguments),"error")},log:function(level,args,type){if(silentLogger[name])return;type||(type="log"),args.unshift("["+name.toUpperCase()+"] -- "+level+" "),(console[type]||console.log).apply(console,args)}}),loggers[name]},silenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)silentLogger[names[i]]=!0},unsilenceLogger:function(){var names=util.toArray(arguments);for(var i=0;i<names.length;i++)delete silentLogger[names[i]]},silenceAllLoggers:function(){this.silenceLogger.apply(this,knownLoggers)},unsilenceAllLoggers:function(){this.unsilenceLogger.apply(this,knownLoggers)}};return util}),define("lib/platform",["./util"],function(util){function browserParseHeaders(rawHeaders){var headers={},lines=rawHeaders.split(/\r?\n/),lastKey=null,md,key,value;for(var i=0;i<lines.length;i++){if(lines[i].length==0)continue;(md=lines[i].match(/^([^:]+):\s*(.+)$/))?(key=md[1],value=md[2],headers[key]=value,lastKey=key):(md=lines[i].match(/^\s+(.+)$/))?(key=lastKey,value=md[1],headers[key]=headers[key]+value):logger.error("Failed to parse header line: "+lines[i])}return headers}function ajaxBrowser(params){var timedOut=!1,timer;params.timeout&&(timer=window.setTimeout(function(){timedOut=!0,params.error("timeout")},params.timeout));var xhr=new XMLHttpRequest;params.method||(params.method="GET"),xhr.open(params.method,params.url,!0);if(params.headers)for(var header in params.headers)xhr.setRequestHeader(header,params.headers[header]);logger.debug("A "+params.url),xhr.onreadystatechange=function(){xhr.readyState==4&&!timedOut&&(logger.debug("B "+params.url),timer&&window.clearTimeout(timer),logger.debug("xhr cb "+params.url),xhr.status==200||xhr.status==201||xhr.status==204||xhr.status==207?params.success(xhr.responseText,browserParseHeaders(xhr.getAllResponseHeaders())):params.error(xhr.status))},logger.debug("xhr "+params.url),typeof params.data=="string"?xhr.send(params.data):xhr.send()}function ajaxExplorer(params){var xdr=new XDomainRequest;xdr.timeout=params.timeout||3e3,xdr.open(params.method,params.url),xdr.onload=function(){xdr.status==200||xdr.status==201||xdr.status==204?params.success(xhr.responseText):params.error(xhr.status)},xdr.onerror=function(){err("unknown error")},xdr.ontimeout=function(){err(timeout)},params.data?xdr.send(params.data):xdr.send()}function ajaxNode(params){function normalizeHeaders(headers){var h={};for(var key in headers)h[key.replace(/(?:^|\-)[a-z]/g,function(match){return match.toUpperCase()})]=headers[key];return h}var http=require("http"),https=require("https"),url=require("url");params.method||(params.method="GET"),params.data?params.headers["content-length"]=params.data.length:params.data=null;var urlObj=url.parse(params.url),options={method:params.method,host:urlObj.hostname,path:urlObj.path,port:urlObj.port?port:urlObj.protocol=="https:"?443:80,headers:params.headers},timer,timedOut;params.timeout&&(timer=setTimeout(function(){params.error("timeout"),timedOut=!0},params.timeout));var lib=urlObj.protocol=="https:"?https:http,request=lib.request(options,function(response){var str="";response.setEncoding("utf8"),response.on("data",function(chunk){str+=chunk}),response.on("end",function(){timer&&clearTimeout(timer),timedOut||(response.statusCode==200||response.statusCode==201||response.statusCode==204?params.success(str,normalizeHeaders(response.headers)):params.error(response.statusCode))})});request.on("error",function(e){timer&&clearTimeout(timer),params.error(e.message)}),params.data?request.end(params.data):request.end()}function parseXmlBrowser(str,cb){var tree=(new DOMParser).parseFromString(str,"text/xml"),nodes=tree.getElementsByTagName("Link"),obj={Link:[]};for(var i=0;i<nodes.length;i++){var link={};if(nodes[i].attributes)for(var j=0;j<nodes[i].attributes.length;j++)link[nodes[i].attributes[j].name]=nodes[i].attributes[j].value;var props=nodes[i].getElementsByTagName("Property");link.properties={},xyz=props;for(var k=0;k<props.length;k++)link.properties[props[k].getAttribute("type")]=props[k].childNodes[0].nodeValue;link.rel&&obj.Link.push({"@":link})}cb(null,obj)}function parseXmlNode(str,cb){var xml2js=require("xml2js");(new xml2js.Parser).parseString(str,cb)}function harvestParamNode(){}function harvestParamBrowser(param){if(location.hash.length){var pairs=location.hash.substring(1).split("&");for(var i=0;i<pairs.length;i++)if(pairs[i].substring(0,(param+"=").length)==param+"="){var ret=decodeURIComponent(pairs[i].substring((param+"=").length));return delete pairs[i],location="#"+pairs.join("&"),ret}}}function setElementHtmlNode(eltName,html){}function setElementHtmlBrowser(eltName,html){var elt=eltName;elt instanceof Element||(elt=document.getElementById(eltName)),elt.innerHTML=html}function getElementValueNode(eltName){}function getElementValueBrowser(eltName){return document.getElementById(eltName).value}function eltOnNode(eltName,eventType,cb){}function eltOnBrowser(eltName,eventType,cb){eventType=="click"?document.getElementById(eltName).onclick=cb:eventType=="hover"?document.getElementById(eltName).onmouseover=cb:eventType=="type"&&(document.getElementById(eltName).onkeyup=cb)}function getLocationBrowser(){return window.location.href.split("#")[0]}function getLocationNode(){}function setLocationBrowser(location){window.location=location}function setLocationNode(){}function alertBrowser(str){alert(str)}function alertNode(str){console.log(str)}var logger=util.getLogger("platform");return typeof window=="undefined"?{ajax:ajaxNode,parseXml:parseXmlNode,harvestParam:harvestParamNode,setElementHTML:setElementHtmlNode,getElementValue:getElementValueNode,eltOn:eltOnNode,getLocation:getLocationNode,setLocation:setLocationNode,alert:alertNode}:window.XDomainRequest?{ajax:ajaxExplorer,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}:{ajax:ajaxBrowser,parseXml:parseXmlBrowser,harvestParam:harvestParamBrowser,setElementHTML:setElementHtmlBrowser,getElementValue:getElementValueBrowser,eltOn:eltOnBrowser,getLocation:getLocationBrowser,setLocation:setLocationBrowser,alert:alertBrowser}}),define("lib/webfinger",["./platform","./util"],function(platform,util){function userAddress2hostMetas(userAddress,cb){var parts=userAddress.toLowerCase().split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9a-z\-\_]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9a-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{var query="?resource=acct:"+encodeURIComponent(userAddress);cb(null,["https://"+parts[1]+"/.well-known/host-meta.json"+query,"https://"+parts[1]+"/.well-known/host-meta"+query,"http://"+parts[1]+"/.well-known/host-meta.json"+query,"http://"+parts[1]+"/.well-known/host-meta"+query])}}function fetchXrd(addresses,timeout,cb){var firstAddress=addresses.shift();firstAddress?platform.ajax({url:firstAddress,success:function(data){parseAsJrd(data,function(err,obj){err?parseAsXrd(data,function(err,obj){err?fetchXrd(addresses,timeout,cb):cb(null,obj)}):cb(null,obj)})},error:function(data){fetchXrd(addresses,timeout,cb)},timeout:timeout}):cb("could not fetch xrd")}function parseAsXrd(str,cb){platform.parseXml(str,function(err,obj){if(err)cb(err);else if(obj&&obj.Link){var links={};if(obj.Link&&obj.Link["@"])obj.Link["@"].rel&&(links[obj.Link["@"].rel]=obj.Link["@"]);else for(var i=0;i<obj.Link.length;i++)obj.Link[i]["@"]&&obj.Link[i]["@"].rel&&(links[obj.Link[i]["@"].rel]=obj.Link[i]["@"]);cb(null,links)}else cb("found valid xml but with no Link elements in there")})}function parseAsJrd(str,cb){var obj;try{obj=JSON.parse(str)}catch(e){cb("not valid JSON");return}obj.links||cb("JRD contains no links");var links={};for(var i=0;i<obj.links.length;i++)obj.links[i].rel&&(links[obj.links[i].rel]=obj.links[i]);cb(null,links)}function parseRemoteStorageLink(obj,cb){obj&&obj.href&&obj.type&&obj.properties&&obj.properties["auth-endpoint"]?cb(null,obj):cb("could not extract storageInfo from lrdd")}function getStorageInfo(userAddress,options,cb){userAddress2hostMetas(userAddress,function(err1,hostMetaAddresses){logger.debug("HOST META ADDRESSES",hostMetaAddresses,"(error: ",err1,")"),err1?cb(err1):fetchXrd(hostMetaAddresses,options.timeout,function(err2,hostMetaLinks){if(err2)cb("could not fetch host-meta for "+userAddress);else if(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage)parseRemoteStorageLink(hostMetaLinks.remoteStorage||hostMetaLinks.remotestorage,cb);else if(hostMetaLinks.lrdd&&hostMetaLinks.lrdd.template){var parts=hostMetaLinks.lrdd.template.split("{uri}"),lrddAddresses=[parts.join("acct:"+userAddress),parts.join(userAddress)];fetchXrd(lrddAddresses,options.timeout,function(err4,lrddLinks){err4?cb("could not fetch lrdd for "+userAddress):lrddLinks.remoteStorage?parseRemoteStorageLink(lrddLinks.remoteStorage,cb):lrddLinks.remotestorage?parseRemoteStorageLink(lrddLinks.remotestorage,cb):cb("could not extract storageInfo from lrdd")})}else cb("could not extract lrdd template from host-meta")})})}var logger=util.getLogger("webfinger");return{getStorageInfo:getStorageInfo}}),define("lib/hardcoded",["./platform"],function(platform){function testIrisCouch(userAddress,options,cb){platform.ajax({url:"http://proxy.unhosted.org/irisCouchCheck?q=acct:"+userAddress,success:function(data){var obj;try{obj=JSON.parse(data)}catch(e){}obj?cb(null,obj):cb("err: unparsable response from IrisCouch check")},error:function(err){cb("err: during IrisCouch test:"+err)},timeout:options.timeout})}function mapToIrisCouch(userAddress){var parts=userAddress.split("@");return["libredocs","mail","browserid","me"].indexOf(parts[0])==-1?parts[0]+"@iriscouch.com":parts[2].substring(0,parts[2].indexOf("."))+"@iriscouch.com"}function guessStorageInfo(userAddress,options,cb){var parts=userAddress.split("@");if(parts.length<2)cb("That is not a user address. There is no @-sign in it");else if(parts.length>2)cb("That is not a user address. There is more than one @-sign in it");else if(!/^[\.0-9A-Za-z]+$/.test(parts[0]))cb('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');else if(!/^[\.0-9A-Za-z\-]+$/.test(parts[1]))cb('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');else{while(parts[1].indexOf(".")!=-1){if(guesses[parts[1]]){blueprint=guesses[parts[1]],cb(null,{rel:"https://www.w3.org/community/unhosted/wiki/personal-data-service-00",type:blueprint.type,href:blueprint.hrefPrefix+"/"+(blueprint.pathFormat=="user@host"?userAddress:parts[1]+"/"+parts[0]),properties:{"access-methods":["http://oauth.net/core/1.0/parameters/auth-header"],"auth-methods":["http://oauth.net/discovery/1.0/consumer-identity/static"],"auth-endpoint":blueprint.authPrefix+userAddress}});return}parts[1]=parts[1].substring(parts[1].indexOf(".")+1)}new Date<new Date("9/9/2012")?testIrisCouch(userAddress,options,cb):cb("err: not a guessable domain, and fakefinger-migration has ended")}}var guesses={"iriscouch.com":{type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#couchdb",authPrefix:"http://proxy.unhosted.org/OAuth.html?userAddress=",hrefPrefix:"http://proxy.unhosted.org/CouchDb",pathFormat:"host/user"}};return function(){var surfnetSaml={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/saml/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/saml",pathFormat:"user@host"},surfnetBrowserId={type:"https://www.w3.org/community/unhosted/wiki/remotestorage-2011.10#simple",authPrefix:"https://storage.surfnetlabs.nl/browserid/oauth/authorize?user_address=",hrefPrefix:"https://storage.surfnetlabs.nl/browserid",pathFormat:"user@host"},dutchUniversitiesNoSaml=["leidenuniv.nl","leiden.edu","uva.nl","vu.nl","eur.nl","maastrichtuniversity.nl","ru.nl","rug.nl","uu.nl","tudelft.nl","utwente.nl","tue.nl","tilburguniversity.edu","uvt.nl","wur.nl","wageningenuniversity.nl","ou.nl","lumc.nl","amc.nl","ahk.nl","cah.nl","driestar.nl","che.nl","chn.nl","hen.nl","huygens.nl","diedenoort.nl","efa.nl","dehaagsehogeschool.nl","hasdenbosch.nl","inholland.nl","hsbrabant.nl","dehorst.nl","kempel.nl","domstad.nl","hsdrenthe.nl","edith.nl","hsleiden.nl","interport.nl","schumann.nl","hsbos.nl","hva.nl","han.nl","hvu.nl","hesasd.nl","hes-rdam.nl","hku.nl","hmtr.nl","hzeeland.nl","hotelschool.nl","ichtus-rdam.nl","larenstein.nl","iselinge.nl","koncon.nl","kabk.nl","lhump.nl","msm.nl","hsmarnix.nl","nhtv.nl","nth.nl","nhl.nl","sandberg.nl","hsij.nl","stoas.nl","thrijswijk.nl","tio.nl","vhall.nl","chw.nl","hogeschoolrotterdam.nl"],dutchUniversitiesSaml=["surfnet.nl","fontys.nl"];for(var i=0;i<dutchUniversitiesSaml.length;i++)guesses[dutchUniversitiesSaml[i]]=surfnetSaml;for(var i=0;i<dutchUniversitiesNoSaml.length;i++)guesses[dutchUniversitiesNoSaml[i]]=surfnetBrowserId}(),{guessStorageInfo:guessStorageInfo}}),define("lib/getputdelete",["./platform","./util"],function(platform,util){function doCall(method,url,value,mimeType,token,cb,deadLine){var platformObj={url:url,method:method,error:function(err){cb(err)},success:function(data,headers){logger.debug("doCall cb "+url,"headers:",headers),cb(null,data,headers["Content-Type"]||defaultContentType)},timeout:3e3};platformObj.headers={Authorization:"Bearer "+token},mimeType&&(platformObj.headers["Content-Type"]=mimeType),platformObj.fields={withCredentials:"true"},method!="GET"&&(platformObj.data=value),logger.debug("platform.ajax "+url),platform.ajax(platformObj)}function get(url,token,cb){doCall("GET",url,null,null,token,function(err,data,mimetype){if(err==404)cb(null,undefined);else{if(url.substr(-1)=="/")try{data=JSON.parse(data)}catch(e){cb("unparseable directory index");return}cb(err,data,mimetype)}})}function put(url,value,mimeType,token,cb){logger.info("calling PUT "+url),doCall("PUT",url,value,mimeType,token,function(err,data){logger.debug("cb from PUT "+url),err==404?doPut(url,value,token,1,cb):cb(err,data)})}function set(url,valueStr,mimeType,token,cb){typeof valueStr=="undefined"?doCall("DELETE",url,null,null,token,cb):put(url,valueStr,mimeType,token,cb)}var logger=util.getLogger("getputdelete"),defaultContentType="application/octet-stream";return{get:get,set:set}}),define("lib/wireClient",["./getputdelete"],function(getputdelete){function set(key,value){localStorage.setItem(prefix+key,JSON.stringify(value))}function remove(key){localStorage.removeItem(prefix+key)}function get(key){var valStr=localStorage.getItem(prefix+key);if(typeof valStr=="string")try{return JSON.parse(valStr)}catch(e){localStorage.removeItem(prefix+key)}return null}function disconnectRemote(){remove("storageType"),remove("storageHref"),remove("bearerToken")}function getState(){return get("storageType")&&get("storageHref")?get("bearerToken")?"connected":"authing":"anonymous"}function on(eventType,cb){eventType=="error"&&(errorHandler=cb)}function resolveKey(storageType,storageHref,basePath,relPath){var item=(basePath.length?basePath+"/":"")+relPath;return storageHref+item}function setChain(driver,hashMap,mimeType,token,cb,timestamp){var i;for(i in hashMap)break;if(i){var thisOne=hashMap[i];delete hashMap[i],driver.set(i,thisOne,mimeType,token,function(err,timestamp){err?cb(err):setChain(driver,hashMap,mimeType,token,cb,timestamp)})}else cb(null,timestamp)}var prefix="remote_storage_wire_",errorHandler=function(){};return{get:function(path,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.get(resolveKey(storageType,storageHref,"",path),token,cb)},set:function(path,valueStr,mimeType,cb){var storageType=get("storageType"),storageHref=get("storageHref"),token=get("bearerToken");typeof path!="string"?cb('argument "path" should be a string'):getputdelete.set(resolveKey(storageType,storageHref,"",path),valueStr,mimeType,token,cb)},setStorageInfo:function(type,href){set("storageType",type),set("storageHref",href)},getStorageHref:function(){return get("storageHref")},setBearerToken:function(bearerToken){set("bearerToken",bearerToken)},disconnectRemote:disconnectRemote,on:on,getState:getState}}),define("lib/store",["./util"],function(util){function fireChange(e){for(var i=0;i<onChange.length;i++)onChange[i](e)}function getNode(path){var valueStr=localStorage.getItem(prefixNodes+path),value;if(valueStr)try{value=JSON.parse(valueStr)}catch(e){}return value||(value={startAccess:null,startForce:null,timestamp:0,keep:!0,diff:{}}),value}function isDir(path){return typeof path!="string"&&(logger.error("Given path is not a string: ",path),doSomething()),path.substr(-1)=="/"}function getContainingDir(path){var parts=path.split("/");return parts[parts.length-1].length||parts.pop(),parts.length?(parts.pop(),parts.join("/")+(parts.length?"/":"")):undefined}function getFileName(path){var parts=path.split("/");return isDir(path)?parts[parts.length-2]+"/":parts[parts.length-1]}function getCurrTimestamp(){return(new Date).getTime()}function updateNode(path,node,outgoing,meta,timestamp){node?localStorage.setItem(prefixNodes+path,JSON.stringify(node)):localStorage.removeItem(prefixNodes+path);var containingDir=getContainingDir(path);if(containingDir){var parentNode=getNode(containingDir),parentData=getNodeData(parentNode)||{};if(meta){if(!parentData||!parentData[getFileName(path)])parentData[getFileName(path)]=0;updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!0)}else if(outgoing)node?parentData[getFileName(path)]=(new Date).getTime():delete parentData[getFileName(path)],parentNode.diff[getFileName(path)]=(new Date).getTime(),updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!0);else{if(node){if(!parentData[getFileName(path)]||parentData[getFileName(path)]<timestamp)parentData[getFileName(path)]=timestamp,delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp)}else parentData[getFileName(path)]&&(delete parentData[getFileName(path)],delete parentNode.diff[getFileName(path)],updateNodeData(containingDir,parentData),updateNode(containingDir,parentNode,!1,!1,timestamp));path.substr(-1)!="/"&&fireChange({path:path,origin:"remote",oldValue:undefined,newValue:node?getNodeData(node):undefined,timestamp:timestamp})}}}function forget(path){localStorage.removeItem(prefixNodes+path)}function forgetAll(){for(var i=0;i<localStorage.length;i++)localStorage.key(i).substr(0,prefixNodes.length)==prefixNodes&&(localStorage.removeItem(localStorage.key(i)),i--)}function on(eventName,cb){if(eventName!="change")throw"Unknown event: "+eventName;onChange.push(cb)}function getState(path){return"disconnected"}function updateNodeData(path,data){if(!path)throw console.trace(),"Path is required!";var encodedData;try{encodedData=JSON.stringify(data)}catch(exc){encodedData=data}localStorage.setItem(prefixNodesData+path,encodedData)}function setNodeData(path,data,outgoing,timestamp,mimeType){var node=getNode(path);mimeType||(mimeType="application/json"),node.mimeType=mimeType,timestamp||(timestamp=(new Date).getTime()),updateNodeData(path,data),updateNode(path,data?node:undefined,outgoing,!1,timestamp)}function getNodeData(path){typeof path=="object"&&(path=path.path);var valueStr=localStorage.getItem(prefixNodesData+path);if(!valueStr)return undefined;try{return JSON.parse(valueStr)}catch(exc){return valueStr}}function setNodeAccess(path,claim){var node=getNode(path);claim!=node.startAccess&&(claim=="rw"||node.startAccess==null)&&(node.startAccess=claim,updateNode(path,node,!1,!0))}function setNodeForce(path,force){var node=getNode(path);node.startForce=force,updateNode(path,node,!1,!0)}function clearDiff(path,i){var node=getNode(path);delete node.diff[i],updateNode(path,node,!1,!0)}var logger=util.getLogger("store"),onChange=[],prefixNodes="remote_storage_nodes:",prefixNodesData="remote_storage_node_data:";return typeof window!="undefined"&&window.addEventListener("storage",function(e){e.key.substring(0,prefixNodes.length==prefixNodes)&&(e.path=e.key.substring(prefixNodes.length),isDir(e.path)||(e.origin="device",fireChange(e)))}),{on:on,getNode:getNode,getNodeData:getNodeData,setNodeData:setNodeData,setNodeAccess:setNodeAccess,setNodeForce:setNodeForce,clearDiff:clearDiff,forget:forget,forgetAll:forgetAll}}),define("lib/sync",["./wireClient","./store","./util"],function(wireClient,store,util){function getState(path){return busy?"busy":"connected"}function setBusy(val){busy=val;for(var i=0;i<stateCbs.length;i++)stateCbs[i](val?"busy":"connected")}function on(eventType,cb){eventType=="state"&&stateCbs.push(cb)}function dirMerge(dirPath,remote,cached,diff,force,access,startOne,finishOne,clearCb){for(var i in remote)(!cached[i]&&!diff[i]||cached[i]<remote[i])&&pullNode(dirPath+i,force,access,startOne,finishOne);for(var i in cached)if(!remote[i]||cached[i]>remote[i])if(i.substr(-1)=="/")pullNode(dirPath+i,force,access,startOne,finishOne);else{var childNode=store.getNode(dirPath+i),childData=store.getNodeData(dirPath+i);startOne(),typeof childData=="object"&&(childData=JSON.stringify(childData)),wireClient.set(dirPath+i,childData,"application/json",function(err){finishOne()})}for(var i in diff)cached[i]?remote[i]===cached[i]&&clearCb(i):remote[i]?(startOne(),wireClient.set(dirPath+i,undefined,undefined,function(err){finishOne()})):clearCb(i)}function pullNode(path,force,access,startOne,finishOne){var thisNode=store.getNode(path),thisData=store.getNodeData(path);!thisData&&path.substr(-1)=="/"&&(thisData={}),logger.debug("pullNode "+path,thisNode);if(thisNode.startAccess=="rw"||!access)access=thisNode.startAccess;thisNode.startForce&&(force=thisNode.startForce);if(access)startOne(),wireClient.get(path,function(err,data){!err&&data&&(path.substr(-1)=="/"?dirMerge(path,data,thisData,thisNode.diff,force,access,startOne,finishOne,function(i){store.clearDiff(path,i)}):store.setNodeData(path,data,!1)),finishOne(err)});else for(var i in thisData)i.substr(-1)=="/"&&pullNode(path+i,force,access,startOne,finishOne)}function fetchNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(err),outstanding--,outstanding==0&&(setBusy(!1),callback(errors||null,store.getNode(path)))}var outstanding=0,errors=[];setBusy(!0),pullNode(path,!1,!0,startOne,finishOne)}function syncNow(path,callback){function startOne(){outstanding++}function finishOne(err){err&&errors.push(path),outstanding--,outstanding==0&&(setBusy(!1),callback&&callback(errors.length>0?errors:null))}if(wireClient.getState()=="anonymous"){callback&&callback(["not connected"]);return}var outstanding=0,errors=[];logger.info("syncNow "+path),setBusy(!0),pullNode(path,!1,!1,startOne,finishOne)}var prefix="_remoteStorage_",busy=!1,stateCbs=[],logger=util.getLogger("sync");return{syncNow:syncNow,fetchNow:fetchNow,getState:getState,on:on}}),define("lib/widget",["./assets","./webfinger","./hardcoded","./wireClient","./sync","./store","./platform"],function(assets,webfinger,hardcoded,wireClient,sync,store,platform){function translate(text){return text}function isRegistering(){return localStorage.getItem("remote_storage_registering")}function setRegistering(value){value===!1?localStorage.removeItem("remote_storage_registering"):localStorage.setItem("remote_storage_registering","true")}function calcWidgetStateOnLoad(){wc=wireClient;if(isRegistering())return"registering";var wireClientState=wireClient.getState();return wireClientState=="connected"?sync.getState():wireClientState}function setWidgetStateOnLoad(){setWidgetState(calcWidgetStateOnLoad())}function setWidgetState(state){widgetState=state,displayWidgetState(state,userAddress)}function getWidgetState(){return widgetState}function displayWidgetState(state,userAddress){var userAddress=localStorage.remote_storage_widget_useraddress,html="<style>"+assets.widgetCss+"</style>"+'<div id="remotestorage-state" class="'+state+'">'+'  <input id="remotestorage-connect-button" class="remotestorage-button" type="submit" value="'+translate("connect")+'"/>'+'  <span id="remotestorage-register-button" class="remotestorage-button">'+translate("get remoteStorage")+"</span>"+'  <img id="remotestorage-cube" src="'+assets.remoteStorageCube+'"/>'+'  <span id="remotestorage-disconnect">Disconnect '+(userAddress?"<strong>"+userAddress+"</strong>":"")+"</span>"+'  <a id="remotestorage-questionmark" href="http://unhosted.org/#remotestorage" target="_blank">?</a>'+'  <span class="infotext" id="remotestorage-infotext">This app allows you to use your own data storage!<br/>Click for more info on the Unhosted movement.</span>'+'  <input id="remotestorage-useraddress" type="text" value="me@local.dev" placeholder="you@remotestorage" autofocus="" />'+'  <a class="infotext" href="http://remotestoragejs.com/" target="_blank" id="remotestorage-devsonly">RemoteStorageJs is still in developer preview!<br/>Click for more info.</a>'+"</div>";platform.setElementHTML(connectElement,html),platform.eltOn("remotestorage-register-button","click",handleRegisterButtonClick),platform.eltOn("remotestorage-connect-button","click",handleConnectButtonClick),platform.eltOn("remotestorage-disconnect","click",handleDisconnectClick),platform.eltOn("remotestorage-cube","click",handleCubeClick),platform.eltOn("remotestorage-useraddress","type",handleWidgetTypeUserAddress)}function handleRegisterButtonClick(){setRegistering();var win=window.open("http://unhosted.org/en/a/register.html","Get your remote storage","resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=820,height=800,top=0,left=0");setWidgetState("registering")}function redirectUriToClientId(loc){if(loc.substring(0,"http://".length)=="http://")loc=loc.substring("http://".length);else{if(loc.substring(0,"https://".length)!="https://")return loc;loc=loc.substring("https://".length)}var hostParts=loc.split("/")[0].split("@");return hostParts.length>2?loc:(hostParts.length==2&&hostParts.shift(),hostParts[0])}function dance(endpoint){var endPointParts=endpoint.split("?"),queryParams=[];endPointParts.length==2?queryParams=endPointParts[1].split("&"):endPointParts.length>2&&errorHandler("more than one questionmark in auth-endpoint - ignoring");var loc=platform.getLocation(),scopesArr=[];for(var i in scopesObj)scopesArr.push(i+":"+scopesObj[i]);queryParams.push("response_type=token"),queryParams.push("scope="+encodeURIComponent(scopesArr.join(" "))),queryParams.push("redirect_uri="+encodeURIComponent(loc)),queryParams.push("client_id="+encodeURIComponent(redirectUriToClientId(loc))),platform.setLocation(endPointParts[0]+"?"+queryParams.join("&"))}function discoverStorageInfo(userAddress,cb){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?hardcoded.guessStorageInfo(userAddress,{timeout:3e3},function(err2,data2){err2?cb(err2):data2.type&&data2.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data2.type,data2.href),cb(null,data2.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from webfinger")}):data.type&&data.href&&data.properties&&data.properties["auth-endpoint"]?(wireClient.setStorageInfo(data.type,data.href),cb(null,data.properties["auth-endpoint"])):cb("cannot make sense of storageInfo from hardcoded")})}function handleConnectButtonClick(){widgetState=="typing"?(userAddress=platform.getElementValue("remotestorage-useraddress"),localStorage.remote_storage_widget_useraddress=userAddress,setWidgetState("connecting"),discoverStorageInfo(userAddress,function(err,auth){err?(alert("webfinger discovery failed! (sorry this is still a developer preview! developers, point local.dev to 127.0.0.1, then run sudo node server/nodejs-example.js from the repo)"),setWidgetState("failed")):dance(auth)})):setWidgetState("typing")}function handleDisconnectClick(){widgetState=="connected"?(wireClient.disconnectRemote(),store.forgetAll(),setWidgetState("anonymous")):alert("you cannot disconnect now, please wait until the cloud is up to date...")}function handleCubeClick(){sync.syncNow("/",function(errors){})}function handleWidgetTypeUserAddress(){setRegistering(!1),console.log("handleWidgetTypeUserAddress")}function handleWidgetHover(){console.log("handleWidgetHover")}function display(setConnectElement,setLocale){var tokenHarvested=platform.harvestParam("access_token"),storageRootHarvested=platform.harvestParam("storage_root"),storageApiHarvested=platform.harvestParam("storage_api"),authorizeEndpointHarvested=platform.harvestParam("authorize_endpoint");tokenHarvested&&wireClient.setBearerToken(tokenHarvested),storageRootHarvested&&wireClient.setStorageInfo(storageApiHarvested?storageApiHarvested:"2012.04",storageRootHarvested),authorizeEndpointHarvested&&dance(authorizeEndpointHarvested),connectElement=setConnectElement,locale=setLocale,wireClient.on("error",function(err){platform.alert(translate(err))}),sync.on("state",setWidgetState),setWidgetStateOnLoad(),window.onkeydown=function(evt){if(evt.ctrlKey&&evt.which==83)return evt.preventDefault(),console.log("CTRL+S - SYNCING"),sync.syncNow("/",function(errors){}),!1}}function addScope(module,mode){if(!scopesObj[module]||mode=="rw")scopesObj[module]=mode}var locale="en",connectElement,widgetState,userAddress,scopesObj={};return{display:display,addScope:addScope,getState:getWidgetState}}),define("lib/baseClient",["./sync","./store","./util"],function(sync,store,util){function bindContext(callback,context){return context?function(){return callback.apply(context,arguments)}:callback}function extractModuleName(path){if(path&&typeof path=="string"){var parts=path.split("/");if(parts.length>3&&parts[1]=="public")return parts[2];if(parts.length>2)return parts[1]}}function fireChange(moduleName,eventObj){if(moduleName&&moduleChangeHandlers[moduleName])for(var i=0;i<moduleChangeHandlers[moduleName].length;i++)moduleChangeHandlers[moduleName][i](eventObj)}function fireError(str){for(var i=0;i<errorHandlers.length;i++)errorHandlers[i](str)}function set(path,absPath,valueStr){if(isDir(absPath)){fireError("attempt to set a value to a directory "+absPath);return}var node=store.getNode(absPath),changeEvent={origin:"window",oldValue:store.getNodeData(node),newValue:valueStr,path:path},ret=store.setNodeData(absPath,valueStr,!0),moduleName=extractModuleName(absPath);return fireChange(moduleName,changeEvent),fireChange("root",changeEvent),ret}function claimAccess(path,claim){store.setNodeAccess(path,claim)}function isDir(path){return typeof path!="string"&&doSomething(),path.substr(-1)=="/"}var moduleChangeHandlers={},errorHandlers=[],logger=util.getLogger("baseClient");return store.on("change",function(e){var moduleName=extractModuleName(e.path);fireChange(moduleName,e),fireChange("root",e)}),{claimAccess:claimAccess,getInstance:function(moduleName,isPublic){function makePath(path){return moduleName=="root"?path:(isPublic?"/public/":"/")+moduleName+"/"+path}function nodeGivesAccess(path,mode){var node=store.getNode(path);logger.debug("check node access",path,mode,node);var access=(new RegExp(mode)).test(node.startAccess);if(access)return!0;if(path.length>0)return nodeGivesAccess(path.replace(/[^\/]+\/?$/,""))}function ensureAccess(mode){var path=makePath(moduleName=="root"?"/":"");if(!nodeGivesAccess(path,mode))throw"Not sufficient access claimed for node at "+path}return{on:function(eventType,cb,context){eventType=="change"?moduleName&&(moduleChangeHandlers[moduleName]||(moduleChangeHandlers[moduleName]=[]),moduleChangeHandlers[moduleName].push(bindContext(cb,context))):eventType=="error"&&errorHandlers.push(bindContext(cb,context))},getObject:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath);return data&&typeof data=="object"&&delete data["@type"],data}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node);data&&typeof data=="object"&&delete data["@type"],bindContext(cb,context)(data)})},getListing:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath),data=store.getNodeData(absPath),arr=[];for(var i in data)arr.push(i);return arr}sync.fetchNow(absPath,function(err,node){var data=store.getNodeData(node),arr=[];for(var i in data)arr.push(i);bindContext(cb,context)(arr)})},getDocument:function(path,cb,context){ensureAccess("r");var absPath=makePath(path);if(!cb){var node=store.getNode(absPath);return{mimeType:node.mimeType,data:store.getNodeData(node)}}sync.fetchNow(absPath,function(err,node){bindContext(cb,context)({mimeType:node.mimeType,data:store.getNodeData(node)})})},remove:function(path,cb,context){ensureAccess("w");var ret=set(path,makePath(path));return this.syncNow(cb,context),ret},storeObject:function(type,path,obj,cb,context){ensureAccess("w");if(typeof obj!="object")throw"storeObject needs to get an object as value!";obj["@type"]="https://remotestoragejs.com/spec/modules/"+moduleName+"/"+type;var ret=set(path,makePath(path),obj,"application/json");return this.sync(path),this.syncNow(cb,context),ret},storeDocument:function(mimeType,path,data,cb,context){ensureAccess("w");var ret=set(path,makePath(path),data,mimeType);return this.syncNow(cb,context),ret},getItemURL:function(path){var base=remoteStorage.getStorageHref();return base?(base.substr(-1)!="/"&&(base+="/"),base+makePath(path)):null},getCurrentWebRoot:function(){return"https://example.com/this/is/an/example/"+(isPublic?"public/":"")+moduleName+"/"},sync:function(path,switchVal){var absPath=makePath(path);store.setNodeForce(absPath,switchVal!=0)},syncNow:function(cb,context){sync.syncNow(makePath(""),cb?bindContext(cb,context):function(errors){errors&&errors.length>0&&(logger.error("Error syncing: ",errors),fireError(errors))})},getState:function(path){}}}}}),define("lib/nodeConnect",["./wireClient","./webfinger"],function(wireClient,webfinger){return{setUserAddress:function(userAddress,callback){webfinger.getStorageInfo(userAddress,{timeout:3e3},function(err,data){err?console.error("Failed to look up storage info for user "+userAddress+": ",err):wireClient.setStorageInfo(data.type,data.href),callback(err)})},setStorageInfo:wireClient.setStorageInfo,setBearerToken:wireClient.setBearerToken}}),define("remoteStorage",["require","./lib/widget","./lib/baseClient","./lib/store","./lib/sync","./lib/wireClient","./lib/nodeConnect","./lib/util"],function(require,widget,baseClient,store,sync,wireClient,nodeConnect,util){function deprecate(oldFn,newFn){logger.error("DEPRECATION: "+oldFn+" is deprecated! Use "+newFn+" instead.")}var claimedModules={},modules={},logger=util.getLogger("base"),remoteStorage={defineModule:function(moduleName,builder){logger.debug("DEFINE MODULE",moduleName);var module=builder(baseClient.getInstance(moduleName,!1),baseClient.getInstance(moduleName,!0));modules[moduleName]=module,this[moduleName]=module.exports,logger.debug("Module defined: "+moduleName,module,this)},getModuleList:function(){return Object.keys(modules)},getClaimedModuleList:function(){return Object.keys(claimedModules)},getModuleInfo:function(moduleName){return modules[moduleName]},claimAccess:function(claimed){if(typeof claimed!="object"||claimed instanceof Array){claimed instanceof Array||(claimed=Array.prototype.slice.call(arguments));var _modules=claimed,mode="rw";claimed={};var lastArg=arguments[arguments.length-1];typeof lastArg=="string"&&lastArg.match(/^rw?$/)&&(mode=lastArg,delete arguments[arguments.length-1]);for(var i in _modules)claimed[_modules[i]]=mode}for(var moduleName in claimed)this.claimModuleAccess(moduleName,claimed[moduleName])},claimModuleAccess:function(moduleName,mode){logger.debug("claimModuleAccess",moduleName,mode);if(!moduleName in modules)throw"Module not defined: "+moduleName;if(moduleName in claimedModules)return;mode||(mode="r"),moduleName=="root"?(moduleName="",widget.addScope("",mode),baseClient.claimAccess("/",mode)):(widget.addScope(moduleName,mode),baseClient.claimAccess("/"+moduleName+"/",mode),baseClient.claimAccess("/public/"+moduleName+"/",mode)),claimedModules[moduleName]=!0},loadModule:function(){deprecate("remoteStorage.loadModule","remoteStorage.claimAccess"),this.claimModuleAccess.apply(this,arguments)},setBearerToken:function(bearerToken,claimedScopes){wireClient.setBearerToken(bearerToken),baseClient.claimScopes(claimedScopes)},disconnectRemote:wireClient.disconnectRemote,flushLocal:store.forgetAll,syncNow:sync.syncNow,displayWidget:widget.display,getWidgetState:widget.getState,setStorageInfo:wireClient.setStorageInfo,getStorageHref:wireClient.getStorageHref,nodeConnect:nodeConnect,util:util};return remoteStorage}),remoteStorage=require("remoteStorage")})()
\ No newline at end of file
index 6e5b11d..35a888c 100644 (file)
@@ -35,7 +35,10 @@ define(['./wireClient', './store', './util'], function(wireClient, store, util)
           var childNode = store.getNode(dirPath+i);
           var childData = store.getNodeData(dirPath + i);
           startOne();
-          wireClient.set(dirPath+i, JSON.stringify(childData), 'application/json', function(err) {
+          if(typeof(childData) === 'object') {
+            childData = JSON.stringify(childData);
+          }
+          wireClient.set(dirPath+i, childData, 'application/json', function(err) {
             finishOne();
           });
         }