Registry.require(["promise","helper","xmlhttprequest","cloud","tools"],function(){var n=Registry.log,b=Registry.get("promise"),A=Registry.get("helper"),y=Registry.get("xmlhttprequest"),I=y.run,B=Registry.get("cloud"),C=Registry.get("tools"),m=0,p={ePASTEBIN:1,eCHROMESYNC:2,eSYNCFS:3,eGDRIVE:4,eDROPBOX:5,eWEBDAV:6},x=[],u=!1,v=null,D=[{method:"HEAD",url:"https://www.google.com",extract:function(a,b){try{var c=y.parseHeaders(b).date;if(c)return new Date(c)}catch(m){}return null}},{method:"GET",url:"https://json-time.appspot.com/time.json",
extract:function(a){try{var b=JSON.parse(a);if(!b.error&&b.datetime)return new Date(b.datetime)}catch(c){}return null}}],f=function(){var a=function(a){var c=a.type,e=a.id,l,f=function(q,a){if(a==m){var b=q.name,r=/.user.js$/;n.debug("si: cloud file changed",b,q);(b.match(/.meta.json$/)||b.match(r))&&x.forEach(function(h){h(b)})}},d={},p;return{init:function(a){l=B[c]({path:"sync",url:a.url,basic_auth:a.basic_auth});return b.Pledge().then(function(){if(!l.credentials&&!a.basic_auth)return l.list()}).then(function(){p||
(p=l.changes.listen(),p.progress(function(a){f(a,e)}));return!0})},list:function(a){return l.list(a).then(function(a){d={};var b={},q={},h,t,w=Date.now();a.forEach(function(g){d[g.name]=g;var a=/.meta.json$/,k=/.user.js$/;if(g.modified>w)n.debug("si: ignore future list item",w,g);else if((h=g.name.match(a))||(t=g.name.match(k)))h?(g.uuid=a=g.name.replace(a,""),g.lastModified=g.modified,g.precision=g.precision,b[a]=g):t&&(a=g.name.replace(k,""),q[a]=g)});return Object.keys(b).map(function(g){var a;
if(a=b[g])return a.source=q[g],a.options=a.options||{},a}).filter(function(a){return a})})},setSource:function(a,k){var c=a+".user.js",r=d[c],h;return b.Pledge(!1).then(function(){if(r&&l.compare)return l.compare(r,k)}).then(function(a){if(a)return n.debug("si: remote source data matches, skip upload of",c),b.Pledge();h=new Blob([k],{type:"text/plain"});return l.put(r||c,h)})},getSource:function(a,k){var c=a+".user.js",r=d[c];if(r)return b.Pledge(!1).then(function(){if(k&&l.compare)return l.compare(r,
k)}).then(function(a){return a?(n.debug("si: remote source data matches, skip download of",c),b.Pledge(k)):l.get(r).then(C.readAsText)});n.warn("si: list cache does not contain this UUID",a);return b.Breach()},getMeta:function(a){var k;return(k=d[a+".meta.json"])?l.get(k).then(C.readAsText).then(function(b){var c;var h=null;try{h=JSON.parse(b)}catch(t){}h&&h.uuid?b=h:(n.debug("si: unable to parse extended info of undefined"),b=null);if((c=b)&&(c.uuid=a))return c.lastModified=k.modified||c.lastModified,
c.precision=k.precision,c.options=c.options||{},c}):b.Breach()},setMeta:function(a,b){var c=new Blob([JSON.stringify(a)],{type:"text/plain"}),e=a.uuid+".meta.json";return l.put(d[e]||e,c,b)},remove:function(a){a.options.removed=Date.now()+v;var b=new Blob([JSON.stringify(a)],{type:"text/plain"});return l.put(a.uuid+".meta.json",b).then(function(){var b;if(b=d[a.uuid+".user.js"])return l.delete(b)})},reset:function(){return l.list(!0).then(function(a){return a=a.filter(function(a){var b=/.user.js$/;
return a.name.match(/.meta.json$/)||a.name.match(b)})}).then(function(a){var c=[];a.forEach(function(a){c.push(function(){var c=b();l.delete(a).always(function(){c.resolve()});return c.promise()}())});return b.when(c).always(function(){d={}})})},getRemoteUrl:function(a){if(l.getRemoteUrl)return l.getRemoteUrl(a.uuid+".user.js")},getRemoteDomains:function(){if(l.getRemoteDomains)return l.getRemoteDomains()}}},d=a({type:"drive",id:p.eGDRIVE}),c=a({type:"dropbox",id:p.eDROPBOX}),a=a({type:"webdav",id:p.eWEBDAV}),
f=function(){var a=!1,c,d=function(a,t){m==p.eCHROMESYNC&&"sync"==t&&b.Pledge().then(function(){if(null===v)return E()}).then(function(){var b=new RegExp(c+"$");a&&Object.keys(a).forEach(function(g){var c=a[g];n.debug('si: storage key "%s" in namespace "%s" changed. Old value was "%s", new value is "%s".',g,t,c.oldValue,c.newValue);if(-1!=g.search(b))for(var d=0;d<x.length;d++)if(!k[g]){var e=z(c.newValue,g);if(e)x[d](g,e)}})})},e=function(a){var c=b(),w=[];a?f().done(function(b){w=A.select(b,function(c){return c.item&&
c.item.uuis==a});c.resolve(w)}).fail(function(a){c.reject(a)}):c.resolve(w);return c.promise()},f=function(){return F(function(){var a=b(),t=new RegExp(c+"$");rea.storage.sync.get(null,function(c){var b=[];c&&Object.keys(c).forEach(function(a){-1!=a.search(t)&&b.push({key:a,item:z(c[a],a)})});a.resolve(b)});return a.promise()})},z=function(a,c){var b=null;try{b=JSON.parse(a)}catch(g){}return b&&(b.url||b.options)?b:(n.debug("si: unable to parse extended info of "+c),null)},u=function(a){return a.then(function(a){var c=
{};a=A.select(a,function(a,b){if(!c[a.key])return c[a.key]=!0});if(1<a.length){var g=b(),h=[],d=a.pop();a.forEach(function(a){h.push(y(a.key))});b.when(h).done(function(){g.resolve(d)});return g.promise()}return b.Pledge(a[0])})},q=null,k={},y=function(a,c){var d=b();rea.storage.sync.remove(a,function(a){(a=rea.runtime.lastError)?d.reject(a):d.resolve()});return d.promise()},r=function(a){var c=b();rea.storage.sync.set(k,function(a){(a=rea.runtime.lastError)?c.reject(a):(k={},c.resolve())});return c.promise()};
return{init:function(){var h=!0;if(!a)try{rea.storage.onChanged.addListener(d),a=!0}catch(e){n.warn("si: error registering sync callback: "+e.message),h=!1}c="@v2";return b.Pledge(h)},list:function(){return b.Pledge().then(function(){if(null===v)return E()}).then(function(){return f()}).then(function(a){var d=new RegExp(c+"$"),e=[];a.forEach(function(a){var c=a.key,b=a.item;a=c.replace(d,"");var h=null;if(h=k[c]?z(k[c],c):b)c=h.options||{},b=!!c.removed,e.push({id:a,uuid:b?a:h.uuid,lastModified:b?
c.removed:h.lastModified,url:h.url,options:c})});return b.Pledge(e)})},setMeta:function(a,d){var f=b();u(e(a.uuid)).done(function(b){var e;b?(e=b.key,b=b.item):(e=a.uuid+c,b={});b.url=a.url;b.options=a.options||{};b.uuid=a.uuid;d.lastModified&&(b.lastModified=d.lastModified);k[e]=JSON.stringify(b);q&&window.clearTimeout(q);q=window.setTimeout(r,3E3);f.resolve()});return f.promise()},remove:function(a){var d=b();u(e(a.uuid)).done(function(b){var e;b?(e=b.key,b=b.item):(e=a.uuid+c,b={});b.options=b.options||
{};b.options.removed=Date.now()+v;k[e]=JSON.stringify(b);q&&window.clearTimeout(q);q=window.setTimeout(r,3E3);d.resolve()});return d.promise()},reset:function(){return F(function(){var a=b();rea.storage.sync.clear(function(){k={};a.resolve()});return a.promise()})}}}(),e={};rea.storage.sync.supported&&(e[p.eCHROMESYNC]=f);e[p.eGDRIVE]=d;e[p.eDROPBOX]=c;e[p.eWEBDAV]=a;return e}(),G=function(){var a=b(),d=0,c=function(){if(d<D.length){var b=D[d];I({method:b.method,url:b.url},{ondone:function(e){4==
e.readyState&&200==e.status?(e=b.extract(e.responseText,e.responseHeaders),null===e?(d++,window.setTimeout(c,1)):a.resolve(e)):(d++,window.setTimeout(c,1))}})}else a.reject(void 0)};c();return a.promise()},E=function(){var a=b();G().done(function(a){v=a.getTime()-Date.now()}).fail(function(){v=0;n.log("si: time offset detection failed!")}).always(a.resolve);return a.promise()},F=function(a,d){var c=b();void 0===d&&(d=3);var f=function(){if(u)window.setTimeout(f,500);else{u=!0;try{a().always(function(){u=
!1}).done(function(){c.resolve.apply(this,arguments)}).fail(function(){0<--d?(n.log("si: some retries left, wait for",6E4,"ms"),window.setTimeout(f,6E4)):(n.warn("si: no retries left, skipping this sync request!"),c.reject("no retries left"))})}catch(b){n.warn(b),u=!1,c.reject(b)}}};f();return c.promise()},H={init:function(a,d){x=[];m=a;return f[m]?f[m].init(d).done(function(a){}):b.Breach()},getUtc:G,debug:function(a){},addChangeListener:function(a){x.push(a)},getRemoteUrl:function(a){if(f[m]&&f[m].getRemoteUrl)return f[m].getRemoteUrl(a)},
getRemoteDomains:function(){if(f[m]&&f[m].getRemoteDomains)return f[m].getRemoteDomains()},caps:function(){var a={};a.__defineGetter__("specialMeta",function(){return f[m]&&!!f[m].getMeta});a.__defineGetter__("syncsSource",function(){return f[m]&&!!f[m].getSource});return a}(),types:p};"list setMeta getMeta setSource getSource reset remove".split(" ").forEach(function(a){H[a]=function(){return f[m]&&f[m][a]?f[m][a].apply(this,arguments):b.Pledge()}});Registry.register("syncinfo","5946",
function(a){B.init(function(d){var c=b(),f=a.openAndWatch({url:d.url},function(a){a?c&&c.notify(a):c&&(c.reject("auth_failed"),c=null)});return{promise:c.promise(),close:function(){f.cancel()}}});return H})});
