Beta 7 with some repo names changed.

This commit is contained in:
Luis Fernando Molina committed 2020-11-15 13:05:19 +01:00
1 parent 0f7b40cca7
commit 963c19493a
3408 files changed
+462217 -15516

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
// This uploads a DApp to the Swarm network *without* using the filesystem.
// That allows a web application running on the browser to upload any DApp.
// This will output a hash that can be accessed on Mist & similar.
const swarm = require("./..").at("http://swarm-gateways.net");
// The contents of index.html.
const indexHtml = new Buffer(
`<html>
<body>
<h3><img src="ethereum_icon.png"/> Swarm.js example DApp!</h3>
<p><a href="foo/test_text_1.txt">Test #1</a></p>
<p><a href="foo/test_text_2.txt">Test #2</a></p>
</body>
</html>`);
// For binary data, we can just use a buffer.
// This is a 16x16 Ethereum icon png.
const ethereumIconPng = new Buffer([
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x08,0x04,0x00,0x00,0x00,0xb5,0xfa,0x37,
0xea,0x00,0x00,0x00,0xf7,0x49,0x44,0x41,0x54,0x28,0x91,0x63,0x60,0x40,0x01,0x0d,
0x09,0x0e,0x8e,0x0c,0xb8,0xc1,0x2c,0xa1,0xce,0x9b,0xc6,0xcf,0xa3,0xf8,0x70,0x2a,
0x98,0x90,0xd7,0xf9,0xdf,0xf0,0xbf,0x55,0x27,0x2e,0xfd,0x62,0x7d,0xff,0x40,0x0a,
0x4c,0xdf,0x3a,0x2a,0x62,0x55,0xd0,0x77,0xac,0xe7,0x3f,0x48,0x81,0xf1,0x7f,0xcb,
0xcd,0x58,0xa4,0x27,0xc6,0xf6,0xfc,0xe9,0xf9,0xdf,0x01,0x56,0x60,0xfc,0xdf,0x25,
0x04,0xdd,0x78,0x9e,0x89,0x97,0xbb,0xfe,0x17,0xff,0x0f,0xf8,0x2f,0xfb,0x5f,0xeb,
0xbf,0xd1,0x7f,0xf3,0xa7,0x81,0x42,0x28,0x0a,0x26,0x95,0x66,0xfd,0x77,0xf9,0x6f,
0xf5,0xdf,0xec,0xbf,0xf0,0x7f,0xd1,0xff,0x12,0xff,0xd5,0xfe,0x5b,0xd4,0xa0,0x28,
0xf0,0x5d,0x61,0xfa,0xd3,0xe2,0xbf,0xc5,0x7f,0x73,0xa0,0x02,0x11,0x10,0xfc,0xa6,
0xba,0x0c,0x45,0xc1,0x7c,0x97,0xdc,0x76,0x8b,0xf5,0x96,0x50,0x05,0x12,0x6b,0x0c,
0x5b,0x7c,0xfc,0x50,0x14,0x4c,0x15,0xea,0x3b,0xd7,0xbb,0xc6,0x2f,0xc4,0xfc,0x93,
0xe8,0x2f,0xdd,0x04,0xcb,0x8d,0xa6,0x0f,0x82,0x84,0xd1,0x9c,0x39,0xc9,0xa3,0xe7,
0x7f,0xff,0xab,0x96,0x74,0xc7,0x68,0xb3,0xe7,0xc6,0xff,0x5d,0x1d,0xb0,0x79,0xb4,
0xbe,0xe7,0x7f,0xf7,0x5f,0x23,0xa0,0x27,0x6d,0x8b,0xb0,0x06,0x14,0x30,0xa8,0xf7,
0x83,0x02,0xca,0x7c,0xaf,0x27,0x17,0x0e,0x05,0xd3,0x54,0x3b,0xdf,0x1a,0x7d,0x73,
0x35,0xc0,0x21,0x0d,0x02,0x4d,0x05,0xb6,0xe1,0xa8,0x22,0x00,0xbf,0x45,0x6f,0x1b,
0x57,0x23,0xc8,0x42,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82]);
// Some test .txt file.
const testText1 = new Buffer("test text #1");
// Other test .txt file.
const testText2 = new Buffer("test text #2");
// The DApp is just an object mapping routes to contents, which can be either
// strings or buffers. Mime types are inferred from the extension. You can also
// force them by using `{"type": "application/json", "content": "[1,2,3]"}`, for
// example. Notice the empty route also pointing to index.html.
const exampleDApp = {
"" : {type: "text/html", data: indexHtml},
"/index.html" : {type: "text/html", data: indexHtml},
"/ethereum_icon.png" : {type: "image/png", data: ethereumIconPng},
"/foo/test_text_1.txt" : {type: "text/plain", data: testText1},
"/foo/test_text_2.txt" : {type: "text/plain", data: testText2}
}
// Now we just upload it.
swarm.upload(exampleDApp)
.then(console.log)
.catch(console.log);
@@ -0,0 +1,29 @@
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,e,f){a!=Array.prototype&&a!=Object.prototype&&(a[e]=f.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.SYMBOL_PREFIX="jscomp_symbol_";
$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.Symbol=function(){var a=0;return function(e){return $jscomp.SYMBOL_PREFIX+(e||"")+a++}}();
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.iterator;a||(a=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&$jscomp.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(a){var e=0;return $jscomp.iteratorPrototype(function(){return e<a.length?{done:!1,value:a[e++]}:{done:!0}})};
$jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[$jscomp.global.Symbol.iterator]=function(){return this};return a};$jscomp.makeIterator=function(a){$jscomp.initSymbolIterator();var e=a[Symbol.iterator];return e?e.call(a):$jscomp.arrayIterator(a)};
$jscomp.polyfill=function(a,e,f,h){if(e){f=$jscomp.global;a=a.split(".");for(h=0;h<a.length-1;h++){var c=a[h];c in f||(f[c]={});f=f[c]}a=a[a.length-1];h=f[a];e=e(h);e!=h&&null!=e&&$jscomp.defineProperty(f,a,{configurable:!0,writable:!0,value:e})}};$jscomp.FORCE_POLYFILL_PROMISE=!1;
$jscomp.polyfill("Promise",function(a){function e(){this.batch_=null}function f(b){return b instanceof c?b:new c(function(a,c){a(b)})}if(a&&!$jscomp.FORCE_POLYFILL_PROMISE)return a;e.prototype.asyncExecute=function(b){null==this.batch_&&(this.batch_=[],this.asyncExecuteBatch_());this.batch_.push(b);return this};e.prototype.asyncExecuteBatch_=function(){var b=this;this.asyncExecuteFunction(function(){b.executeBatch_()})};var h=$jscomp.global.setTimeout;e.prototype.asyncExecuteFunction=function(b){h(b,
0)};e.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var b=this.batch_;this.batch_=[];for(var a=0;a<b.length;++a){var c=b[a];b[a]=null;try{c()}catch(q){this.asyncThrow_(q)}}}this.batch_=null};e.prototype.asyncThrow_=function(b){this.asyncExecuteFunction(function(){throw b;})};var c=function(b){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];var a=this.createResolveAndReject_();try{b(a.resolve,a.reject)}catch(k){a.reject(k)}};c.prototype.createResolveAndReject_=
function(){function b(b){return function(m){c||(c=!0,b.call(a,m))}}var a=this,c=!1;return{resolve:b(this.resolveTo_),reject:b(this.reject_)}};c.prototype.resolveTo_=function(b){if(b===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(b instanceof c)this.settleSameAsPromise_(b);else{a:switch(typeof b){case "object":var a=null!=b;break a;case "function":a=!0;break a;default:a=!1}a?this.resolveToNonPromiseObj_(b):this.fulfill_(b)}};c.prototype.resolveToNonPromiseObj_=function(a){var b=
void 0;try{b=a.then}catch(k){this.reject_(k);return}"function"==typeof b?this.settleSameAsThenable_(b,a):this.fulfill_(a)};c.prototype.reject_=function(a){this.settle_(2,a)};c.prototype.fulfill_=function(a){this.settle_(1,a)};c.prototype.settle_=function(a,c){if(0!=this.state_)throw Error("Cannot settle("+a+", "+c+"): Promise already settled in state"+this.state_);this.state_=a;this.result_=c;this.executeOnSettledCallbacks_()};c.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var a=
0;a<this.onSettledCallbacks_.length;++a)u.asyncExecute(this.onSettledCallbacks_[a]);this.onSettledCallbacks_=null}};var u=new e;c.prototype.settleSameAsPromise_=function(a){var b=this.createResolveAndReject_();a.callWhenSettled_(b.resolve,b.reject)};c.prototype.settleSameAsThenable_=function(a,c){var b=this.createResolveAndReject_();try{a.call(c,b.resolve,b.reject)}catch(q){b.reject(q)}};c.prototype.then=function(a,e){function b(a,b){return"function"==typeof a?function(b){try{h(a(b))}catch(n){f(n)}}:
b}var h,f,m=new c(function(a,b){h=a;f=b});this.callWhenSettled_(b(a,h),b(e,f));return m};c.prototype.catch=function(a){return this.then(void 0,a)};c.prototype.callWhenSettled_=function(a,c){function b(){switch(e.state_){case 1:a(e.result_);break;case 2:c(e.result_);break;default:throw Error("Unexpected state: "+e.state_);}}var e=this;null==this.onSettledCallbacks_?u.asyncExecute(b):this.onSettledCallbacks_.push(b)};c.resolve=f;c.reject=function(a){return new c(function(b,c){c(a)})};c.race=function(a){return new c(function(b,
c){for(var e=$jscomp.makeIterator(a),h=e.next();!h.done;h=e.next())f(h.value).callWhenSettled_(b,c)})};c.all=function(a){var b=$jscomp.makeIterator(a),e=b.next();return e.done?f([]):new c(function(a,c){function h(b){return function(c){m[b]=c;k--;0==k&&a(m)}}var m=[],k=0;do m.push(void 0),k++,f(e.value).callWhenSettled_(h(m.length-1),c),e=b.next();while(!e.done)})};return c},"es6","es3");
$jscomp.iteratorFromArray=function(a,e){$jscomp.initSymbolIterator();a instanceof String&&(a+="");var f=0,h={next:function(){if(f<a.length){var c=f++;return{value:e(c,a[c]),done:!1}}h.next=function(){return{done:!0,value:void 0}};return h.next()}};h[Symbol.iterator]=function(){return h};return h};$jscomp.polyfill("Array.prototype.entries",function(a){return a?a:function(){return $jscomp.iteratorFromArray(this,function(a,f){return[a,f]})}},"es6","es3");
$jscomp.polyfill("Array.prototype.keys",function(a){return a?a:function(){return $jscomp.iteratorFromArray(this,function(a){return a})}},"es6","es3");
(function(){function a(e,f,h){function c(b,k){if(!f[b]){if(!e[b]){var m="function"==typeof require&&require;if(!k&&m)return m(b,!0);if(u)return u(b,!0);k=Error("Cannot find module '"+b+"'");throw k.code="MODULE_NOT_FOUND",k;}k=f[b]={exports:{}};e[b][0].call(k.exports,function(a){return c(e[b][1][a]||a)},k,k.exports,a,e,f,h)}return f[b].exports}for(var u="function"==typeof require&&require,b=0;b<h.length;b++)c(h[b]);return c}return a})()({1:[function(a,e,f){e.exports=function(a){var c=a.fsp,e=a.files,
b=a.os,f=a.path,h=a.child_process,q=a.mimetype,T=a.defaultArchives,A=a.request,U=a.downloadUrl,w=a.bytes,L=a.hash,n=a.pick,V=function(a){return function(d){return function(g){return g[a]=d,g}}},B=function(a){return function(d){for(var g={},b=0,c=a.length;b<c;++b)g[a[b]]=d[b];return g}},X=function(a){return function(d){var g={},b;for(b in a)g[b]=a[b];for(var c in d)g[c]=d[c];return g}},Y=function(a){return function(d){if(a.length!==d.length)return!1;for(var b=0;b<a;++b)if(a[b]!==d[b])return!1;return!0}},
M=function(a){return function(d){return a+"/bzz-raw:/"+d}},r=function(a){return function(d){return A(M(a)(d),{responseType:"arraybuffer"}).then(function(a){a=new Uint8Array(a);if(Y(a)([52,48,52,32,112,97,103,101,32,110,111,116,32,102,111,117,110,100,10]))throw"Error 404.";return a})}},y=function(a){return function(d){return function W(d){return function(b){return function(g){var c=function(a){return void 0===a.path?Promise.resolve():"application/bzz-manifest+json"===a.contentType?W(a.hash)(b+a.path)(g):
Promise.resolve(V(b+a.path)({type:a.contentType,hash:a.hash})(g))};return r(a)(d).then(function(a){return JSON.parse(x(a)).entries}).then(function(a){return Promise.all(a.map(c))}).then(function(){return g})}}}(d)("")({})}},C=function(a){return function(d){return y(a)(d).then(function(a){return B(Object.keys(a))(Object.keys(a).map(function(d){return a[d].hash}))})}},D=function(a){return function(d){return y(a)(d).then(function(d){var b=Object.keys(d),g=b.map(function(a){return d[a].hash}),c=b.map(function(a){return d[a].type});
g=g.map(r(a));var e=function(a){return a.map(function(a,d){return{type:c[d],data:a}})};return Promise.all(g).then(function(a){return B(b)(e(a))})})}},z=function(a){return function(d){return function(b){return e.download(M(a)(d))(b)}}},E=function(a){return function(d){return function(b){return C(a)(d).then(function(d){var g=[],c;for(c in d)if(0<c.length){var e=f.join(b,c);g.push(z(a)(d[c])(e))}return Promise.all(g).then(function(){return b})})}}},p=function(a){return function(d){return A(a+"/bzz-raw:/",
{body:"string"===typeof d?F(d):d,method:"POST"})}},G=function(a){return function(d){return function(b){return function(g){return function Z(c){return A(a+"/bzz:/"+d+("/"===b[0]?b:"/"+b),{method:"PUT",headers:{"Content-Type":g.type},body:g.data}).then(function(a){if(-1!==a.indexOf("error"))throw a;return a}).catch(function(a){return 0<c&&Z(c-1)})}(3)}}}},v=function(a){return function(d){return t(a)({"":d})}},N=function(a){return function(d){return c.readFile(d).then(function(b){return v(a)({type:q.lookup(d),
data:b})})}},t=function(a){return function(d){return p(a)("{}").then(function(b){var c=function(b){return function(c){return G(a)(c)(b)(d[b])}};return Object.keys(d).reduce(function(a,d){return a.then(c(d))},Promise.resolve(b))})}},H=function(a){return function(d){return c.readFile(d).then(p(a))}},I=function(a){return function(d){return function(b){return e.directoryTree(b).then(function(a){return Promise.all(a.map(function(a){return c.readFile(a)})).then(function(d){var c=a.map(function(a){return a.slice(b.length)}),
g=a.map(function(a){return q.lookup(a)||"text/plain"});return B(c)(d.map(function(a,d){return{type:g[d],data:a}}))})}).then(function(a){return X(d?{"":a[d]}:{})(a)}).then(t(a))}}},O=function(a){return function(d){if("data"===d.pick)return n.data().then(p(a));if("file"===d.pick)return n.file().then(v(a));if("directory"===d.pick)return n.directory().then(t(a));if(d.path)switch(d.kind){case "data":return H(a)(d.path);case "file":return N(a)(d.path);case "directory":return I(a)(d.defaultFile)(d.path)}else{if(d.length||
"string"===typeof d)return p(a)(d);if(d instanceof Object)return t(a)(d)}return Promise.reject(Error("Bad arguments"))}},P=function(a){return function(d){return function(b){return aa(a)(d).then(function(c){return c?b?E(a)(d)(b):D(a)(d):b?z(a)(d)(b):r(a)(d)})}}},Q=function(a,c){var d=b.platform().replace("win32","windows")+"-"+("x64"===b.arch()?"amd64":"386");c=(c||T)[d];d=c.archiveMD5;var g=c.binaryMD5;return e.safeDownloadArchived(U+c.archive+".tar.gz")(d)(g)(a)},R=function(a){return new Promise(function(d,
b){var c=h.spawn,e=function(a){return function(d){return-1!==(""+d).indexOf(a)}},g=a.password,f=a.privateKey,k=0,l=c(a.binPath,["--bzzaccount",a.account||f,"--datadir",a.dataDir,"--ens-api",a.ensApi]);c=function(a){0===k&&e("Passphrase")(a)?setTimeout(function(){k=1;l.stdin.write(g+"\n")},500):e("Swarm http proxy started")(a)&&(k=2,clearTimeout(m),d(l))};l.stdout.on("data",c);l.stderr.on("data",c);var m=setTimeout(function(){return b(Error("Couldn't start swarm process."))},2E4)})},S=function(a){return new Promise(function(d,
b){a.stderr.removeAllListeners("data");a.stdout.removeAllListeners("data");a.stdin.removeAllListeners("error");a.removeAllListeners("error");a.removeAllListeners("exit");a.kill("SIGINT");var c=setTimeout(function(){return a.kill("SIGKILL")},8E3);a.once("close",function(){clearTimeout(c);d()})})},J=function(a){return p(a)("test").then(function(a){return"c9a99c7d326dcc6316f32fe2625b311f6dc49a175e6877681ded93137d3569e7"===a}).catch(function(){return!1})},aa=function(a){return function(b){return r(a)(b).then(function(a){try{return!!JSON.parse(x(a)).entries}catch(ba){return!1}})}},
l=function(a){return function(b,d,c,e,f){var g;"undefined"!==typeof b&&(g=a(b));"undefined"!==typeof d&&(g=a(d));"undefined"!==typeof c&&(g=a(c));"undefined"!==typeof e&&(g=a(e));"undefined"!==typeof f&&(g=a(f));return g}},x=function(a){return w.toString(w.fromUint8Array(a))},F=function(a){return w.toUint8Array(w.fromString(a))},K=function(a){return{download:function(b,c){return P(a)(b)(c)},downloadData:l(r(a)),downloadDataToDisk:l(z(a)),downloadDirectory:l(D(a)),downloadDirectoryToDisk:l(E(a)),downloadEntries:l(y(a)),
downloadRoutes:l(C(a)),isAvailable:function(){return J(a)},upload:function(b){return O(a)(b)},uploadData:l(p(a)),uploadFile:l(v(a)),uploadFileFromDisk:l(v(a)),uploadDataFromDisk:l(H(a)),uploadDirectory:l(t(a)),uploadDirectoryFromDisk:l(I(a)),uploadToManifest:l(G(a)),pick:n,hash:L,fromString:F,toString:x}};return{at:K,local:function(a){return function(b){return J("http://localhost:8500").then(function(c){return c?b(K("http://localhost:8500")).then(function(){}):Q(a.binPath,a.archives).onData(function(b){return(a.onProgress||
function(){})(b.length)}).then(function(){return R(a)}).then(function(a){return b(K("http://localhost:8500")).then(function(){return a})}).then(S)})}},download:P,downloadBinary:Q,downloadData:r,downloadDataToDisk:z,downloadDirectory:D,downloadDirectoryToDisk:E,downloadEntries:y,downloadRoutes:C,isAvailable:J,startProcess:R,stopProcess:S,upload:O,uploadData:p,uploadDataFromDisk:H,uploadFile:v,uploadFileFromDisk:N,uploadDirectory:t,uploadDirectoryFromDisk:I,uploadToManifest:G,pick:n,hash:L,fromString:F,
toString:x}}},{}]},{},[1]);
+36
View File
@@ -0,0 +1,36 @@
// THIS IS OUTDATED
// TODO: update it
const Swarm = require("./..");
const fs = require("fs");
const path = require("path");
const privateKeyPath = path.join(process.cwd(), "swarmPrivateKey");
// Writes a temporary private key file to disk
fs.writeFileSync(privateKeyPath, "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
// To run Swarm locally, you need a running Geth
// node and an Ethereum account/password
const swarmSetup = {
privateKey: privateKeyPath,
dataDir: process.env.HOME + "/Library/Ethereum/testnet",
ensApi: process.env.HOME + "/Library/Ethereum/testnet/geth.ipc",
binPath: process.env.HOME + "/.swarm/swarm"
};
// Magically starts a local Swarm node
// Downloads binaries if necessary
Swarm.local(swarmSetup)(swarm => new Promise((resolve, reject) => {
// Removes the temporary private key file
fs.unlinkSync(privateKeyPath);
// Uploads data using the local node
swarm.upload("test").then(hash => {
console.log("Uploaded data. Address:", hash);
// Closes the Swarm process.
resolve();
}).catch(e => console.log(e));
}))
.then(() => console.log("Done!"))
.catch(e => console.log(e));
+31
View File
@@ -0,0 +1,31 @@
const swarm = require("./..").at("http://swarm-gateways.net");
(async () => {
try {
// Uploading raw data
const file = "this is a test";
const fileHash = await swarm.upload(new Buffer(file))
console.log("Uploaded file. SwarmHash:", fileHash);
//// Downloading raw data
const fileBuffer = await swarm.download(fileHash);
console.log("Downloaded file. Contents:", swarm.toString(fileBuffer));
// Uploading directory
const dir = {
"/foo.txt": {type: "text/plain", data: "this is foo.txt"},
"/bar.txt": {type: "text/plain", data: "this is bar.txt"}
};
const dirHash = await swarm.upload(dir);
console.log("Uploaded directory. SwarmHash:", dirHash);
//// Downloaading a directory
const dirObj = await swarm.download(dirHash);
console.log("Downloaded directory. Contents:");
for (let path in dirObj)
console.log("-", path, ":", swarm.toString(dirObj[path].data));
} catch (e) {
console.log(e);
}
})();
+75
View File
@@ -0,0 +1,75 @@
let swarm = Swarm.at("http://swarm-gateways.net");
// Uploads a file or directory to the Swarm network
const upload = dir => {
swarm.upload(dir).then(print).catch(console.log);
};
// Downloads from Swarm and inserts on site
const download = () => {
const hash = prompt("Hash:");
if (hash) swarm.download(hash).then(print).catch(console.log);
};
// Sets the Swarm provider / gateway
const setProvider = e => {
swarm = Swarm.at(document.getElementById("provider").value);
};
// Pretty printers
const print = val => {
let p = document.createElement("p");
let o = document.getElementById("output");
p.appendChild(toHTML(val));
o.insertBefore(p, o.firstChild);
};
// Interprets data as text/png/jpg/raw/directory, builds an HTML
const toHTML = val => {
// Directory
if (val instanceof Object && !val.length) {
let table = document.createElement("table");
for (var key in val) {
let row = document.createElement("tr");
let cell0 = document.createElement("td");
let cell1 = document.createElement("td");
cell0.appendChild(toHTML(key));
cell1.appendChild(toHTML(val[key].data));
row.appendChild(cell0);
row.appendChild(cell1);
table.appendChild(row);
}
return table;
// String
} else if (typeof val === "string") {
let span = document.createElement("span");
span.innerHTML = val;
return span;
// Buffer
} else if (val.length) {
// PNG
if (val[1] === 80 && val[2] === 78 && val[3] === 71) {
let image = document.createElement("img");
image.src = "data:image/png;base64," + btoa(String.fromCharCode.apply(null,val));
return image;
// JPG
} else if (val[0] === 0xFF && val[1] === 0xD8 && val[val.length-2] === 0xFF && val[val.length-1] === 0xD9) {
let image = document.createElement("img");
image.src = "data:image/jpg;base64," + btoa(String.fromCharCode.apply(null,val));
return image;
// Plain text / binary data
} else {
let isText = true;
for (let i = 0; i < val.length; ++i)
if (val[i] < 32 || val[i] > 126)
isText = false;
return toHTML(isText
? [].map.call(val, c => String.fromCharCode(c)).join("")
: [].map.call(val, b => ("00"+b.toString(16)).slice(-2)).join(""));
};
};
};
+654
View File
@@ -0,0 +1,654 @@
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// TODO: this is a temporary fix to hide those libraries from the browser. A
// slightly better long-term solution would be to split this file into two,
// separating the functions that are used on Node.js from the functions that
// are used only on the browser.
module.exports = function (_ref) {
var fs = _ref.fs,
files = _ref.files,
os = _ref.os,
path = _ref.path,
child_process = _ref.child_process,
mimetype = _ref.mimetype,
defaultArchives = _ref.defaultArchives,
request = _ref.request,
downloadUrl = _ref.downloadUrl,
bytes = _ref.bytes,
hash = _ref.hash,
pick = _ref.pick;
// ∀ a . String -> JSON -> Map String a -o Map String a
// Inserts a key/val pair in an object impurely.
var impureInsert = function impureInsert(key) {
return function (val) {
return function (map) {
return map[key] = val, map;
};
};
}; // String -> JSON -> Map String JSON
// Merges an array of keys and an array of vals into an object.
var toMap = function toMap(keys) {
return function (vals) {
var map = {};
for (var i = 0, l = keys.length; i < l; ++i) {
map[keys[i]] = vals[i];
}
return map;
};
}; // ∀ a . Map String a -> Map String a -> Map String a
// Merges two maps into one.
var merge = function merge(a) {
return function (b) {
var map = {};
for (var key in a) {
map[key] = a[key];
}
for (var _key in b) {
map[_key] = b[_key];
}
return map;
};
}; // ∀ a . [a] -> [a] -> Bool
var equals = function equals(a) {
return function (b) {
if (a.length !== b.length) {
return false;
} else {
for (var i = 0, l = a.length; i < a; ++i) {
if (a[i] !== b[i]) return false;
}
}
return true;
};
}; // String -> String -> String
var rawUrl = function rawUrl(swarmUrl) {
return function (hash) {
return "".concat(swarmUrl, "/bzzr:/").concat(hash);
};
}; // String -> String -> Promise Uint8Array
// Gets the raw contents of a Swarm hash address.
var downloadData = function downloadData(swarmUrl) {
return function (hash) {
return request(rawUrl(swarmUrl)(hash), {
responseType: "arraybuffer"
}).then(function (arrayBuffer) {
var uint8Array = new Uint8Array(arrayBuffer);
var error404 = [52, 48, 52, 32, 112, 97, 103, 101, 32, 110, 111, 116, 32, 102, 111, 117, 110, 100, 10];
if (equals(uint8Array)(error404)) throw "Error 404.";
return uint8Array;
});
};
}; // type Entry = {"type": String, "hash": String}
// type File = {"type": String, "data": Uint8Array}
// String -> String -> Promise (Map String Entry)
// Solves the manifest of a Swarm address recursively.
// Returns a map from full paths to entries.
var downloadEntries = function downloadEntries(swarmUrl) {
return function (hash) {
var search = function search(hash) {
return function (path) {
return function (routes) {
// Formats an entry to the Swarm.js type.
var format = function format(entry) {
return {
type: entry.contentType,
hash: entry.hash
};
}; // To download a single entry:
// if type is bzz-manifest, go deeper
// if not, add it to the routing table
var downloadEntry = function downloadEntry(entry) {
if (entry.path === undefined) {
return Promise.resolve();
} else {
return entry.contentType === "application/bzz-manifest+json" ? search(entry.hash)(path + entry.path)(routes) : Promise.resolve(impureInsert(path + entry.path)(format(entry))(routes));
}
}; // Downloads the initial manifest and then each entry.
return downloadData(swarmUrl)(hash).then(function (text) {
return JSON.parse(toString(text)).entries;
}).then(function (entries) {
return Promise.all(entries.map(downloadEntry));
}).then(function () {
return routes;
});
};
};
};
return search(hash)("")({});
};
}; // String -> String -> Promise (Map String String)
// Same as `downloadEntries`, but returns only hashes (no types).
var downloadRoutes = function downloadRoutes(swarmUrl) {
return function (hash) {
return downloadEntries(swarmUrl)(hash).then(function (entries) {
return toMap(Object.keys(entries))(Object.keys(entries).map(function (route) {
return entries[route].hash;
}));
});
};
}; // String -> String -> Promise (Map String File)
// Gets the entire directory tree in a Swarm address.
// Returns a promise mapping paths to file contents.
var downloadDirectory = function downloadDirectory(swarmUrl) {
return function (hash) {
return downloadEntries(swarmUrl)(hash).then(function (entries) {
var paths = Object.keys(entries);
var hashs = paths.map(function (path) {
return entries[path].hash;
});
var types = paths.map(function (path) {
return entries[path].type;
});
var datas = hashs.map(downloadData(swarmUrl));
var files = function files(datas) {
return datas.map(function (data, i) {
return {
type: types[i],
data: data
};
});
};
return Promise.all(datas).then(function (datas) {
return toMap(paths)(files(datas));
});
});
};
}; // String -> String -> String -> Promise String
// Gets the raw contents of a Swarm hash address.
// Returns a promise with the downloaded file path.
var downloadDataToDisk = function downloadDataToDisk(swarmUrl) {
return function (hash) {
return function (filePath) {
return files.download(rawUrl(swarmUrl)(hash))(filePath);
};
};
}; // String -> String -> String -> Promise (Map String String)
// Gets the entire directory tree in a Swarm address.
// Returns a promise mapping paths to file contents.
var downloadDirectoryToDisk = function downloadDirectoryToDisk(swarmUrl) {
return function (hash) {
return function (dirPath) {
return downloadRoutes(swarmUrl)(hash).then(function (routingTable) {
var downloads = [];
for (var route in routingTable) {
if (route.length > 0) {
var filePath = path.join(dirPath, route);
downloads.push(downloadDataToDisk(swarmUrl)(routingTable[route])(filePath));
}
;
}
;
return Promise.all(downloads).then(function () {
return dirPath;
});
});
};
};
}; // String -> Uint8Array -> Promise String
// Uploads raw data to Swarm.
// Returns a promise with the uploaded hash.
var uploadData = function uploadData(swarmUrl) {
return function (data) {
return request("".concat(swarmUrl, "/bzzr:/"), {
body: typeof data === "string" ? fromString(data) : data,
method: "POST"
});
};
}; // String -> String -> String -> File -> Promise String
// Uploads a file to the Swarm manifest at a given hash, under a specific
// route. Returns a promise containing the uploaded hash.
// FIXME: for some reasons Swarm-Gateways is sometimes returning
// error 404 (bad request), so we retry up to 3 times. Why?
var uploadToManifest = function uploadToManifest(swarmUrl) {
return function (hash) {
return function (route) {
return function (file) {
var attempt = function attempt(n) {
var slashRoute = route[0] === "/" ? route : "/" + route;
var url = "".concat(swarmUrl, "/bzz:/").concat(hash).concat(slashRoute);
var opt = {
method: "PUT",
headers: {
"Content-Type": file.type
},
body: file.data
};
return request(url, opt).then(function (response) {
if (response.indexOf("error") !== -1) {
throw response;
}
return response;
}).catch(function (e) {
return n > 0 && attempt(n - 1);
});
};
return attempt(3);
};
};
};
}; // String -> {type: String, data: Uint8Array} -> Promise String
var uploadFile = function uploadFile(swarmUrl) {
return function (file) {
return uploadDirectory(swarmUrl)({
"": file
});
};
}; // String -> String -> Promise String
var uploadFileFromDisk = function uploadFileFromDisk(swarmUrl) {
return function (filePath) {
return fs.readFile(filePath).then(function (data) {
return uploadFile(swarmUrl)({
type: mimetype.lookup(filePath),
data: data
});
});
};
}; // String -> Map String File -> Promise String
// Uploads a directory to Swarm. The directory is
// represented as a map of routes and files.
// A default path is encoded by having a "" route.
var uploadDirectory = function uploadDirectory(swarmUrl) {
return function (directory) {
return uploadData(swarmUrl)("{}").then(function (hash) {
var uploadRoute = function uploadRoute(route) {
return function (hash) {
return uploadToManifest(swarmUrl)(hash)(route)(directory[route]);
};
};
var uploadToHash = function uploadToHash(hash, route) {
return hash.then(uploadRoute(route));
};
return Object.keys(directory).reduce(uploadToHash, Promise.resolve(hash));
});
};
}; // String -> Promise String
var uploadDataFromDisk = function uploadDataFromDisk(swarmUrl) {
return function (filePath) {
return fs.readFile(filePath).then(uploadData(swarmUrl));
};
}; // String -> Nullable String -> String -> Promise String
var uploadDirectoryFromDisk = function uploadDirectoryFromDisk(swarmUrl) {
return function (defaultPath) {
return function (dirPath) {
return files.directoryTree(dirPath).then(function (fullPaths) {
return Promise.all(fullPaths.map(function (path) {
return fs.readFile(path);
})).then(function (datas) {
var paths = fullPaths.map(function (path) {
return path.slice(dirPath.length);
});
var types = fullPaths.map(function (path) {
return mimetype.lookup(path) || "text/plain";
});
return toMap(paths)(datas.map(function (data, i) {
return {
type: types[i],
data: data
};
}));
});
}).then(function (directory) {
return merge(defaultPath ? {
"": directory[defaultPath]
} : {})(directory);
}).then(uploadDirectory(swarmUrl));
};
};
}; // String -> UploadInfo -> Promise String
// Simplified multi-type upload which calls the correct
// one based on the type of the argument given.
var _upload = function upload(swarmUrl) {
return function (arg) {
// Upload raw data from browser
if (arg.pick === "data") {
return pick.data().then(uploadData(swarmUrl)); // Upload a file from browser
} else if (arg.pick === "file") {
return pick.file().then(uploadFile(swarmUrl)); // Upload a directory from browser
} else if (arg.pick === "directory") {
return pick.directory().then(uploadDirectory(swarmUrl)); // Upload directory/file from disk
} else if (arg.path) {
switch (arg.kind) {
case "data":
return uploadDataFromDisk(swarmUrl)(arg.path);
case "file":
return uploadFileFromDisk(swarmUrl)(arg.path);
case "directory":
return uploadDirectoryFromDisk(swarmUrl)(arg.defaultFile)(arg.path);
}
; // Upload UTF-8 string or raw data (buffer)
} else if (arg.length || typeof arg === "string") {
return uploadData(swarmUrl)(arg); // Upload directory with JSON
} else if (arg instanceof Object) {
return uploadDirectory(swarmUrl)(arg);
}
return Promise.reject(new Error("Bad arguments"));
};
}; // String -> String -> Nullable String -> Promise (String | Uint8Array | Map String Uint8Array)
// Simplified multi-type download which calls the correct function based on
// the type of the argument given, and on whether the Swwarm address has a
// directory or a file.
var _download = function download(swarmUrl) {
return function (hash) {
return function (path) {
return isDirectory(swarmUrl)(hash).then(function (isDir) {
if (isDir) {
return path ? downloadDirectoryToDisk(swarmUrl)(hash)(path) : downloadDirectory(swarmUrl)(hash);
} else {
return path ? downloadDataToDisk(swarmUrl)(hash)(path) : downloadData(swarmUrl)(hash);
}
});
};
};
}; // String -> Promise String
// Downloads the Swarm binaries into a path. Returns a promise that only
// resolves when the exact Swarm file is there, and verified to be correct.
// If it was already there to begin with, skips the download.
var downloadBinary = function downloadBinary(path, archives) {
var system = os.platform().replace("win32", "windows") + "-" + (os.arch() === "x64" ? "amd64" : "386");
var archive = (archives || defaultArchives)[system];
var archiveUrl = downloadUrl + archive.archive + ".tar.gz";
var archiveMD5 = archive.archiveMD5;
var binaryMD5 = archive.binaryMD5;
return files.safeDownloadArchived(archiveUrl)(archiveMD5)(binaryMD5)(path);
}; // type SwarmSetup = {
// account : String,
// password : String,
// dataDir : String,
// binPath : String,
// ensApi : String,
// onDownloadProgress : Number ~> (),
// archives : [{
// archive: String,
// binaryMD5: String,
// archiveMD5: String
// }]
// }
// SwarmSetup ~> Promise Process
// Starts the Swarm process.
var startProcess = function startProcess(swarmSetup) {
return new Promise(function (resolve, reject) {
var spawn = child_process.spawn;
var hasString = function hasString(str) {
return function (buffer) {
return ('' + buffer).indexOf(str) !== -1;
};
};
var account = swarmSetup.account,
password = swarmSetup.password,
dataDir = swarmSetup.dataDir,
ensApi = swarmSetup.ensApi,
privateKey = swarmSetup.privateKey;
var STARTUP_TIMEOUT_SECS = 3;
var WAITING_PASSWORD = 0;
var STARTING = 1;
var LISTENING = 2;
var PASSWORD_PROMPT_HOOK = "Passphrase";
var LISTENING_HOOK = "Swarm http proxy started";
var state = WAITING_PASSWORD;
var swarmProcess = spawn(swarmSetup.binPath, ['--bzzaccount', account || privateKey, '--datadir', dataDir, '--ens-api', ensApi]);
var handleProcessOutput = function handleProcessOutput(data) {
if (state === WAITING_PASSWORD && hasString(PASSWORD_PROMPT_HOOK)(data)) {
setTimeout(function () {
state = STARTING;
swarmProcess.stdin.write(password + '\n');
}, 500);
} else if (hasString(LISTENING_HOOK)(data)) {
state = LISTENING;
clearTimeout(timeout);
resolve(swarmProcess);
}
};
swarmProcess.stdout.on('data', handleProcessOutput);
swarmProcess.stderr.on('data', handleProcessOutput); //swarmProcess.on('close', () => setTimeout(restart, 2000));
var restart = function restart() {
return startProcess(swarmSetup).then(resolve).catch(reject);
};
var error = function error() {
return reject(new Error("Couldn't start swarm process."));
};
var timeout = setTimeout(error, 20000);
});
}; // Process ~> Promise ()
// Stops the Swarm process.
var stopProcess = function stopProcess(process) {
return new Promise(function (resolve, reject) {
process.stderr.removeAllListeners('data');
process.stdout.removeAllListeners('data');
process.stdin.removeAllListeners('error');
process.removeAllListeners('error');
process.removeAllListeners('exit');
process.kill('SIGINT');
var killTimeout = setTimeout(function () {
return process.kill('SIGKILL');
}, 8000);
process.once('close', function () {
clearTimeout(killTimeout);
resolve();
});
});
}; // SwarmSetup -> (SwarmAPI -> Promise ()) -> Promise ()
// Receives a Swarm configuration object and a callback function. It then
// checks if a local Swarm node is running. If no local Swarm is found, it
// downloads the Swarm binaries to the dataDir (if not there), checksums,
// starts the Swarm process and calls the callback function with an API
// object using the local node. That callback must return a promise which
// will resolve when it is done using the API, so that this function can
// close the Swarm process properly. Returns a promise that resolves when the
// user is done with the API and the Swarm process is closed.
// TODO: check if Swarm process is already running (improve `isAvailable`)
var local = function local(swarmSetup) {
return function (useAPI) {
return _isAvailable("http://localhost:8500").then(function (isAvailable) {
return isAvailable ? useAPI(at("http://localhost:8500")).then(function () {}) : downloadBinary(swarmSetup.binPath, swarmSetup.archives).onData(function (data) {
return (swarmSetup.onProgress || function () {})(data.length);
}).then(function () {
return startProcess(swarmSetup);
}).then(function (process) {
return useAPI(at("http://localhost:8500")).then(function () {
return process;
});
}).then(stopProcess);
});
};
}; // String ~> Promise Bool
// Returns true if Swarm is available on `url`.
// Perfoms a test upload to determine that.
// TODO: improve this?
var _isAvailable = function isAvailable(swarmUrl) {
var testFile = "test";
var testHash = "c9a99c7d326dcc6316f32fe2625b311f6dc49a175e6877681ded93137d3569e7";
return uploadData(swarmUrl)(testFile).then(function (hash) {
return hash === testHash;
}).catch(function () {
return false;
});
}; // String -> String ~> Promise Bool
// Returns a Promise which is true if that Swarm address is a directory.
// Determines that by checking that it (i) is a JSON, (ii) has a .entries.
// TODO: improve this?
var isDirectory = function isDirectory(swarmUrl) {
return function (hash) {
return downloadData(swarmUrl)(hash).then(function (data) {
try {
return !!JSON.parse(toString(data)).entries;
} catch (e) {
return false;
}
});
};
}; // Uncurries a function; used to allow the f(x,y,z) style on exports.
var uncurry = function uncurry(f) {
return function (a, b, c, d, e) {
var p; // Hardcoded because efficiency (`arguments` is very slow).
if (typeof a !== "undefined") p = f(a);
if (typeof b !== "undefined") p = f(b);
if (typeof c !== "undefined") p = f(c);
if (typeof d !== "undefined") p = f(d);
if (typeof e !== "undefined") p = f(e);
return p;
};
}; // () -> Promise Bool
// Not sure how to mock Swarm to test it properly. Ideas?
var test = function test() {
return Promise.resolve(true);
}; // Uint8Array -> String
var toString = function toString(uint8Array) {
return bytes.toString(bytes.fromUint8Array(uint8Array));
}; // String -> Uint8Array
var fromString = function fromString(string) {
return bytes.toUint8Array(bytes.fromString(string));
}; // String -> SwarmAPI
// Fixes the `swarmUrl`, returning an API where you don't have to pass it.
var at = function at(swarmUrl) {
return {
download: function download(hash, path) {
return _download(swarmUrl)(hash)(path);
},
downloadData: uncurry(downloadData(swarmUrl)),
downloadDataToDisk: uncurry(downloadDataToDisk(swarmUrl)),
downloadDirectory: uncurry(downloadDirectory(swarmUrl)),
downloadDirectoryToDisk: uncurry(downloadDirectoryToDisk(swarmUrl)),
downloadEntries: uncurry(downloadEntries(swarmUrl)),
downloadRoutes: uncurry(downloadRoutes(swarmUrl)),
isAvailable: function isAvailable() {
return _isAvailable(swarmUrl);
},
upload: function upload(arg) {
return _upload(swarmUrl)(arg);
},
uploadData: uncurry(uploadData(swarmUrl)),
uploadFile: uncurry(uploadFile(swarmUrl)),
uploadFileFromDisk: uncurry(uploadFile(swarmUrl)),
uploadDataFromDisk: uncurry(uploadDataFromDisk(swarmUrl)),
uploadDirectory: uncurry(uploadDirectory(swarmUrl)),
uploadDirectoryFromDisk: uncurry(uploadDirectoryFromDisk(swarmUrl)),
uploadToManifest: uncurry(uploadToManifest(swarmUrl)),
pick: pick,
hash: hash,
fromString: fromString,
toString: toString
};
};
return {
at: at,
local: local,
download: _download,
downloadBinary: downloadBinary,
downloadData: downloadData,
downloadDataToDisk: downloadDataToDisk,
downloadDirectory: downloadDirectory,
downloadDirectoryToDisk: downloadDirectoryToDisk,
downloadEntries: downloadEntries,
downloadRoutes: downloadRoutes,
isAvailable: _isAvailable,
startProcess: startProcess,
stopProcess: stopProcess,
upload: _upload,
uploadData: uploadData,
uploadDataFromDisk: uploadDataFromDisk,
uploadFile: uploadFile,
uploadFileFromDisk: uploadFileFromDisk,
uploadDirectory: uploadDirectory,
uploadDirectoryFromDisk: uploadDirectoryFromDisk,
uploadToManifest: uploadToManifest,
pick: pick,
hash: hash,
fromString: fromString,
toString: toString
};
};
},{}]},{},[1])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvc3dhcm0uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV Line truncated