Browse Source

Testing deploy

Signed-off-by: moxiegirl <mary@blockstack.com>
feat/clarity-updates
moxiegirl 7 years ago
parent
commit
fd3de4dfe0
  1. 357
      _site/2017/05/25/post63.html
  2. 264
      _site/404.html
  3. 351
      _site/README.md
  4. BIN
      _site/android/images/app-flow.png
  5. BIN
      _site/android/images/blockstack-install.png
  6. BIN
      _site/android/images/blockstack-signin.png
  7. BIN
      _site/android/images/chrome-prompt.png
  8. BIN
      _site/android/images/configure-activity.png
  9. BIN
      _site/android/images/create-restore.png
  10. BIN
      _site/android/images/final-app.png
  11. BIN
      _site/android/images/hello-andriod-1.png
  12. BIN
      _site/android/images/initial-build.png
  13. BIN
      _site/android/images/new-interface.png
  14. BIN
      _site/android/images/oreo-api.png
  15. BIN
      _site/android/images/running-app.png
  16. BIN
      _site/android/images/select-hdw.png
  17. BIN
      _site/android/images/studio-download.png
  18. BIN
      _site/android/images/sync-project.png
  19. BIN
      _site/android/images/sync-success.png
  20. 1232
      _site/android/tutorial.html
  21. 1
      _site/assets/css/main.css
  22. BIN
      _site/assets/img/favicon.png
  23. 13
      _site/assets/img/location.svg
  24. BIN
      _site/assets/img/touch-icon.png
  25. 1
      _site/assets/js/custom.js
  26. 8772
      _site/assets/js/main.js
  27. BIN
      _site/assets/posts/7C04AAA0EE9E3886.png
  28. 1
      _site/assets/posts/SVG/logo.svg
  29. 51
      _site/assets/posts/books.svg
  30. 100
      _site/assets/posts/box.svg
  31. 188
      _site/assets/posts/city.svg
  32. 47
      _site/assets/posts/imac.svg
  33. BIN
      _site/assets/posts/image1.png
  34. BIN
      _site/assets/posts/logo.png
  35. 8
      _site/assets/posts/logo.svg
  36. 5
      _site/assets/posts/old.logo.svg
  37. 41
      _site/assets/posts/safe.svg
  38. 113
      _site/assets/posts/sky.svg
  39. BIN
      _site/assets/posts/slideshow-1/image1.png
  40. 26
      _site/assets/posts/teacup.svg
  41. BIN
      _site/assets/posts/touch-icon.png
  42. 1
      _site/assets/posts/touch-icon.svg
  43. 350
      _site/changelog/index.html
  44. 17
      _site/collections.json
  45. 344
      _site/contact/index.html
  46. 36
      _site/core/README.md
  47. 4
      _site/core/advanced_usage.md
  48. 36
      _site/core/aglio_templates/core.jade
  49. 357
      _site/core/aglio_templates/mixins.jade
  50. 53
      _site/core/aglio_templates/public.jade
  51. 223
      _site/core/aglio_templates/scripts.js
  52. 3061
      _site/core/api-specs.md
  53. 414
      _site/core/atlas_network.md
  54. 4
      _site/core/attic/README.md
  55. 124
      _site/core/attic/advanced_usage.md
  56. BIN
      _site/core/attic/figures/gaia-authentication.png
  57. BIN
      _site/core/attic/figures/gaia-connect.png
  58. BIN
      _site/core/attic/figures/gaia-getfile.png
  59. BIN
      _site/core/attic/figures/gaia-listdir.png
  60. BIN
      _site/core/attic/figures/gaia-putfile.png
  61. 461
      _site/core/attic/gaia.md
  62. 324
      _site/core/basic_usage.md
  63. 1342
      _site/core/blockstack_naming_service.md
  64. 530
      _site/core/cli.md
  65. 385
      _site/core/faq_technical.md
  66. BIN
      _site/core/figures/test-screen.png
  67. 3
      _site/core/gaia.md
  68. 148
      _site/core/glossary.md
  69. 80
      _site/core/install-api.md
  70. 3
      _site/core/interactive_regtest_macos.md
  71. 42
      _site/core/memcached.md
  72. 589
      _site/core/namespace_creation.md
  73. 64
      _site/core/openbazaar.md
  74. 33
      _site/core/resolver.md
  75. 184
      _site/core/search.md
  76. 114
      _site/core/setup_core_portal.md
  77. 303
      _site/core/subdomains.md
  78. 492
      _site/core/wire-format.md
  79. 49
      _site/feed.xml
  80. 50
      _site/get-content.sh
  81. 423
      _site/index.html
  82. 6
      _site/netlify.toml
  83. 294
      _site/news/index.html
  84. 41
      _site/package.json
  85. 2
      _site/robots.txt
  86. 3
      _site/search.json
  87. 270
      _site/thanks/index.html

357
_site/2017/05/25/post63.html

@ -0,0 +1,357 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Site tags | Blockstack</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="Site tags" />
<meta name="author" content="John Black" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Site tags" />
<meta property="og:description" content="Site tags" />
<link rel="canonical" href="http://localhost:4000/2017/05/25/post63.html" />
<meta property="og:url" content="http://localhost:4000/2017/05/25/post63.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2017-05-25T00:00:00-07:00" />
<script type="application/ld+json">
{"description":"Site tags","author":{"@type":"Person","name":"John Black"},"@type":"BlogPosting","url":"http://localhost:4000/2017/05/25/post63.html","headline":"Site tags","dateModified":"2017-05-25T00:00:00-07:00","datePublished":"2017-05-25T00:00:00-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/2017/05/25/post63.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container uk-container-xsmall">
<article class="uk-article">
<h1 class="uk-article-title">Site tags</h1>
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
<time datetime="2017-05-25T00:00:00-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/moxiegirl/docs-new/blob/master/_posts/2017-05-25-post63.md" class="btn btn-default githubEditButton" role="button"><span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> May 25, 2017
</time>
</div>
<div class="uk-article-content">
<p>http://localhost:4000/assets/posts/</p>
<p>/2017/05/25/post63.html</p>
<p>Musce libero nunc, dignissim quis turpis quis, semper vehicula dolor. Suspendisse tincidunt consequat quam, ac posuere leo dapibus id. Cras fringilla convallis elit, at eleifend mi interam.</p>
<p>Nulla non sollicitudin. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla. Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit.</p>
<h2 id="image-lightbox-example">Image Lightbox Example</h2>
<p>Nunc porta malesuada porta. Etiam tristique vestibulum dolor at ultricies. Proin hendrerit sapien sed erat fermentum, at commodo velit consectetur.</p>
<figure data-uk-lightbox="animation: slide">
<!-- <a class="uk-inline" href="http://localhost:4000/assets/posts/image1.png" caption="Image in lightbox"> -->
<a class="uk-inline" href="/assets/posts/image1.png" caption="Image in lightbox">
<!-- <img src="http://localhost:4000/assets/posts/image1.png" alt="Alt for image"> -->
<img src="/assets/posts/image1.png" alt="Alt for image" />
<div class="uk-position-center">
<span data-uk-overlay-icon=""></span>
</div>
</a>
<figcaption data-uk-grid="" class="uk-flex-right"><span class="uk-width-auto">Image in lightbox</span></figcaption>
</figure>
<p>Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna, et dapibus turpis.</p>
<h2 id="example-of-code-block">Example Of Code Block</h2>
<p>In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">"X-UA-Compatible"</span> <span class="na">content=</span><span class="s">"IE=edge"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"/assets/css/main.css"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"shortcut icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">href=</span><span class="s">"/assets/img/favicon.png"</span> <span class="nt">&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"/assets/js/main.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
</code></pre>
</div>
<h2 id="text-and-quote">Text and Quote</h2>
<p>Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna turpis.</p>
<blockquote>
<p>Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet</p>
</blockquote>
<p>In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<p>Etiam in fermentum mi. Sed et tempor felis, eu aliquet nisi. Nam eget ullamcorper arcu. Nunc porttitor nisl a dolor blandit, eget consequat sem maximus. Phasellus lacinia quam porta orci malesuada, vel tincidunt.</p>
<div class="share uk-text-center">
<a href="https://twitter.com/intent/tweet?text=Site tags&url=http://localhost:4000/2017/05/25/post63.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Flocalhost%3A4000%2F2017%2F05%2F25%2Fpost63.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
</div>
</div>
<hr class="uk-margin-medium">
<div class="uk-margin-large-top paginate-post">
<div class="uk-child-width-expand@s uk-grid-large uk-pagi" data-uk-grid>
<div>
</div>
<div>
</div>
</div>
</div>
</article>
<script>
// Table of contents scroll to
UIkit.scroll('#markdown-toc a', {
duration: 400,
offset: 120
});
</script>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>

264
_site/404.html

@ -0,0 +1,264 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Feeling Lost | Blockstack</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="Feeling Lost" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Docs" />
<meta property="og:description" content="Docs" />
<link rel="canonical" href="http://localhost:4000/404.html" />
<meta property="og:url" content="http://localhost:4000/404.html" />
<meta property="og:site_name" content="Blockstack" />
<script type="application/ld+json">
{"description":"Docs","author":{"@type":"Person","name":"Blockstack"},"@type":"WebPage","url":"http://localhost:4000/404.html","headline":"Feeling Lost","@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container uk-container-xsmall">
<article class="uk-article">
<h1 class="uk-article-title">Feeling Lost</h1>
<div class="article-content">
<h2 id="the-page-you-are-looking-for-cannot-be-found-please-navigate-to-homepage">The page you are looking for cannot be found. Please navigate to <a href="http://localhost:4000">homepage</a>.</h2>
</div>
</article>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>

351
_site/README.md

@ -0,0 +1,351 @@
# Docs is a premium documentation Jekyll theme
Desk was developed by [Ivan Chromjak](https://ivanchromjak.com) for [jekyll.plus](https://jekyll.plus/), theme [live demo](https://docs.jekyll.plus/) available.
## Features
* Contact form
* Live Search
* Responsive videos
* Image lightbox
* Google maps
* Github avatar
* Changelog page
* Contact form (FormSpree)
* Pre-built pages
* Disqus comments for posts
* Configurable home page header images
* Optimised for [GitHub](https://pages.github.com/) pages
* RSS feed
* SEO tags
* Google Analytics
## Installation
Install the dependencies with [Bundler](http://bundler.io/):
```bash
bundle install
```
Run the following to generate your site:
```bash
bundle exec jekyll serve
```
You can find more on [Deployment Methods](https://jekyllrb.com/docs/deployment-methods/) page on Jekyll website.
## Setup
### Site and author details
Add your site and author details in `_config.yml`:
```yaml
# Site title and description
title: Docs - Documentation Jekyll Theme
description: Documentation Jekyll theme.
# Site base hostname & protocol, e.g. http://example.com
url: "https://docs.jekyll.plus"
# Site logo, image or text
brand:
image: touch-icon.svg # e.g. logo.png, upload logo image file to /assets/img/ folder
text: Docs # if the above "logo:" image variable is not set, this text logo is displayed instead
# Default author settings
author:
name: John Smith
github: PressApps # Github username for avatar
# Author settings, displayed on post and doc pages if front matter references author name e.g. author: peter
authors:
peter:
name: Peter Brown
github: PressApps # Github username for avatar
# Social icons displayed in footer
social:
email:
website:
facebook: https://www.facebook.com/
flickr:
dribbble:
github:
googleplus:
instagram: https://www.instagram.com/
linkedin:
pinterest:
twitter: https://twitter.com/
vimeo: https://vimeo.com/
youtube:
# Twitter share button
twitter_username:
```
### Navigation Bar
Set in the main navigation links in `_data/navigation_header.yml`:
```yaml
- title: About
url: /about/
```
### Footer
Edit copyright notice in `_config.yml`:
```yaml
footer:
copyright:
```
Set in the navigation links in `_data/navigation_footer.yml`:
```yaml
- title: About
url: /about/
```
### Enabling comments (via Disqus)
Optionally, if you have a Disqus account, you can tell Jekyll to use it to show a comments section below each post. To enable it, add the following lines to your Jekyll site:
```yaml
disqus:
shortname: my_disqus_shortname
```
You can find out more about Disqus' shortnames [here](https://help.disqus.com/customer/portal/articles/466208).
Comments are enabled by default and will only appear in production, i.e., `JEKYLL_ENV=production`. If you don't want to display comments for a particular post you can disable them by adding `comments: false` to that post's YAML Front Matter.
### Google Analytics
To enable Google Anaytics, add the following lines to your Jekyll site:
```yaml
google_analytics: UA-NNNNNNNN-N
```
Google Analytics will only appear in production, i.e., `JEKYLL_ENV=production`
### Google Map
To display Google map on contact page, add the following in your page content, replacing latitude, longitude and zoom values:
```yaml
{% include map.html latitude="40.6700" longitude="-73.9400" zoom="16" %}
```
### Contact Form (via FormSpree)
Submit the form and confirm your email address at [FormSpree](https://formspree.io/). Then add the following lines to contact page YAML Front Matter, replacing the email address:
```yaml
formspree:
email: my_name@gmail.com
redirect: /thanks/
```
### Update favicon
You can find the current favicon (favicon.png) inside the theme `/assets/img/` directory, just replace it with your new favicon.
## Posts
To create a new post, you can create a new markdown file inside the `_posts` directory by following the recommended file naming format:
```
YEAR-MONTH-DAY-title.MARKUP
```
Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. For example, the following are examples of valid post filenames:
```
2011-12-31-new-years-eve-is-awesome.md
2012-09-12-how-to-write-a-blog.md
```
Post requires front matter, everything in between the first and second --- are part of the YAML Front Matter, and everything after the second --- will be rendered with Markdown and show up as “Content”.
The following is a post file with different configurations you can add as example:
```yaml
---
layout: post
title: How To Travel On Low Budget
---
```
You can rebuild the site in many different ways, but the most common way is to run `bundle exec jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
To keep things more organized, add post images to `/assets/posts/` directory, and add theme images to `/assets/img/` directory.
### Adding images
To add an image to a post or page use the following codes:
Local image from `/assets/posts/` directory:
```yaml
{% include image.html img="girl.jpg" alt="Alt for image" caption="Girl on a rock" %}
```
External wide image with lightbox:
```yaml
{% include image.html img="https://source.unsplash.com/TT-ROxWj9nA.jpg" lightbox="true" alt="Alt for image" caption="Image in lightbox" %}
```
### Adding table of contents
Add the following code at the top of the post:
```
#### Sections in this article
{:.no_toc}
* TOC
{:toc}
```
`{:.no_toc}` excludes the `#### Sections in this article` title from indexing in table of contents
### Responsive Videos
Embed local videos:
```html
<video controls playsinline uk-video="automute: true">
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type="video/mp4">
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.ogv" type="video/ogg">
</video>
```
Embed YouTube videos:
```html
<iframe src="http://www.youtube.com/embed/YE7VzlLtp-4?autoplay=0&amp;showinfo=0&amp;rel=0&amp;modestbranding=1&amp;playsinline=1" width="600" height="340" frameborder="0" allowfullscreen uk-responsive uk-video="automute: true"></iframe>
```
To create a draft post, create the post file under the `_drafts` directory, and you can find more information in [Working with Drafts](https://jekyllrb.com/docs/drafts/).
## Home Page
To create a home page, just create a `index.md` file inside the root directory. The following is a YAML Front Matter example for a page:
```yaml
---
layout: home
hero:
title: How Can We Help? # hero section settings
subtitle: Search or browse in depth articles and videos on everything Jekyll, from basic theme setup and hosting to customisation and development
image: imac.svg # display small image above title
search: true # enable search
categories:
columns: 3 # number of category columns; 1, 2, 3, 4
title: Browse Topics
subtitle: Get your answers fast, jump to most popular documentation content
featured: # featured docs section settings
title: Popular Articles
tag: featured # tag used to populate featured section on home page
section: # display page content
title: Need More?
subtitle: This section displays optional page content lorem ipsum
cta: # call to action section
title: Didn't find an answer to your question?
subtitle: Get in touch with us for details on additional services and custom work pricing
button_text: Contact Us
button_url: /contact/
---
```
Home page category boxes are added in `_data/navigation_home.yml`, e.g.:
```yml
- title: Getting Started
desc: Get your account up and running in just few easy steps
icon: settings
doc: usage
- title: Account and Billing
desc: Managing your account, creating new users and exporting data
icon: credit-card
doc: drafts
```
All available icons can be found [here](https://getuikit.com/docs/icon#library).
## Docs
To create a document post, just create a new page inside the root directory and add the following code in content:
```
{% include faqs.html %}
```
Create new doc post entries in `_docs` folder, similar to creating posts, but with following front matter settings:
```yml
---
layout: doc
title: Category hosting Setting up new domain and page
subtitle: This is optional doc subtitle
tags: featured development
author: peter
---
```
Sidebar navigation on docs post can edited in `_data/navigation_docs.yml`:
```yml
- title: Getting Started # Section title
docs:
- home # Doc file name from _docs folder
- quickstart
- installation
- windows
```
## Changelog page
Create new page with the following front matter:
```yml
---
layout: changelog
title: Changelog
permalink: /changelog/
---
```
Changelog enties are added in `_data/changelog.yml`:
```yml
- title: Version 0.6.0
label:
date: Aug 15, 2017
list:
- Added style support for radio and checkbox in Firefox
- Removed class from Section component
```
## Customization
To modify the primary color, open `/_sass/theme/variables.scss` and replace the color values e.g.:
```scss
// Main content
$color-main: #0F1214;
```
Further style customisation can be done in the following files:
```
/_sass/theme/mixins.scss
/_sass/theme/variables.scss
/assets/css/main.scss
```
## Development
Install [UIkit](https://getuikit.com/) font end framework dependency via Npm:
```bash
npm install
```
Enable live browser reload with the following:
```bash
bundle exec jekyll s --livereload
```
## Credits and Sources
- Google analytics https://www.google.com/analytics/
- Google maps https://www.google.com/maps
- UIkit front end framework https://getuikit.com/
- Jekyll CML https://jekyllrb.com/
## Support
Customer support is provided through our Envato profile page [contact form](https://themeforest.net/user/pressapps) for up to six months from the purchase date and is provided Monday to Friday during the business week. We aim to answer all support requests daily, most are handled within 48h.

BIN
_site/android/images/app-flow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
_site/android/images/blockstack-install.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
_site/android/images/blockstack-signin.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
_site/android/images/chrome-prompt.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
_site/android/images/configure-activity.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
_site/android/images/create-restore.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
_site/android/images/final-app.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
_site/android/images/hello-andriod-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
_site/android/images/initial-build.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
_site/android/images/new-interface.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
_site/android/images/oreo-api.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
_site/android/images/running-app.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
_site/android/images/select-hdw.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
_site/android/images/studio-download.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
_site/android/images/sync-project.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
_site/android/images/sync-success.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

1232
_site/android/tutorial.html

File diff suppressed because it is too large

1
_site/assets/css/main.css

File diff suppressed because one or more lines are too long

BIN
_site/assets/img/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

13
_site/assets/img/location.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="20px" viewBox="0 0 14 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>location-dark</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="location-dark" stroke="#000000">
<path d="M7,0.5 C3.41,0.5 0.5,3.39 0.5,6.98 C0.5,11.83 7,19 7,19 C7,19 13.5,11.83 13.5,6.98 C13.5,3.39 10.59,0.5 7,0.5 L7,0.5 Z" id="Shape" stroke-width="1.01"></path>
<circle id="Oval" cx="7" cy="6.8" r="2.3"></circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 759 B

BIN
_site/assets/img/touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

1
_site/assets/js/custom.js

@ -0,0 +1 @@
// Custom scripts

8772
_site/assets/js/main.js

File diff suppressed because it is too large

BIN
_site/assets/posts/7C04AAA0EE9E3886.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

1
_site/assets/posts/SVG/logo.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

51
_site/assets/posts/books.svg

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="383px" height="264px" viewBox="0 0 383 264" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Books</title>
<desc>Created with Sketch.</desc>
<defs>
<polygon id="path-1" points="0 263.849 462.318 263.849 462.318 0 0 0"></polygon>
</defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Monochrome-Images" transform="translate(-2631.000000, -2201.000000)">
<g id="Books" transform="translate(2590.000000, 2201.000000)">
<path d="M207.0439,261.625 L144.9799,261.625 C142.5109,261.625 140.5099,259.624 140.5099,257.155 L140.5099,15.188 C140.5099,12.72 142.5109,10.719 144.9799,10.719 L207.0439,10.719 C209.5129,10.719 211.5139,12.72 211.5139,15.188 L211.5139,257.155 C211.5139,259.624 209.5129,261.625 207.0439,261.625 Z" id="Fill-1" fill="#EFEFEF"></path>
<path d="M207.0439,261.625 L144.9799,261.625 C142.5109,261.625 140.5099,259.624 140.5099,257.155 L140.5099,15.188 C140.5099,12.72 142.5109,10.719 144.9799,10.719 L207.0439,10.719 C209.5129,10.719 211.5139,12.72 211.5139,15.188 L211.5139,257.155 C211.5139,259.624 209.5129,261.625 207.0439,261.625 Z" id="Stroke-3" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M211.5137,29.7852 L211.5137,15.1882 C211.5137,12.7202 209.5127,10.7192 207.0437,10.7192 L144.9797,10.7192 C142.5107,10.7192 140.5097,12.7202 140.5097,15.1882 L140.5097,29.7852 L211.5137,29.7852 Z" id="Fill-5" fill="#FFFFFF"></path>
<path d="M211.5137,29.7852 L211.5137,15.1882 C211.5137,12.7202 209.5127,10.7192 207.0437,10.7192 L144.9797,10.7192 C142.5107,10.7192 140.5097,12.7202 140.5097,15.1882 L140.5097,29.7852 L211.5137,29.7852 Z" id="Stroke-7" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-10"></g>
<polygon id="Fill-9" fill="#FFFFFF" mask="url(#mask-2)" points="140.51 65.626 211.514 65.626 211.514 38.746 140.51 38.746"></polygon>
<polygon id="Stroke-11" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="140.51 65.626 211.514 65.626 211.514 38.746 140.51 38.746"></polygon>
<polygon id="Fill-12" fill="#FFFFFF" mask="url(#mask-2)" points="140.51 197.042 211.514 197.042 211.514 74.587 140.51 74.587"></polygon>
<polygon id="Stroke-13" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="140.51 197.042 211.514 197.042 211.514 74.587 140.51 74.587"></polygon>
<polygon id="Fill-14" fill="#FFFFFF" mask="url(#mask-2)" points="140.51 232.386 211.514 232.386 211.514 205.505 140.51 205.505"></polygon>
<polygon id="Stroke-15" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="140.51 232.386 211.514 232.386 211.514 205.505 140.51 205.505"></polygon>
<path d="M140.5098,240.8477 L140.5098,257.1557 C140.5098,259.6237 142.5108,261.6247 144.9798,261.6247 L207.0438,261.6247 C209.5128,261.6247 211.5138,259.6237 211.5138,257.1557 L211.5138,240.8477 L140.5098,240.8477 Z" id="Fill-16" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M140.5098,240.8477 L140.5098,257.1557 C140.5098,259.6237 142.5108,261.6247 144.9798,261.6247 L207.0438,261.6247 C209.5128,261.6247 211.5138,259.6237 211.5138,257.1557 L211.5138,240.8477 L140.5098,240.8477 Z" id="Stroke-17" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M109.9024,261.5693 L47.8384,261.5693 C45.3694,261.5693 43.3684,259.5683 43.3684,257.0993 L43.3684,58.1953 C43.3684,55.7263 45.3694,53.7253 47.8384,53.7253 L109.9024,53.7253 C112.3714,53.7253 114.3724,55.7263 114.3724,58.1953 L114.3724,257.0993 C114.3724,259.5683 112.3714,261.5693 109.9024,261.5693" id="Fill-18" fill="#EFEFEF" mask="url(#mask-2)"></path>
<path d="M109.9024,261.5693 L47.8384,261.5693 C45.3694,261.5693 43.3684,259.5683 43.3684,257.0993 L43.3684,58.1953 C43.3684,55.7263 45.3694,53.7253 47.8384,53.7253 L109.9024,53.7253 C112.3714,53.7253 114.3724,55.7263 114.3724,58.1953 L114.3724,257.0993 C114.3724,259.5683 112.3714,261.5693 109.9024,261.5693 Z" id="Stroke-19" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<polygon id="Fill-20" fill="#FFFFFF" mask="url(#mask-2)" points="43.368 149.255 114.372 149.255 114.372 95.493 43.368 95.493"></polygon>
<polygon id="Stroke-21" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="43.368 149.255 114.372 149.255 114.372 95.493 43.368 95.493"></polygon>
<path d="M136.04,261.8486 L118.842,261.8486 C116.373,261.8486 114.372,259.8476 114.372,257.3786 L114.372,35.6756 C114.372,33.2066 116.373,31.2056 118.842,31.2056 L136.04,31.2056 C138.509,31.2056 140.51,33.2066 140.51,35.6756 L140.51,257.3786 C140.51,259.8476 138.509,261.8486 136.04,261.8486" id="Fill-22" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M136.04,261.8486 L118.842,261.8486 C116.373,261.8486 114.372,259.8476 114.372,257.3786 L114.372,35.6756 C114.372,33.2066 116.373,31.2056 118.842,31.2056 L136.04,31.2056 C138.509,31.2056 140.51,33.2066 140.51,35.6756 L140.51,257.3786 C140.51,259.8476 138.509,261.8486 136.04,261.8486 Z" id="Stroke-23" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M249.7715,261.625 L215.9835,261.625 C213.5145,261.625 211.5135,259.624 211.5135,257.155 L211.5135,57.692 C211.5135,55.224 213.5145,53.223 215.9835,53.223 L249.7715,53.223 C252.2405,53.223 254.2415,55.224 254.2415,57.692 L254.2415,257.155 C254.2415,259.624 252.2405,261.625 249.7715,261.625" id="Fill-24" fill="#EFEFEF" mask="url(#mask-2)"></path>
<path d="M249.7715,261.625 L215.9835,261.625 C213.5145,261.625 211.5135,259.624 211.5135,257.155 L211.5135,57.692 C211.5135,55.224 213.5145,53.223 215.9835,53.223 L249.7715,53.223 C252.2405,53.223 254.2415,55.224 254.2415,57.692 L254.2415,257.155 C254.2415,259.624 252.2405,261.625 249.7715,261.625 Z" id="Stroke-25" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M232.9473,244.2432 L232.8073,244.2432 C229.0103,244.2432 225.9323,241.1652 225.9323,237.3682 L225.9323,77.4792 C225.9323,73.6822 229.0103,70.6042 232.8073,70.6042 L232.9473,70.6042 C236.7443,70.6042 239.8223,73.6822 239.8223,77.4792 L239.8223,237.3682 C239.8223,241.1652 236.7443,244.2432 232.9473,244.2432" id="Fill-26" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M232.9473,244.2432 L232.8073,244.2432 C229.0103,244.2432 225.9323,241.1652 225.9323,237.3682 L225.9323,77.4792 C225.9323,73.6822 229.0103,70.6042 232.8073,70.6042 L232.9473,70.6042 C236.7443,70.6042 239.8223,73.6822 239.8223,77.4792 L239.8223,237.3682 C239.8223,241.1652 236.7443,244.2432 232.9473,244.2432 Z" id="Stroke-27" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M284.1172,261.8486 L258.7212,261.8486 C256.2522,261.8486 254.2502,259.8476 254.2502,257.3786 L254.2502,57.9156 C254.2502,55.4476 256.2522,53.4466 258.7212,53.4466 L284.1172,53.4466 C286.5862,53.4466 288.5872,55.4476 288.5872,57.9156 L288.5872,257.3786 C288.5872,259.8476 286.5862,261.8486 284.1172,261.8486" id="Fill-28" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M284.1172,261.8486 L258.7212,261.8486 C256.2522,261.8486 254.2502,259.8476 254.2502,257.3786 L254.2502,57.9156 C254.2502,55.4476 256.2522,53.4466 258.7212,53.4466 L284.1172,53.4466 C286.5862,53.4466 288.5872,55.4476 288.5872,57.9156 L288.5872,257.3786 C288.5872,259.8476 286.5862,261.8486 284.1172,261.8486 Z" id="Stroke-29" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M418.6475,244.8721 L386.8725,258.9231 C384.6145,259.9211 381.9745,258.9001 380.9755,256.6431 L277.3685,22.3301 C276.3705,20.0721 277.3905,17.4331 279.6485,16.4341 L311.4245,2.3831 C313.6825,1.3851 316.3225,2.4061 317.3205,4.6641 L420.9285,238.9761 C421.9265,241.2341 420.9065,243.8741 418.6475,244.8721" id="Fill-30" fill="#EFEFEF" mask="url(#mask-2)"></path>
<path d="M418.6475,244.8721 L386.8725,258.9231 C384.6145,259.9211 381.9745,258.9001 380.9755,256.6431 L277.3685,22.3301 C276.3705,20.0721 277.3905,17.4331 279.6485,16.4341 L311.4245,2.3831 C313.6825,1.3851 316.3225,2.4061 317.3205,4.6641 L420.9285,238.9761 C421.9265,241.2341 420.9065,243.8741 418.6475,244.8721 Z" id="Stroke-31" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<g id="Group-34" mask="url(#mask-2)">
<g transform="translate(310.000000, 40.849000)">
<path d="M0.1152,0.1207 L72.5902,164.0247" id="Fill-32" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.1152,0.1207 L72.5902,164.0247" id="Stroke-33" stroke="#CECECE" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

100
_site/assets/posts/box.svg

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="429px" height="352px" viewBox="0 0 429 352" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Box</title>
<desc>Created with Sketch.</desc>
<defs>
<polygon id="path-1" points="0 352 429.785 352 429.785 0.774 0 0.774"></polygon>
</defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Monochrome-Images" transform="translate(-3339.000000, -3999.000000)">
<g id="Box" transform="translate(3339.000000, 3998.000000)">
<polygon id="Fill-1" fill="#FFFFFF" points="219.9849 212.6842 327.1979 248.5222 362.4979 142.9152 255.2849 107.0792"></polygon>
<polygon id="Stroke-2" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="219.9849 212.6842 327.1979 248.5222 362.4979 142.9152 255.2849 107.0792"></polygon>
<polygon id="Fill-3" fill="#FFFFFF" points="140.76 267.547 248.886 267.547 248.886 159.421 140.76 159.421"></polygon>
<polygon id="Stroke-4" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="140.76 267.547 248.886 267.547 248.886 159.421 140.76 159.421"></polygon>
<polygon id="Fill-5" fill="#FFFFFF" points="336.608 152.2135 303.381 260.3985 222.209 234.8275 255.436 126.6435"></polygon>
<polygon id="Stroke-6" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="336.608 152.2135 303.381 260.3985 222.209 234.8275 255.436 126.6435"></polygon>
<g id="Group-110" transform="translate(0.000000, 0.226000)">
<path d="M362.5489,65.5929 C369.8429,71.9539 377.4399,80.8479 369.7989,98.4469 C362.8469,114.4589 341.7649,112.0269 341.7649,112.0269 C341.7649,112.0269 345.3319,118.1509 339.3489,125.4719 C333.2989,132.8749 306.4029,123.5709 306.4029,123.5709 L309.8269,108.1719 L280.2859,102.1149 C268.8769,99.7499 259.1809,92.1009 254.5359,81.4149 C251.9089,75.3709 250.5739,67.7709 252.2499,58.4469 C257.9819,26.5539 290.0259,31.1139 290.0259,31.1139 C292.9639,31.6429 295.4829,32.5309 297.6669,33.6559 C298.0739,32.4109 298.7029,31.3219 299.6059,30.4249 C305.4099,24.6549 311.8199,32.2539 311.8199,32.2539 C311.8199,32.2539 309.6419,9.9229 331.2409,3.7249 C331.2409,3.7249 363.7699,-4.3841 372.7079,26.7629 C378.1939,45.8769 369.3109,58.8969 362.5489,65.5929 Z" id="Fill-7" fill="#EFEFEF"></path>
<path d="M362.5489,65.5929 C369.3109,58.8969 378.1939,45.8769 372.7079,26.7629 C363.7699,-4.3841 331.2409,3.7249 331.2409,3.7249 C309.6419,9.9229 311.8199,32.2539 311.8199,32.2539 C311.8199,32.2539 305.4099,24.6549 299.6059,30.4249 C298.7029,31.3219 298.0739,32.4109 297.6669,33.6559 C295.4829,32.5309 292.9639,31.6429 290.0259,31.1139 C290.0259,31.1139 257.9819,26.5539 252.2499,58.4469 C250.5739,67.7709 251.9089,75.3709 254.5359,81.4149 C259.1809,92.1009 268.8769,99.7499 280.2859,102.1149 L309.8269,108.1719 L306.4029,123.5709 C306.4029,123.5709 333.2989,132.8749 339.3489,125.4719 C345.3319,118.1509 341.7649,112.0269 341.7649,112.0269 C341.7649,112.0269 362.8469,114.4589 369.7989,98.4469 C377.4399,80.8479 369.8429,71.9539 362.5489,65.5929 Z" id="Stroke-9" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<g id="Group-14" transform="translate(294.000000, 35.000000)">
<path d="M0.6446,155.881 L28.5346,0.691" id="Fill-11" fill="#FFFFFF"></path>
<path d="M0.6446,155.881 L28.5346,0.691" id="Stroke-13" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-18" transform="translate(312.000000, 65.000000)">
<path d="M0.8467,24.5988 L35.0417,0.8218" id="Fill-15" fill="#FFFFFF"></path>
<path d="M0.8467,24.5988 L35.0417,0.8218" id="Stroke-17" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-22" transform="translate(330.000000, 77.000000)">
<path d="M0.2667,0.4865 L11.5727,2.5175" id="Fill-19" fill="#FFFFFF"></path>
<path d="M0.2667,0.4865 L11.5727,2.5175" id="Stroke-21" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-26" transform="translate(268.000000, 81.000000)">
<path d="M0.6153,0.6496 L36.7463,52.6126" id="Fill-23" fill="#FFFFFF"></path>
<path d="M0.6153,0.6496 L36.7463,52.6126" id="Stroke-25" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-30" transform="translate(280.000000, 84.000000)">
<path d="M3.0938,0.2511 L0.5568,14.3641" id="Fill-27" fill="#FFFFFF"></path>
<path d="M3.0938,0.2511 L0.5568,14.3641" id="Stroke-29" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-34" transform="translate(277.000000, 115.000000)">
<path d="M17.4224,3.7648 L0.4394,0.7118" id="Fill-31" fill="#FFFFFF"></path>
<path d="M17.4224,3.7648 L0.4394,0.7118" id="Stroke-33" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-38" transform="translate(306.000000, 49.000000)">
<path d="M0.9561,0.0236 L11.4701,15.1436" id="Fill-35" fill="#FFFFFF"></path>
<path d="M0.9561,0.0236 L11.4701,15.1436" id="Stroke-37" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-42" transform="translate(309.000000, 99.000000)">
<path d="M0.358,10.2814 L14.685,0.3204" id="Fill-39" fill="#FFFFFF"></path>
<path d="M0.358,10.2814 L14.685,0.3204" id="Stroke-41" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-46" transform="translate(303.000000, 129.000000)">
<path d="M0.0045,15.6349 L21.7175,0.5369" id="Fill-43" fill="#FFFFFF"></path>
<path d="M0.0045,15.6349 L21.7175,0.5369" id="Stroke-45" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<polygon id="Fill-47" fill="#FFFFFF" points="314.4498 222.4113 263.6088 213.2743 268.1408 139.9543 335.7298 152.1003"></polygon>
<polygon id="Stroke-49" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="314.4498 222.4113 263.6088 213.2743 268.1408 139.9543 335.7298 152.1003"></polygon>
<polygon id="Fill-51" fill="#EFEFEF" points="314.4498 222.4113 263.6088 213.2743 268.1408 139.9543 335.7298 152.1003"></polygon>
<polygon id="Stroke-53" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="314.4498 222.4113 263.6088 213.2743 268.1408 139.9543 335.7298 152.1003"></polygon>
<polygon id="Fill-55" fill="#FFFFFF" points="341.3018 169.1974 256.9658 154.0414 259.7678 138.4494 344.1038 153.6054"></polygon>
<polygon id="Stroke-57" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="341.3018 169.1974 256.9658 154.0414 259.7678 138.4494 344.1038 153.6054"></polygon>
<polygon id="Fill-59" fill="#EFEFEF" points="341.3018 169.1974 256.9658 154.0414 259.7678 138.4494 344.1038 153.6054"></polygon>
<polygon id="Stroke-61" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="341.3018 169.1974 256.9658 154.0414 259.7678 138.4494 344.1038 153.6054"></polygon>
<path d="M124.9805,194.5822 C124.9805,221.7622 147.0135,243.7952 174.1925,243.7952 C201.3725,243.7952 223.4055,221.7622 223.4055,194.5822 C223.4055,167.4022 201.3725,145.3692 174.1925,145.3692 C147.0135,145.3692 124.9805,167.4022 124.9805,194.5822" id="Fill-63" fill="#EFEFEF"></path>
<path d="M124.9805,194.5822 C124.9805,221.7622 147.0135,243.7952 174.1925,243.7952 C201.3725,243.7952 223.4055,221.7622 223.4055,194.5822 C223.4055,167.4022 201.3725,145.3692 174.1925,145.3692 C147.0135,145.3692 124.9805,167.4022 124.9805,194.5822 Z" id="Stroke-65" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<polygon id="Fill-67" fill="#FFFFFF" points="109.3443 265.1769 210.3623 229.6169 168.9263 111.9069 67.9083 147.4669"></polygon>
<polygon id="Stroke-69" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="109.3443 265.1769 210.3623 229.6169 168.9263 111.9069 67.9083 147.4669"></polygon>
<path d="M174.1929,205.1828 L162.1449,161.7108 C161.8039,160.4818 161.2059,159.3368 160.3899,158.3558 L98.3399,87.5458 C97.5969,86.6528 96.3079,86.4448 95.3209,87.0588 L80.3479,96.3868 C79.3609,97.0008 78.9799,98.2498 79.4539,99.3108 L115.6559,186.2218 C116.1779,187.3878 116.9409,188.4288 117.8949,189.2778 L151.6029,219.2558 L174.1929,205.1828 Z" id="Fill-71" fill="#FFFFFF"></path>
<path d="M174.1929,205.1828 L162.1449,161.7108 C161.8039,160.4818 161.2059,159.3368 160.3899,158.3558 L98.3399,87.5458 C97.5969,86.6528 96.3079,86.4448 95.3209,87.0588 L80.3479,96.3868 C79.3609,97.0008 78.9799,98.2498 79.4539,99.3108 L115.6559,186.2218 C116.1779,187.3878 116.9409,188.4288 117.8949,189.2778 L151.6029,219.2558 L174.1929,205.1828 Z" id="Stroke-73" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M128.9444,169.4162 C130.7084,170.8122 131.3814,173.3572 129.3954,175.1992 C126.8184,177.5902 123.9854,174.6162 122.3504,172.2092 C119.5244,168.0482 123.2154,166.8352 128.9444,169.4162" id="Fill-75" fill="#EFEFEF"></path>
<path d="M128.9444,169.4162 C130.7084,170.8122 131.3814,173.3572 129.3954,175.1992 C126.8184,177.5902 123.9854,174.6162 122.3504,172.2092 C119.5244,168.0482 123.2154,166.8352 128.9444,169.4162 Z" id="Stroke-77" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M129.4752,194.3439 C129.8182,190.3379 130.6502,186.1419 132.4662,182.5269 C133.9512,179.5699 136.0732,176.4709 136.6182,173.1569 C137.4742,167.9439 133.8602,163.0769 131.2362,158.9499 C128.3042,154.3379 124.6322,147.2199 130.6672,143.1139 C135.6472,139.7259 141.9852,143.5549 145.5792,147.3059 C149.9262,151.8449 150.7502,156.9759 150.5762,163.0829 C150.4152,168.6739 150.2302,174.3289 153.7522,179.0219 C155.4252,181.2489 157.7662,182.8849 160.4532,183.6179 C163.1862,184.3639 166.4412,184.4849 168.8862,186.0349 L174.1932,205.1829 L151.6022,219.2559 L129.4442,199.5489 C129.3252,197.8229 129.3262,196.0859 129.4752,194.3439" id="Fill-79" fill="#EFEFEF"></path>
<path d="M129.4752,194.3439 C129.8182,190.3379 130.6502,186.1419 132.4662,182.5269 C133.9512,179.5699 136.0732,176.4709 136.6182,173.1569 C137.4742,167.9439 133.8602,163.0769 131.2362,158.9499 C128.3042,154.3379 124.6322,147.2199 130.6672,143.1139 C135.6472,139.7259 141.9852,143.5549 145.5792,147.3059 C149.9262,151.8449 150.7502,156.9759 150.5762,163.0829 C150.4152,168.6739 150.2302,174.3289 153.7522,179.0219 C155.4252,181.2489 157.7662,182.8849 160.4532,183.6179 C163.1862,184.3639 166.4412,184.4849 168.8862,186.0349 L174.1932,205.1829 L151.6022,219.2559 L129.4442,199.5489 C129.3252,197.8229 129.3262,196.0859 129.4752,194.3439 Z" id="Stroke-81" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M110.1046,134.5158 C109.9086,139.2308 114.0716,141.4198 115.2986,145.5518 C116.3966,149.2458 115.9566,153.5638 112.2996,155.6428 C109.4786,157.2468 106.7616,157.2088 103.4106,156.7008 L79.4546,99.3108 C78.9796,98.2498 79.3606,97.0008 80.3476,96.3868 L95.3216,87.0588 C96.3076,86.4448 97.5966,86.6528 98.3396,87.5458 L125.6296,118.7078 C121.5856,124.3868 110.4206,126.9138 110.1046,134.5158" id="Fill-83" fill="#EFEFEF"></path>
<path d="M110.1046,134.5158 C109.9086,139.2308 114.0716,141.4198 115.2986,145.5518 C116.3966,149.2458 115.9566,153.5638 112.2996,155.6428 C109.4786,157.2468 106.7616,157.2088 103.4106,156.7008 L79.4546,99.3108 C78.9796,98.2498 79.3606,97.0008 80.3476,96.3868 L95.3216,87.0588 C96.3076,86.4448 97.5966,86.6528 98.3396,87.5458 L125.6296,118.7078 C121.5856,124.3868 110.4206,126.9138 110.1046,134.5158 Z" id="Stroke-85" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M89.8262,124.1574 L79.4542,99.3104 C78.9792,98.2504 79.3612,97.0014 80.3472,96.3864 L95.3212,87.0584 C96.3072,86.4444 97.5972,86.6524 98.3402,87.5464 L116.0792,107.8034 L89.8262,124.1574 Z" id="Fill-87" fill="#FFFFFF"></path>
<path d="M89.8262,124.1574 L79.4542,99.3104 C78.9792,98.2504 79.3612,97.0014 80.3472,96.3864 L95.3212,87.0584 C96.3072,86.4444 97.5972,86.6524 98.3402,87.5464 L116.0792,107.8034 L89.8262,124.1574 Z" id="Stroke-89" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<polygon id="Fill-91" fill="#FFFFFF" points="166.6944 178.1261 174.1934 205.1831 151.6024 219.2561 130.6224 200.5971"></polygon>
<polygon id="Stroke-93" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" points="166.6944 178.1261 174.1934 205.1831 151.6024 219.2561 130.6224 200.5971"></polygon>
<path d="M202.8243,233.589 L174.1933,205.183 L151.6023,219.256 L164.4763,257.478 C164.8683,258.999 166.6253,259.702 167.9593,258.872 L202.5403,237.329 C203.8743,236.498 204.0173,234.611 202.8243,233.589" id="Fill-95" fill="#FFFFFF"></path>
<path d="M202.8243,233.589 L174.1933,205.183 L151.6023,219.256 L164.4763,257.478 C164.8683,258.999 166.6253,259.702 167.9593,258.872 L202.5403,237.329 C203.8743,236.498 204.0173,234.611 202.8243,233.589 Z" id="Stroke-97" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-100"></g>
<polygon id="Fill-99" fill="#FFFFFF" mask="url(#mask-2)" points="80.131 350 350.635 350 350.635 181.521 80.131 181.521"></polygon>
<path d="M330.171,280.0646 L350.635,234.5306 L350.635,181.5206 L80.13,181.5206 L80.13,350.0006 L350.635,350.0006 L350.635,339.7356 L94.056,339.7356 C91.15,339.7356 88.795,337.3796 88.795,334.4746 L88.795,280.0646 L330.171,280.0646 Z" id="Fill-101" fill="#EFEFEF" mask="url(#mask-2)"></path>
<polygon id="Stroke-102" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="80.131 350 350.635 350 350.635 181.521 80.131 181.521"></polygon>
<path d="M425.2598,245.0627 L357.1608,180.1587 C355.6748,178.7417 353.3208,178.7977 351.9038,180.2847 L351.8518,180.3387 C350.4348,181.8267 350.4908,184.1797 351.9778,185.5967 L420.0768,250.5007 C421.5638,251.9167 423.9178,251.8607 425.3348,250.3747 C425.3518,250.3567 425.3688,250.3377 425.3858,250.3207 C426.8028,248.8337 426.7468,246.4797 425.2598,245.0627" id="Fill-103" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M425.2598,245.0627 L357.1608,180.1587 C355.6748,178.7417 353.3208,178.7977 351.9038,180.2847 L351.8518,180.3387 C350.4348,181.8267 350.4908,184.1797 351.9778,185.5967 L420.0768,250.5007 C421.5638,251.9167 423.9178,251.8607 425.3348,250.3747 C425.3518,250.3567 425.3688,250.3377 425.3858,250.3207 C426.8028,248.8337 426.7468,246.4797 425.2598,245.0627 Z" id="Stroke-104" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M3.1529,245.0627 L71.2519,180.1587 C72.7389,178.7417 75.0929,178.7977 76.5089,180.2847 L76.5619,180.3387 C77.9789,181.8267 77.9219,184.1797 76.4349,185.5967 L8.3359,250.5007 C6.8489,251.9167 4.4949,251.8607 3.0789,250.3747 C3.0609,250.3567 3.0439,250.3377 3.0269,250.3207 C1.6099,248.8337 1.6669,246.4797 3.1529,245.0627" id="Fill-105" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M3.1529,245.0627 L71.2519,180.1587 C72.7389,178.7417 75.0929,178.7977 76.5089,180.2847 L76.5619,180.3387 C77.9789,181.8267 77.9219,184.1797 76.4349,185.5967 L8.3359,250.5007 C6.8489,251.9167 4.4949,251.8607 3.0789,250.3747 C3.0609,250.3567 3.0439,250.3377 3.0269,250.3207 C1.6099,248.8337 1.6669,246.4797 3.1529,245.0627 Z" id="Stroke-106" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M316.127,256.591 L55.46,256.591 C52.218,256.591 50.023,253.289 51.277,250.301 L80.13,181.521 L350.635,181.521 L320.31,253.81 C319.603,255.495 317.954,256.591 316.127,256.591" id="Fill-107" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M316.127,256.591 L55.46,256.591 C52.218,256.591 50.023,253.289 51.277,250.301 L80.13,181.521 L350.635,181.521 L320.31,253.81 C319.603,255.495 317.954,256.591 316.127,256.591 Z" id="Stroke-108" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

188
_site/assets/posts/city.svg

@ -0,0 +1,188 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="818px" height="288px" viewBox="0 0 818 288" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Style 9</title>
<desc>Created with Sketch.</desc>
<defs>
<polygon id="path-1" points="0 287 1057.606 287 1057.606 0.388 0 0.388"></polygon>
</defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Background-Images" transform="translate(-1803.000000, -2124.000000)">
<g id="Style-9" transform="translate(1683.000000, 2124.000000)">
<path d="M1.9998,285.6122 L1055.6068,285.6122 L1.9998,285.6122 Z" id="Fill-1" fill="#D02929"></path>
<g id="Group-146" transform="translate(0.000000, 0.612000)">
<path d="M712.7791,57.7333 C727.8561,57.7333 720.8011,33.8283 701.7021,39.5383 C700.6451,6.3433 646.5391,-17.9437 624.1671,26.8273 C617.8411,21.8223 603.6371,31.2763 606.7831,39.5383 C599.7571,40.1363 594.2271,40.9493 589.9271,42.0253 C579.9981,44.5103 581.9631,57.6223 592.1991,57.5303 L712.7791,57.7333 Z" id="Fill-4" fill="#FFFFFF"></path>
<path d="M712.7791,57.7333 C727.8561,57.7333 720.8011,33.8283 701.7021,39.5383 C700.6451,6.3433 646.5391,-17.9437 624.1671,26.8273 C617.8411,21.8223 603.6371,31.2763 606.7831,39.5383 C599.7571,40.1363 594.2271,40.9493 589.9271,42.0253 C579.9981,44.5103 581.9631,57.6223 592.1991,57.5303 L712.7791,57.7333 Z" id="Stroke-6" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M894.5662,89.4452 L827.7962,89.4452 C822.3902,89.4452 820.0602,82.4462 824.4852,79.3402 C824.5462,79.2962 824.6092,79.2532 824.6722,79.2092 C830.9712,74.8792 839.2392,75.2722 839.2392,75.2722 C839.2392,75.2722 840.4202,51.8482 862.6632,51.8482 C873.6602,51.8482 882.5472,70.6462 882.5472,70.6462 C882.5472,70.6462 897.5062,70.6462 899.9822,82.4582 C900.7322,86.0362 898.2212,89.4452 894.5662,89.4452" id="Fill-8" fill="#FFFFFF"></path>
<path d="M894.5662,89.4452 L827.7962,89.4452 C822.3902,89.4452 820.0602,82.4462 824.4852,79.3402 C824.5462,79.2962 824.6092,79.2532 824.6722,79.2092 C830.9712,74.8792 839.2392,75.2722 839.2392,75.2722 C839.2392,75.2722 840.4202,51.8482 862.6632,51.8482 C873.6602,51.8482 882.5472,70.6462 882.5472,70.6462 C882.5472,70.6462 897.5062,70.6462 899.9822,82.4582 C900.7322,86.0362 898.2212,89.4452 894.5662,89.4452 Z" id="Stroke-10" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M205.6257,47.9872 L268.5157,47.9872 C274.1377,47.9872 276.5617,40.7082 271.9597,37.4772 C271.8957,37.4322 271.8297,37.3872 271.7647,37.3422 C265.2137,32.8392 256.6157,33.2482 256.6157,33.2482 C256.6157,33.2482 255.3877,8.8862 232.2547,8.8862 C211.3417,8.8862 203.0007,29.4132 199.9927,40.7202 C199.0157,44.3952 201.8237,47.9872 205.6257,47.9872" id="Fill-12" fill="#FFFFFF"></path>
<path d="M205.6257,47.9872 L268.5157,47.9872 C274.1377,47.9872 276.5617,40.7082 271.9597,37.4772 C271.8957,37.4322 271.8297,37.3872 271.7647,37.3422 C265.2137,32.8392 256.6157,33.2482 256.6157,33.2482 C256.6157,33.2482 255.3877,8.8862 232.2547,8.8862 C211.3417,8.8862 203.0007,29.4132 199.9927,40.7202 C199.0157,44.3952 201.8237,47.9872 205.6257,47.9872 Z" id="Stroke-14" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M317.9763,91.7441 L439.1173,91.7441 C450.4893,91.7441 449.9663,82.3811 446.2523,79.1181 C442.4463,75.7751 434.9233,77.1321 434.9233,77.1321 C434.9233,77.1321 432.6833,70.8341 425.3123,67.7671 C418.7913,65.0561 411.9603,66.3471 411.9603,66.3471 C411.9603,66.3471 411.9603,62.0241 407.7863,58.4441 C403.6113,54.8651 398.0443,55.2131 398.0443,55.2131 C398.0443,55.2131 394.2173,31.3811 368.6453,31.3811 C343.0743,31.3811 340.1163,53.8211 340.1163,53.8211 C340.1163,53.8211 334.3753,53.8211 330.2013,57.6481 C326.0263,61.4751 325.5033,65.8241 325.5033,65.8241 C325.5033,65.8241 311.5413,63.9431 307.4133,75.9871 C304.9523,83.1661 310.0073,91.7441 317.9763,91.7441" id="Fill-16" fill="#FFFFFF"></path>
<path d="M317.9763,91.7441 L439.1173,91.7441 C450.4893,91.7441 449.9663,82.3811 446.2523,79.1181 C442.4463,75.7751 434.9233,77.1321 434.9233,77.1321 C434.9233,77.1321 432.6833,70.8341 425.3123,67.7671 C418.7913,65.0561 411.9603,66.3471 411.9603,66.3471 C411.9603,66.3471 411.9603,62.0241 407.7863,58.4441 C403.6113,54.8651 398.0443,55.2131 398.0443,55.2131 C398.0443,55.2131 394.2173,31.3811 368.6453,31.3811 C343.0743,31.3811 340.1163,53.8211 340.1163,53.8211 C340.1163,53.8211 334.3753,53.8211 330.2013,57.6481 C326.0263,61.4751 325.5033,65.8241 325.5033,65.8241 C325.5033,65.8241 311.5413,63.9431 307.4133,75.9871 C304.9523,83.1661 310.0073,91.7441 317.9763,91.7441 Z" id="Stroke-18" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-21"></g>
<polygon id="Fill-20" fill="#FFFFFF" mask="url(#mask-2)" points="477.282 285 598.789 285 598.789 52.795 477.282 52.795"></polygon>
<polygon id="Stroke-22" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="477.282 285 598.789 285 598.789 52.795 477.282 52.795"></polygon>
<polygon id="Fill-23" fill="#FFFFFF" mask="url(#mask-2)" points="236.478 285 385.042 285 385.042 206.532 236.478 206.532"></polygon>
<polygon id="Stroke-24" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="236.478 285 385.042 285 385.042 206.532 236.478 206.532"></polygon>
<polygon id="Fill-25" fill="#FFFFFF" mask="url(#mask-2)" points="658.162 285 806.725 285 806.725 181.265 658.162 181.265"></polygon>
<polygon id="Stroke-26" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="658.162 285 806.725 285 806.725 181.265 658.162 181.265"></polygon>
<polygon id="Fill-27" fill="#FFFFFF" mask="url(#mask-2)" points="431.61 284.486 532.794 284.486 532.794 111.167 431.61 111.167"></polygon>
<polygon id="Stroke-28" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="431.61 284.486 532.794 284.486 532.794 111.167 431.61 111.167"></polygon>
<polygon id="Fill-29" fill="#FFFFFF" mask="url(#mask-2)" points="423.142 117.076 541.26 117.076 541.26 108.068 423.142 108.068"></polygon>
<polygon id="Stroke-30" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="423.142 117.076 541.26 117.076 541.26 108.068 423.142 108.068"></polygon>
<g id="Group-33" mask="url(#mask-2)">
<g transform="translate(431.000000, 172.000000)">
<path d="M0.7087,0.6923 L100.4277,0.6923" id="Fill-31" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.7087,0.6923 L100.4277,0.6923" id="Stroke-32" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<g id="Group-36" mask="url(#mask-2)">
<g transform="translate(433.000000, 230.000000)">
<path d="M0.7126,0.5097 L99.0706,0.5097" id="Fill-34" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.7126,0.5097 L99.0706,0.5097" id="Stroke-35" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<polygon id="Fill-37" fill="#FFFFFF" mask="url(#mask-2)" points="447.059 217.501 461.008 217.501 461.008 187.297 447.059 187.297"></polygon>
<polygon id="Stroke-38" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="447.059 217.501 461.008 217.501 461.008 187.297 447.059 187.297"></polygon>
<polygon id="Fill-39" fill="#FFFFFF" mask="url(#mask-2)" points="476.169 217.501 490.118 217.501 490.118 187.297 476.169 187.297"></polygon>
<polygon id="Stroke-40" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="476.169 217.501 490.118 217.501 490.118 187.297 476.169 187.297"></polygon>
<polygon id="Fill-41" fill="#FFFFFF" mask="url(#mask-2)" points="505.368 217.501 519.317 217.501 519.317 187.297 505.368 187.297"></polygon>
<polygon id="Stroke-42" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="505.368 217.501 519.317 217.501 519.317 187.297 505.368 187.297"></polygon>
<polygon id="Fill-43" fill="#FFFFFF" mask="url(#mask-2)" points="447.059 161.059 461.008 161.059 461.008 130.855 447.059 130.855"></polygon>
<polygon id="Stroke-44" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="447.059 161.059 461.008 161.059 461.008 130.855 447.059 130.855"></polygon>
<polygon id="Fill-45" fill="#FFFFFF" mask="url(#mask-2)" points="476.169 161.059 490.118 161.059 490.118 130.855 476.169 130.855"></polygon>
<polygon id="Stroke-46" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="476.169 161.059 490.118 161.059 490.118 130.855 476.169 130.855"></polygon>
<polygon id="Fill-47" fill="#FFFFFF" mask="url(#mask-2)" points="505.368 161.059 519.317 161.059 519.317 130.855 505.368 130.855"></polygon>
<polygon id="Stroke-48" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="505.368 161.059 519.317 161.059 519.317 130.855 505.368 130.855"></polygon>
<polygon id="Fill-49" fill="#FFFFFF" mask="url(#mask-2)" points="447.059 273.901 461.008 273.901 461.008 243.697 447.059 243.697"></polygon>
<polygon id="Stroke-50" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="447.059 273.901 461.008 273.901 461.008 243.697 447.059 243.697"></polygon>
<polygon id="Fill-51" fill="#FFFFFF" mask="url(#mask-2)" points="476.169 285 490.118 285 490.118 243.697 476.169 243.697"></polygon>
<polygon id="Stroke-52" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="476.169 285 490.118 285 490.118 243.697 476.169 243.697"></polygon>
<polygon id="Fill-53" fill="#FFFFFF" mask="url(#mask-2)" points="505.368 273.901 519.317 273.901 519.317 243.697 505.368 243.697"></polygon>
<polygon id="Stroke-54" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="505.368 273.901 519.317 273.901 519.317 243.697 505.368 243.697"></polygon>
<polygon id="Fill-55" fill="#FFFFFF" mask="url(#mask-2)" points="571.707 284.389 692.113 284.389 692.113 78.142 571.707 78.142"></polygon>
<polygon id="Stroke-56" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="571.707 284.389 692.113 284.389 692.113 78.142 571.707 78.142"></polygon>
<polygon id="Fill-57" fill="#FFFFFF" mask="url(#mask-2)" points="571.707 284.389 692.113 284.389 692.113 273.902 571.707 273.902"></polygon>
<polygon id="Stroke-58" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="571.707 284.389 692.113 284.389 692.113 273.902 571.707 273.902"></polygon>
<polygon id="Fill-59" fill="#FFFFFF" mask="url(#mask-2)" points="561.63 83.814 702.189 83.814 702.189 74.455 561.63 74.455"></polygon>
<polygon id="Stroke-60" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="561.63 83.814 702.189 83.814 702.189 74.455 561.63 74.455"></polygon>
<g id="Group-63" mask="url(#mask-2)">
<g transform="translate(574.000000, 230.000000)">
<path d="M0.2087,0.5097 L118.8717,0.5097" id="Fill-61" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.2087,0.5097 L118.8717,0.5097" id="Stroke-62" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<polygon id="Fill-64" fill="#FFFFFF" mask="url(#mask-2)" points="624.731 285 641.33 285 641.33 243.697 624.731 243.697"></polygon>
<polygon id="Stroke-65" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="624.731 285 641.33 285 641.33 243.697 624.731 243.697"></polygon>
<polygon id="Fill-66" fill="#FFFFFF" mask="url(#mask-2)" points="659.382 273.252 675.982 273.252 675.982 257.439 659.382 257.439"></polygon>
<polygon id="Stroke-67" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="659.382 273.252 675.982 273.252 675.982 257.439 659.382 257.439"></polygon>
<polygon id="Fill-68" fill="#FFFFFF" mask="url(#mask-2)" points="590.703 273.252 607.302 273.252 607.302 257.439 590.703 257.439"></polygon>
<polygon id="Stroke-69" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="590.703 273.252 607.302 273.252 607.302 257.439 590.703 257.439"></polygon>
<polygon id="Fill-70" fill="#FFFFFF" mask="url(#mask-2)" points="659.382 215.492 675.982 215.492 675.982 199.679 659.382 199.679"></polygon>
<polygon id="Stroke-71" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="659.382 215.492 675.982 215.492 675.982 199.679 659.382 199.679"></polygon>
<polygon id="Fill-72" fill="#FFFFFF" mask="url(#mask-2)" points="590.703 215.492 607.302 215.492 607.302 199.679 590.703 199.679"></polygon>
<polygon id="Stroke-73" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="590.703 215.492 607.302 215.492 607.302 199.679 590.703 199.679"></polygon>
<polygon id="Fill-74" fill="#FFFFFF" mask="url(#mask-2)" points="624.731 215.492 641.33 215.492 641.33 199.679 624.731 199.679"></polygon>
<polygon id="Stroke-75" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="624.731 215.492 641.33 215.492 641.33 199.679 624.731 199.679"></polygon>
<polygon id="Fill-76" fill="#FFFFFF" mask="url(#mask-2)" points="659.382 182.625 675.982 182.625 675.982 166.812 659.382 166.812"></polygon>
<polygon id="Stroke-77" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="659.382 182.625 675.982 182.625 675.982 166.812 659.382 166.812"></polygon>
<polygon id="Fill-78" fill="#FFFFFF" mask="url(#mask-2)" points="590.703 182.625 607.302 182.625 607.302 166.812 590.703 166.812"></polygon>
<polygon id="Stroke-79" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="590.703 182.625 607.302 182.625 607.302 166.812 590.703 166.812"></polygon>
<polygon id="Fill-80" fill="#FFFFFF" mask="url(#mask-2)" points="624.731 182.625 641.33 182.625 641.33 166.812 624.731 166.812"></polygon>
<polygon id="Stroke-81" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="624.731 182.625 641.33 182.625 641.33 166.812 624.731 166.812"></polygon>
<polygon id="Fill-82" fill="#FFFFFF" mask="url(#mask-2)" points="659.382 151.617 675.982 151.617 675.982 135.804 659.382 135.804"></polygon>
<polygon id="Stroke-83" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="659.382 151.617 675.982 151.617 675.982 135.804 659.382 135.804"></polygon>
<polygon id="Fill-84" fill="#FFFFFF" mask="url(#mask-2)" points="590.703 151.617 607.302 151.617 607.302 135.804 590.703 135.804"></polygon>
<polygon id="Stroke-85" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="590.703 151.617 607.302 151.617 607.302 135.804 590.703 135.804"></polygon>
<polygon id="Fill-86" fill="#FFFFFF" mask="url(#mask-2)" points="624.731 151.617 641.33 151.617 641.33 135.804 624.731 135.804"></polygon>
<polygon id="Stroke-87" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="624.731 151.617 641.33 151.617 641.33 135.804 624.731 135.804"></polygon>
<polygon id="Fill-88" fill="#FFFFFF" mask="url(#mask-2)" points="659.382 118.75 675.982 118.75 675.982 102.937 659.382 102.937"></polygon>
<polygon id="Stroke-89" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="659.382 118.75 675.982 118.75 675.982 102.937 659.382 102.937"></polygon>
<polygon id="Fill-90" fill="#FFFFFF" mask="url(#mask-2)" points="590.703 118.75 607.302 118.75 607.302 102.937 590.703 102.937"></polygon>
<polygon id="Stroke-91" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="590.703 118.75 607.302 118.75 607.302 102.937 590.703 102.937"></polygon>
<polygon id="Fill-92" fill="#FFFFFF" mask="url(#mask-2)" points="624.731 118.75 641.33 118.75 641.33 102.937 624.731 102.937"></polygon>
<polygon id="Stroke-93" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="624.731 118.75 641.33 118.75 641.33 102.937 624.731 102.937"></polygon>
<path d="M346.7898,160.704 L346.8588,160.704 C348.7388,160.704 350.2638,162.228 350.2638,164.108 L350.2638,285 L343.3858,285 L343.3858,164.108 C343.3858,162.228 344.9098,160.704 346.7898,160.704" id="Fill-94" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M346.7898,160.704 L346.8588,160.704 C348.7388,160.704 350.2638,162.228 350.2638,164.108 L350.2638,285 L343.3858,285 L343.3858,164.108 C343.3858,162.228 344.9098,160.704 346.7898,160.704 Z" id="Stroke-95" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M286.5271,199.9452 C286.5271,233.3922 313.6411,260.5082 347.0891,260.5082 C380.5371,260.5082 407.6511,233.3922 407.6511,199.9452 C407.6511,166.4982 380.5371,131.4682 347.0891,131.4682 C313.6411,131.4682 286.5271,166.4982 286.5271,199.9452" id="Fill-96" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M286.5271,199.9452 C286.5271,233.3922 313.6411,260.5082 347.0891,260.5082 C380.5371,260.5082 407.6511,233.3922 407.6511,199.9452 C407.6511,166.4982 380.5371,131.4682 347.0891,131.4682 C313.6411,131.4682 286.5271,166.4982 286.5271,199.9452 Z" id="Stroke-97" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<polygon id="Fill-98" fill="#FFFFFF" mask="url(#mask-2)" points="128.245 285 271.142 285 271.142 176.154 128.245 176.154"></polygon>
<polygon id="Stroke-99" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="128.245 285 271.142 285 271.142 176.154 128.245 176.154"></polygon>
<polygon id="Fill-100" fill="#FFFFFF" mask="url(#mask-2)" points="122.491 181.313 276.896 181.313 276.896 173.278 122.491 173.278"></polygon>
<polygon id="Stroke-101" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="122.491 181.313 276.896 181.313 276.896 173.278 122.491 173.278"></polygon>
<polygon id="Fill-102" fill="#FFFFFF" mask="url(#mask-2)" points="185.094 284.486 214.293 284.486 214.293 243.697 185.094 243.697"></polygon>
<polygon id="Stroke-103" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="185.094 284.486 214.293 284.486 214.293 243.697 185.094 243.697"></polygon>
<polygon id="Fill-104" fill="#FFFFFF" mask="url(#mask-2)" points="183.626 233.133 215.76 233.133 215.76 197.852 183.626 197.852"></polygon>
<polygon id="Stroke-105" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="183.626 233.133 215.76 233.133 215.76 197.852 183.626 197.852"></polygon>
<polygon id="Fill-106" fill="#FFFFFF" mask="url(#mask-2)" points="230.344 284.389 260.106 284.389 260.106 197.852 230.344 197.852"></polygon>
<polygon id="Stroke-107" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="230.344 284.389 260.106 284.389 260.106 197.852 230.344 197.852"></polygon>
<polygon id="Fill-108" fill="#FFFFFF" mask="url(#mask-2)" points="140.489 284.389 170.251 284.389 170.251 197.852 140.489 197.852"></polygon>
<polygon id="Stroke-109" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="140.489 284.389 170.251 284.389 170.251 197.852 140.489 197.852"></polygon>
<polygon id="Fill-110" fill="#FFFFFF" mask="url(#mask-2)" points="835.836 284.487 928.62 284.487 928.62 230.51 835.836 230.51"></polygon>
<polygon id="Stroke-111" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="835.836 284.487 928.62 284.487 928.62 230.51 835.836 230.51"></polygon>
<polygon id="Fill-112" fill="#FFFFFF" mask="url(#mask-2)" points="829.34 230.617 935.116 230.617 935.116 222.893 829.34 222.893"></polygon>
<polygon id="Stroke-113" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="829.34 230.617 935.116 230.617 935.116 222.893 829.34 222.893"></polygon>
<polygon id="Fill-114" fill="#FFFFFF" mask="url(#mask-2)" points="852.838 285 869.437 285 869.437 243.697 852.838 243.697"></polygon>
<polygon id="Stroke-115" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="852.838 285 869.437 285 869.437 243.697 852.838 243.697"></polygon>
<polygon id="Fill-116" fill="#FFFFFF" mask="url(#mask-2)" points="882.229 273.252 915.629 273.252 915.629 245.766 882.229 245.766"></polygon>
<polygon id="Stroke-117" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="882.229 273.252 915.629 273.252 915.629 245.766 882.229 245.766"></polygon>
<path d="M774.9744,128.0634 L775.0434,128.0634 C776.9234,128.0634 778.4484,129.5874 778.4484,131.4684 L778.4484,285.0004 L771.5694,285.0004 L771.5694,131.4684 C771.5694,129.5874 773.0944,128.0634 774.9744,128.0634" id="Fill-118" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M774.9744,128.0634 L775.0434,128.0634 C776.9234,128.0634 778.4484,129.5874 778.4484,131.4684 L778.4484,285.0004 L771.5694,285.0004 L771.5694,131.4684 C771.5694,129.5874 773.0944,128.0634 774.9744,128.0634 Z" id="Stroke-119" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M714.7117,199.9452 C714.7117,233.3922 741.8257,260.5082 775.2737,260.5082 C808.7217,260.5082 835.8357,233.3922 835.8357,199.9452 C835.8357,166.4982 808.7217,100.5322 775.2737,100.5322 C741.8257,100.5322 714.7117,166.4982 714.7117,199.9452" id="Fill-120" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M714.7117,199.9452 C714.7117,233.3922 741.8257,260.5082 775.2737,260.5082 C808.7217,260.5082 835.8357,233.3922 835.8357,199.9452 C835.8357,166.4982 808.7217,100.5322 775.2737,100.5322 C741.8257,100.5322 714.7117,166.4982 714.7117,199.9452 Z" id="Stroke-121" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<g id="Group-124" mask="url(#mask-2)">
<g transform="translate(237.000000, 107.000000)">
<path d="M0.8406,0.6972 L22.8406,0.6972" id="Fill-122" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.8406,0.6972 L22.8406,0.6972" id="Stroke-123" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<g id="Group-127" mask="url(#mask-2)">
<g transform="translate(281.000000, 107.000000)">
<path d="M0.7859,0.6972 L36.7859,0.6972" id="Fill-125" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.7859,0.6972 L36.7859,0.6972" id="Stroke-126" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<g id="Group-130" mask="url(#mask-2)">
<g transform="translate(435.000000, 27.000000)">
<path d="M0.8405,0.6972 L16.8405,0.6972" id="Fill-128" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.8405,0.6972 L16.8405,0.6972" id="Stroke-129" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<g id="Group-133" mask="url(#mask-2)">
<g transform="translate(752.000000, 37.000000)">
<polyline id="Fill-131" stroke="none" fill="#FFFFFF" fill-rule="evenodd" points="0.8181 0.6972 2.8181 0.6972 14.8181 0.6972"></polyline>
<polyline id="Stroke-132" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round" points="0.8181 0.6972 2.8181 0.6972 14.8181 0.6972"></polyline>
</g>
</g>
<g id="Group-136" mask="url(#mask-2)">
<g transform="translate(516.000000, 37.000000)">
<polyline id="Fill-134" stroke="none" fill="#FFFFFF" fill-rule="evenodd" points="0.3171 0.6972 7.3171 0.6972 23.3171 0.6972"></polyline>
<polyline id="Stroke-135" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round" points="0.3171 0.6972 7.3171 0.6972 23.3171 0.6972"></polyline>
</g>
</g>
<g id="Group-139" mask="url(#mask-2)">
<g transform="translate(569.000000, 17.000000)">
<polyline id="Fill-137" stroke="none" fill="#FFFFFF" fill-rule="evenodd" points="0.8406 0.6972 0.8406 2.6972 12.8406 2.6972"></polyline>
<polyline id="Stroke-138" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round" points="0.8406 0.6972 0.8406 2.6972 12.8406 2.6972"></polyline>
</g>
</g>
<g id="Group-142" mask="url(#mask-2)">
<g transform="translate(841.000000, 104.000000)">
<path d="M0.3923,0.6972 L22.4833,0.6972" id="Fill-140" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.3923,0.6972 L22.4833,0.6972" id="Stroke-141" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
<g id="Group-145" mask="url(#mask-2)">
<g transform="translate(879.000000, 104.000000)">
<path d="M0.8406,0.6972 L16.8406,0.6972" id="Fill-143" stroke="none" fill="#FFFFFF" fill-rule="evenodd"></path>
<path d="M0.8406,0.6972 L16.8406,0.6972" id="Stroke-144" stroke="#E1E4E5" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

47
_site/assets/posts/imac.svg

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="391px" height="332px" viewBox="0 0 391 332" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>iMac</title>
<desc>Created with Sketch.</desc>
<defs>
<polygon id="path-1" points="0 331.839 390.165 331.839 390.165 0 0 0"></polygon>
</defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Monochrome-Images" transform="translate(-511.000000, -1008.000000)">
<g id="iMac" transform="translate(511.000000, 1008.000000)">
<path d="M264.565,329.839 L125.6,329.839 C152.563,304.719 153.241,265.184 155.392,226.457 L234.597,226.457 C235.235,269.31 238.642,309.679 264.565,329.839 Z" id="Fill-1" fill="#FFFFFF"></path>
<path d="M264.565,329.839 L125.6,329.839 C152.563,304.719 153.241,265.184 155.392,226.457 L234.597,226.457 C235.235,269.31 238.642,309.679 264.565,329.839" id="Fill-3" fill="#FFFFFF"></path>
<path d="M241.9644,291.8429 C236.6784,272.7479 235.4844,249.9809 235.1344,226.4569 L155.9294,226.4569 C154.6784,248.9789 153.9144,271.7679 148.2004,291.8429 L241.9644,291.8429 Z" id="Fill-5" fill="#EFEFEF"></path>
<path d="M264.565,329.839 L125.6,329.839 C152.563,304.719 153.241,265.184 155.392,226.457 L234.597,226.457 C235.235,269.31 238.642,309.679 264.565,329.839 Z" id="Stroke-7" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M388.1656,245.5754 L388.1656,15.7374 C388.1656,6.5714 383.5026,2.0004 377.7516,2.0004 L12.4136,2.0004 C6.6626,2.0004 1.9996,6.5714 1.9996,15.7374 L1.9996,245.5754 L388.1656,245.5754 Z" id="Fill-9" fill="#EFEFEF"></path>
<path d="M388.1656,245.5754 L388.1656,15.7374 C388.1656,6.5714 383.5026,2.0004 377.7516,2.0004 L12.4136,2.0004 C6.6626,2.0004 1.9996,6.5714 1.9996,15.7374 L1.9996,245.5754 L388.1656,245.5754 Z" id="Stroke-11" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M1.9996,232.4645 L1.9996,266.6085 C1.9996,272.2465 6.6626,276.8175 12.4136,276.8175 L377.7516,276.8175 C383.5026,276.8175 388.1656,272.2465 388.1656,266.6085 L388.1656,232.4645 L1.9996,232.4645 Z" id="Fill-13" fill="#FFFFFF"></path>
<path d="M1.9996,232.4645 L1.9996,266.6085 C1.9996,272.2465 6.6626,276.8175 12.4136,276.8175 L377.7516,276.8175 C383.5026,276.8175 388.1656,272.2465 388.1656,266.6085 L388.1656,232.4645 L1.9996,232.4645 Z" id="Stroke-15" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M204.0641,254.0524 C204.0641,258.9154 200.0431,262.8574 195.0831,262.8574 C190.1221,262.8574 186.1011,258.9154 186.1011,254.0524 C186.1011,249.1904 190.1221,245.2484 195.0831,245.2484 C200.0431,245.2484 204.0641,249.1904 204.0641,254.0524" id="Fill-17" fill="#C7CFD3"></path>
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-20"></g>
<polygon id="Fill-19" fill="#FFFFFF" mask="url(#mask-2)" points="16.839 216.594 373.327 216.594 373.327 18.021 16.839 18.021"></polygon>
<polygon id="Stroke-21" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)" points="16.839 216.594 373.327 216.594 373.327 18.021 16.839 18.021"></polygon>
<path d="M198.1764,9.6286 C198.1764,11.3036 196.7914,12.6616 195.0824,12.6616 C193.3734,12.6616 191.9894,11.3036 191.9894,9.6286 C191.9894,7.9536 193.3734,6.5966 195.0824,6.5966 C196.7914,6.5966 198.1764,7.9536 198.1764,9.6286" id="Fill-22" fill="#C7CFD3" mask="url(#mask-2)"></path>
<path d="M264.565,321.4294 L125.6,321.4294 C123.349,321.4294 121.525,323.2544 121.525,325.5054 L121.525,325.5874 C121.525,327.8384 123.349,329.6634 125.6,329.6634 L264.565,329.6634 C266.816,329.6634 268.64,327.8384 268.64,325.5874 L268.64,325.5054 C268.64,323.2544 266.816,321.4294 264.565,321.4294" id="Fill-24" fill="#FFFFFF" mask="url(#mask-2)"></path>
<path d="M264.565,321.4294 L125.6,321.4294 C123.349,321.4294 121.525,323.2544 121.525,325.5054 L121.525,325.5874 C121.525,327.8384 123.349,329.6634 125.6,329.6634 L264.565,329.6634 C266.816,329.6634 268.64,327.8384 268.64,325.5874 L268.64,325.5054 C268.64,323.2544 266.816,321.4294 264.565,321.4294 Z" id="Stroke-25" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M277.1744,183.1427 L112.9904,183.1427 C109.1094,183.1427 105.9624,179.9997 105.9624,176.1237 L105.9624,59.3837 C105.9624,55.5077 109.1094,52.3647 112.9904,52.3647 L277.1744,52.3647 C281.0564,52.3647 284.2024,55.5077 284.2024,59.3837 L284.2024,176.1237 C284.2024,179.9997 281.0564,183.1427 277.1744,183.1427" id="Fill-26" fill="#EFEFEF" mask="url(#mask-2)"></path>
<path d="M277.1744,183.1427 L112.9904,183.1427 C109.1094,183.1427 105.9624,179.9997 105.9624,176.1237 L105.9624,59.3837 C105.9624,55.5077 109.1094,52.3647 112.9904,52.3647 L277.1744,52.3647 C281.0564,52.3647 284.2024,55.5077 284.2024,59.3837 L284.2024,176.1237 C284.2024,179.9997 281.0564,183.1427 277.1744,183.1427 Z" id="Stroke-27" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M239.5455,158.3395 L150.6195,158.3395 C148.5175,158.3395 146.8135,156.6375 146.8135,154.5385 L146.8135,91.3095 C146.8135,89.2095 148.5175,87.5075 150.6195,87.5075 L239.5455,87.5075 C241.6485,87.5075 243.3525,89.2095 243.3525,91.3095 L243.3525,154.5385 C243.3525,156.6375 241.6485,158.3395 239.5455,158.3395" id="Fill-28" fill="#FCFCFC" mask="url(#mask-2)"></path>
<path d="M239.5455,158.3395 L150.6195,158.3395 C148.5175,158.3395 146.8135,156.6375 146.8135,154.5385 L146.8135,91.3095 C146.8135,89.2095 148.5175,87.5075 150.6195,87.5075 L239.5455,87.5075 C241.6485,87.5075 243.3525,89.2095 243.3525,91.3095 L243.3525,154.5385 C243.3525,156.6375 241.6485,158.3395 239.5455,158.3395 Z" id="Stroke-29" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M284.2027,67.6569 L284.2027,59.3839 C284.2027,55.5079 281.0567,52.3649 277.1747,52.3649 L112.9907,52.3649 C109.1087,52.3649 105.9627,55.5079 105.9627,59.3839 L105.9627,67.6569 L284.2027,67.6569 Z" id="Fill-30" fill="#FCFCFC" mask="url(#mask-2)"></path>
<path d="M284.2027,67.6569 L284.2027,59.3839 C284.2027,55.5079 281.0567,52.3649 277.1747,52.3649 L112.9907,52.3649 C109.1087,52.3649 105.9627,55.5079 105.9627,59.3839 L105.9627,67.6569 L284.2027,67.6569 Z" id="Stroke-31" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M166.857,122.9235 L223.308,122.9235" id="Stroke-32" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M166.857,108.3219 L223.308,108.3219" id="Stroke-33" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M175.9039,138.1164 L214.2609,138.1164" id="Stroke-34" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M18.2418,30.3693 L372.3188,30.3693" id="Stroke-35" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M34.9742,24.3503 L58.0942,24.3503" id="Stroke-36" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M345.0543,24.3503 L361.3743,24.3503" id="Stroke-37" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M322.7125,24.3503 L337.6725,24.3503" id="Stroke-38" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
<path d="M302.9918,24.3503 L315.2318,24.3503" id="Stroke-39" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
_site/assets/posts/image1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
_site/assets/posts/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1006 B

8
_site/assets/posts/logo.svg

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 28.3 28.3" style="enable-background:new 0 0 28.3 28.3;" xml:space="preserve">
<title>logo</title>
<image style="overflow:visible;enable-background:new ;" width="192" height="192" xlink:href="7C04AAA0EE9E3886.png" transform="matrix(0.15 0 0 0.15 0 0)">
</image>
</svg>

After

Width:  |  Height:  |  Size: 547 B

5
_site/assets/posts/old.logo.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" version="1.1" width="34" height="34" style="fill: rgb(0, 0, 0);">
<g id="surface1">
<path style=" " d="M 12 2 C 6.488281 2 2 6.488281 2 12 C 2 17.511719 6.488281 22 12 22 C 17.511719 22 22 17.511719 22 12 C 22 6.488281 17.511719 2 12 2 Z M 12 4 C 16.429688 4 20 7.570313 20 12 C 20 16.429688 16.429688 20 12 20 C 10.445313 20 9.007813 19.542969 7.78125 18.78125 C 8.480469 18.003906 9.222656 17.183594 10.0625 16.34375 C 10.625 15.78125 13.269531 17.605469 15.3125 15.5625 C 16.683594 14.191406 17.308594 11.953125 16.84375 10.09375 L 13.5625 13.40625 C 13.5625 13.40625 12.578125 13.390625 11.59375 12.40625 C 10.609375 11.421875 10.59375 10.4375 10.59375 10.4375 L 13.90625 7.15625 C 12.050781 6.691406 9.808594 7.316406 8.4375 8.6875 C 6.328125 10.796875 8.25 13.3125 7.71875 13.84375 C 6.863281 14.699219 6.027344 15.492188 5.21875 16.21875 C 4.457031 14.992188 4 13.554688 4 12 C 4 7.570313 7.570313 4 12 4 Z "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

41
_site/assets/posts/safe.svg

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="328px" height="294px" viewBox="0 0 328 294" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Safe</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Monochrome-Images" transform="translate(-543.000000, -1599.000000)">
<g id="Safe" transform="translate(518.000000, 1600.000000)">
<path d="M103.4494,290.1996 L69.7464,290.1996 C65.7494,290.1996 62.5084,286.9596 62.5084,282.9616 L62.5084,203.1596 L110.6874,203.1596 L110.6874,282.9616 C110.6874,286.9596 107.4474,290.1996 103.4494,290.1996" id="Fill-1" fill="#FFFFFF"></path>
<path d="M103.4494,290.1996 L69.7464,290.1996 C65.7494,290.1996 62.5084,286.9596 62.5084,282.9616 L62.5084,203.1596 L110.6874,203.1596 L110.6874,282.9616 C110.6874,286.9596 107.4474,290.1996 103.4494,290.1996 Z" id="Stroke-3" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M308.0588,290.1996 L274.3558,290.1996 C270.3588,290.1996 267.1178,286.9596 267.1178,282.9616 L267.1178,203.1596 L315.2968,203.1596 L315.2968,282.9616 C315.2968,286.9596 312.0568,290.1996 308.0588,290.1996" id="Fill-5" fill="#FFFFFF"></path>
<path d="M308.0588,290.1996 L274.3558,290.1996 C270.3588,290.1996 267.1178,286.9596 267.1178,282.9616 L267.1178,203.1596 L315.2968,203.1596 L315.2968,282.9616 C315.2968,286.9596 312.0568,290.1996 308.0588,290.1996 Z" id="Stroke-7" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M342.7751,278.4252 L35.0301,278.4252 C30.7641,278.4252 27.3051,274.8692 27.3051,270.4842 L27.3051,8.9422 C27.3051,4.5552 30.7641,0.9992 35.0301,0.9992 L342.7751,0.9992 C347.0421,0.9992 350.5011,4.5552 350.5011,8.9422 L350.5011,270.4842 C350.5011,274.8692 347.0421,278.4252 342.7751,278.4252" id="Fill-9" fill="#FFFFFF"></path>
<path d="M342.7751,278.4252 L35.0301,278.4252 C30.7641,278.4252 27.3051,274.8692 27.3051,270.4842 L27.3051,8.9422 C27.3051,4.5552 30.7641,0.9992 35.0301,0.9992 L342.7751,0.9992 C347.0421,0.9992 350.5011,4.5552 350.5011,8.9422 L350.5011,270.4842 C350.5011,274.8692 347.0421,278.4252 342.7751,278.4252 Z" id="Stroke-11" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M307.3552,34.1743 L70.4512,34.1743 C66.0642,34.1743 62.5082,37.7313 62.5082,42.1163 L62.5082,237.3083 C62.5082,241.6943 66.0642,245.2503 70.4512,245.2503 L307.3552,245.2503 C311.7412,245.2503 315.2972,241.6943 315.2972,237.3083 L315.2972,42.1163 C315.2972,37.7313 311.7412,34.1743 307.3552,34.1743" id="Fill-13" fill="#EFEFEF"></path>
<path d="M307.3552,34.1743 L70.4512,34.1743 C66.0642,34.1743 62.5082,37.7313 62.5082,42.1163 L62.5082,237.3083 C62.5082,241.6943 66.0642,245.2503 70.4512,245.2503 L307.3552,245.2503 C311.7412,245.2503 315.2972,241.6943 315.2972,237.3083 L315.2972,42.1163 C315.2972,37.7313 311.7412,34.1743 307.3552,34.1743 Z" id="Stroke-15" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M188.9714,224.9204 L188.8344,224.9204 C185.0904,224.9204 182.0554,221.8854 182.0554,218.1414 L182.0554,61.2844 C182.0554,57.5404 185.0904,54.5054 188.8344,54.5054 L188.9714,54.5054 C192.7154,54.5054 195.7504,57.5404 195.7504,61.2844 L195.7504,218.1414 C195.7504,221.8854 192.7154,224.9204 188.9714,224.9204" id="Fill-17" fill="#EFEFEF"></path>
<path d="M188.9714,224.9204 L188.8344,224.9204 C185.0904,224.9204 182.0554,221.8854 182.0554,218.1414 L182.0554,61.2844 C182.0554,57.5404 185.0904,54.5054 188.8344,54.5054 L188.9714,54.5054 C192.7154,54.5054 195.7504,57.5404 195.7504,61.2844 L195.7504,218.1414 C195.7504,221.8854 192.7154,224.9204 188.9714,224.9204 Z" id="Stroke-19" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M274.11,139.644 L274.11,139.781 C274.11,143.525 271.075,146.56 267.331,146.56 L110.474,146.56 C106.731,146.56 103.695,143.525 103.695,139.781 L103.695,139.644 C103.695,135.9 106.731,132.866 110.474,132.866 L267.331,132.866 C271.075,132.866 274.11,135.9 274.11,139.644" id="Fill-21" fill="#EFEFEF"></path>
<path d="M274.11,139.644 L274.11,139.781 C274.11,143.525 271.075,146.56 267.331,146.56 L110.474,146.56 C106.731,146.56 103.695,143.525 103.695,139.781 L103.695,139.644 C103.695,135.9 106.731,132.866 110.474,132.866 L267.331,132.866 C271.075,132.866 274.11,135.9 274.11,139.644 Z" id="Stroke-23" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M249.1052,79.4135 L249.2022,79.5105 C251.8492,82.1575 251.8492,86.4495 249.2022,89.0975 L138.2872,200.0125 C135.6402,202.6585 131.3482,202.6585 128.7002,200.0125 L128.6042,199.9145 C125.9562,197.2675 125.9562,192.9755 128.6042,190.3275 L239.5182,79.4135 C242.1662,76.7665 246.4582,76.7665 249.1052,79.4135" id="Fill-25" fill="#EFEFEF"></path>
<path d="M249.1052,79.4135 L249.2022,79.5105 C251.8492,82.1575 251.8492,86.4495 249.2022,89.0975 L138.2872,200.0125 C135.6402,202.6585 131.3482,202.6585 128.7002,200.0125 L128.6042,199.9145 C125.9562,197.2675 125.9562,192.9755 128.6042,190.3275 L239.5182,79.4135 C242.1662,76.7665 246.4582,76.7665 249.1052,79.4135 Z" id="Stroke-27" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M128.6037,79.5102 L128.7007,79.4132 C131.3477,76.7662 135.6407,76.7662 138.2877,79.4132 L249.2017,190.3272 C251.8497,192.9752 251.8497,197.2682 249.2017,199.9142 L249.1047,200.0122 C246.4577,202.6582 242.1657,202.6582 239.5187,200.0122 L128.6037,89.0972 C125.9567,86.4492 125.9567,82.1572 128.6037,79.5102" id="Fill-29" fill="#EFEFEF"></path>
<path d="M128.6037,79.5102 L128.7007,79.4132 C131.3477,76.7662 135.6407,76.7662 138.2877,79.4132 L249.2017,190.3272 C251.8497,192.9752 251.8497,197.2682 249.2017,199.9142 L249.1047,200.0122 C246.4577,202.6582 242.1657,202.6582 239.5187,200.0122 L128.6037,89.0972 C125.9567,86.4492 125.9567,82.1572 128.6037,79.5102 Z" id="Stroke-31" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M62.4104,162.8325 L62.5084,162.8325 L62.5084,209.0725 L62.4104,209.0725 C57.0534,209.0725 52.7094,204.7295 52.7094,199.3715 L52.7094,172.5335 C52.7094,167.1765 57.0534,162.8325 62.4104,162.8325" id="Fill-33" fill="#EFEFEF"></path>
<path d="M62.4104,162.8325 L62.5084,162.8325 L62.5084,209.0725 L62.4104,209.0725 C57.0534,209.0725 52.7094,204.7295 52.7094,199.3715 L52.7094,172.5335 C52.7094,167.1765 57.0534,162.8325 62.4104,162.8325 Z" id="Stroke-35" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M62.4104,70.353 L62.5084,70.353 L62.5084,116.592 L62.4104,116.592 C57.0534,116.592 52.7094,112.249 52.7094,106.892 L52.7094,80.053 C52.7094,74.696 57.0534,70.353 62.4104,70.353" id="Fill-37" fill="#EFEFEF"></path>
<path d="M62.4104,70.353 L62.5084,70.353 L62.5084,116.592 L62.4104,116.592 C57.0534,116.592 52.7094,112.249 52.7094,106.892 L52.7094,80.053 C52.7094,74.696 57.0534,70.353 62.4104,70.353 Z" id="Stroke-39" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M246.9904,139.7123 C246.9904,171.7933 220.9844,197.8003 188.9034,197.8003 C156.8224,197.8003 130.8154,171.7933 130.8154,139.7123 C130.8154,107.6313 156.8224,81.6243 188.9034,81.6243 C220.9844,81.6243 246.9904,107.6313 246.9904,139.7123" id="Fill-41" fill="#EFEFEF"></path>
<path d="M246.9904,139.7123 C246.9904,171.7933 220.9844,197.8003 188.9034,197.8003 C156.8224,197.8003 130.8154,171.7933 130.8154,139.7123 C130.8154,107.6313 156.8224,81.6243 188.9034,81.6243 C220.9844,81.6243 246.9904,107.6313 246.9904,139.7123 Z" id="Stroke-43" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M227.0441,139.7123 C227.0441,160.7773 209.9671,177.8543 188.9031,177.8543 C167.8381,177.8543 150.7621,160.7773 150.7621,139.7123 C150.7621,118.6483 167.8381,101.5713 188.9031,101.5713 C209.9671,101.5713 227.0441,118.6483 227.0441,139.7123" id="Fill-45" fill="#FFFFFF"></path>
<path d="M227.0441,139.7123 C227.0441,160.7773 209.9671,177.8543 188.9031,177.8543 C167.8381,177.8543 150.7621,160.7773 150.7621,139.7123 C150.7621,118.6483 167.8381,101.5713 188.9031,101.5713 C209.9671,101.5713 227.0441,118.6483 227.0441,139.7123 Z" id="Stroke-47" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M293.3649,139.7123 C293.3649,154.9823 302.3369,168.1543 315.2969,174.2473 L315.2949,105.1783 C302.3369,111.2723 293.3649,124.4443 293.3649,139.7123" id="Fill-49" fill="#FFFFFF"></path>
<path d="M293.3649,139.7123 C293.3649,154.9823 302.3369,168.1543 315.2969,174.2473 L315.2949,105.1783 C302.3369,111.2723 293.3649,124.4443 293.3649,139.7123 Z" id="Stroke-51" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M208.9108,139.7123 C208.9108,150.7623 199.9528,159.7203 188.9028,159.7203 C177.8528,159.7203 168.8948,150.7623 168.8948,139.7123 C168.8948,128.6623 177.8528,119.7043 188.9028,119.7043 C199.9528,119.7043 208.9108,128.6623 208.9108,139.7123" id="Fill-53" fill="#EFEFEF"></path>
<path d="M208.9108,139.7123 C208.9108,150.7623 199.9528,159.7203 188.9028,159.7203 C177.8528,159.7203 168.8948,150.7623 168.8948,139.7123 C168.8948,128.6623 177.8528,119.7043 188.9028,119.7043 C199.9528,119.7043 208.9108,128.6623 208.9108,139.7123 Z" id="Stroke-55" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

113
_site/assets/posts/sky.svg

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="818px" height="275px" viewBox="0 0 818 275" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Style 1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Background-Images" transform="translate(-1803.000000, -398.000000)">
<g id="Style-1" transform="translate(1805.000000, 400.000000)">
<path d="M602.9937,70.2916 L493.2167,70.7126 C484.3287,70.7476 480.4527,59.2536 487.7077,54.1196 C487.8087,54.0476 487.9127,53.9756 488.0147,53.9036 C498.3447,46.7446 511.9387,47.3396 511.9387,47.3396 C511.9387,47.3396 513.7327,8.8196 550.3037,8.6796 C568.3847,8.6096 583.1147,39.4606 583.1147,39.4606 C583.1147,39.4606 607.7107,39.3666 611.8547,58.7706 C613.1097,64.6476 609.0047,70.2686 602.9937,70.2916" id="Fill-1" fill="#FFFFFF"></path>
<path d="M602.9937,70.2916 L493.2167,70.7126 C484.3287,70.7476 480.4527,59.2536 487.7077,54.1196 C487.8087,54.0476 487.9127,53.9756 488.0147,53.9036 C498.3447,46.7446 511.9387,47.3396 511.9387,47.3396 C511.9387,47.3396 513.7327,8.8196 550.3037,8.6796 C568.3847,8.6096 583.1147,39.4606 583.1147,39.4606 C583.1147,39.4606 607.7107,39.3666 611.8547,58.7706 C613.1097,64.6476 609.0047,70.2686 602.9937,70.2916 Z" id="Stroke-3" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M12.2124,153.7398 L159.7364,154.3058 C171.6814,154.3518 176.8894,138.9068 167.1404,132.0068 C167.0034,131.9098 166.8654,131.8128 166.7264,131.7168 C152.8464,122.0948 134.5764,122.8948 134.5764,122.8948 C134.5764,122.8948 132.1654,71.1308 83.0204,70.9418 C58.7224,70.8488 38.9264,112.3068 38.9264,112.3068 C38.9264,112.3068 5.8734,112.1808 0.3044,138.2568 C-1.3836,146.1558 4.1354,153.7088 12.2124,153.7398" id="Fill-5" fill="#FFFFFF"></path>
<path d="M12.2124,153.7398 L159.7364,154.3058 C171.6814,154.3518 176.8894,138.9068 167.1404,132.0068 C167.0034,131.9098 166.8654,131.8128 166.7264,131.7168 C152.8464,122.0948 134.5764,122.8948 134.5764,122.8948 C134.5764,122.8948 132.1654,71.1308 83.0204,70.9418 C58.7224,70.8488 38.9264,112.3068 38.9264,112.3068 C38.9264,112.3068 5.8734,112.1808 0.3044,138.2568 C-1.3836,146.1558 4.1354,153.7088 12.2124,153.7398 Z" id="Stroke-7" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M335.6382,36.2115 L393.7292,35.9885 C398.9212,35.9685 401.1342,29.2365 396.8722,26.2695 C396.8132,26.2275 396.7522,26.1855 396.6922,26.1445 C390.6252,22.0075 382.6852,22.4165 382.6852,22.4165 C382.6852,22.4165 381.4632,-0.0815 360.0962,0.0005 C340.7792,0.0745 333.1482,19.0635 330.4092,29.5195 C329.5202,32.9175 332.1262,36.2255 335.6382,36.2115" id="Fill-9" fill="#FFFFFF"></path>
<path d="M335.6382,36.2115 L393.7292,35.9885 C398.9212,35.9685 401.1342,29.2365 396.8722,26.2695 C396.8132,26.2275 396.7522,26.1855 396.6922,26.1445 C390.6252,22.0075 382.6852,22.4165 382.6852,22.4165 C382.6852,22.4165 381.4632,-0.0815 360.0962,0.0005 C340.7792,0.0745 333.1482,19.0635 330.4092,29.5195 C329.5202,32.9175 332.1262,36.2255 335.6382,36.2115 Z" id="Stroke-11" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M538.5034,89.3248 L710.0794,89.9528 C726.1854,90.0118 725.4944,76.7488 720.2504,72.1088 C714.8764,67.3538 704.2154,69.2358 704.2154,69.2358 C704.2154,69.2358 701.0754,60.3038 690.6504,55.9238 C681.4304,52.0488 671.7484,53.8408 671.7484,53.8408 C671.7484,53.8408 671.7714,47.7198 665.8764,42.6278 C659.9824,37.5368 652.0964,38.0008 652.0964,38.0008 C652.0964,38.0008 646.7994,4.2258 610.5814,4.0938 C574.3634,3.9608 570.0594,35.7288 570.0594,35.7288 C570.0594,35.7288 561.9284,35.6998 555.9944,41.0978 C550.0624,46.4968 549.3004,52.6538 549.3004,52.6538 C549.3004,52.6538 529.5344,49.9158 523.6244,66.9538 C520.1014,77.1078 527.2174,89.2838 538.5034,89.3248" id="Fill-13" fill="#FFFFFF"></path>
<path d="M538.5034,89.3248 L710.0794,89.9528 C726.1854,90.0118 725.4944,76.7488 720.2504,72.1088 C714.8764,67.3538 704.2154,69.2358 704.2154,69.2358 C704.2154,69.2358 701.0754,60.3038 690.6504,55.9238 C681.4304,52.0488 671.7484,53.8408 671.7484,53.8408 C671.7484,53.8408 671.7714,47.7198 665.8764,42.6278 C659.9824,37.5368 652.0964,38.0008 652.0964,38.0008 C652.0964,38.0008 646.7994,4.2258 610.5814,4.0938 C574.3634,3.9608 570.0594,35.7288 570.0594,35.7288 C570.0594,35.7288 561.9284,35.6998 555.9944,41.0978 C550.0624,46.4968 549.3004,52.6538 549.3004,52.6538 C549.3004,52.6538 529.5344,49.9158 523.6244,66.9538 C520.1014,77.1078 527.2174,89.2838 538.5034,89.3248 Z" id="Stroke-15" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<g id="Group-20" transform="translate(235.000000, 84.487000)">
<path d="M0.2407,0.9906 L21.7437,0.9906" id="Fill-17" fill="#FFFFFF"></path>
<path d="M0.2407,0.9906 L21.7437,0.9906" id="Stroke-19" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-24" transform="translate(206.000000, 84.487000)">
<path d="M0.0962,0.9906 L16.8612,0.9906" id="Fill-21" fill="#FFFFFF"></path>
<path d="M0.0962,0.9906 L16.8612,0.9906" id="Stroke-23" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-28" transform="translate(273.000000, 83.487000)">
<path d="M0.2427,0.4906 L7.7427,0.4906" id="Fill-25" fill="#FFFFFF"></path>
<path d="M0.2427,0.4906 L7.7427,0.4906" id="Stroke-27" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<path d="M194.4663,123.6822 C208.3923,123.6282 201.7913,101.5722 184.1693,106.9142 C183.0753,76.2562 133.0113,54.0142 112.5053,95.4482 C106.6453,90.8482 93.5583,99.6302 96.4923,107.2512 C90.0043,107.8282 84.9013,108.5992 80.9323,109.6082 C71.7693,111.9392 73.6303,124.0422 83.0853,123.9212 L194.4663,123.6822 Z" id="Fill-29" fill="#FFFFFF"></path>
<path d="M194.4663,123.6822 C208.3923,123.6282 201.7913,101.5722 184.1693,106.9142 C183.0753,76.2562 133.0113,54.0142 112.5053,95.4482 C106.6453,90.8482 93.5583,99.6302 96.4923,107.2512 C90.0043,107.8282 84.9013,108.5992 80.9323,109.6082 C71.7693,111.9392 73.6303,124.0422 83.0853,123.9212 L194.4663,123.6822 Z" id="Stroke-31" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M381.6294,139.5597 L420.5504,139.5597 C421.9694,139.5597 423.1194,138.4097 423.1194,136.9917 L423.1194,135.1267 C423.1194,133.9037 349.0834,98.2617 336.3534,98.2617 L312.4304,98.2617 C311.0114,98.2617 309.8604,99.4117 309.8604,100.8307 C309.8604,100.8307 310.6914,103.1177 311.8624,103.3827 L380.2604,139.4067 C380.7094,139.5087 381.1694,139.5597 381.6294,139.5597" id="Fill-33" fill="#FFFFFF"></path>
<path d="M381.6294,139.5597 L420.5504,139.5597 C421.9694,139.5597 423.1194,138.4097 423.1194,136.9917 L423.1194,135.1267 C423.1194,133.9037 349.0834,98.2617 336.3534,98.2617 L312.4304,98.2617 C311.0114,98.2617 309.8604,99.4117 309.8604,100.8307 C309.8604,100.8307 310.6914,103.1177 311.8624,103.3827 L380.2604,139.4067 C380.7094,139.5087 381.1694,139.5597 381.6294,139.5597 Z" id="Stroke-35" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M272.0923,138.0753 C272.0923,132.0673 275.8203,128.0033 290.7303,128.0033 L454.0963,128.0033 C490.1673,128.0033 497.7963,136.6553 508.3663,142.7633 C514.2253,146.1503 516.0223,159.4633 491.2843,159.5283 C444.6243,159.6503 346.7633,159.5283 322.0133,159.5283 C304.6153,159.5283 272.0923,150.0753 272.0923,138.0753" id="Fill-37" fill="#FFFFFF"></path>
<path d="M272.0923,138.0753 C272.0923,132.0673 275.8203,128.0033 290.7303,128.0033 L454.0963,128.0033 C490.1673,128.0033 497.7963,136.6553 508.3663,142.7633 C514.2253,146.1503 516.0223,159.4633 491.2843,159.5283 C444.6243,159.6503 346.7633,159.5283 322.0133,159.5283 C304.6153,159.5283 272.0923,150.0753 272.0923,138.0753 Z" id="Stroke-39" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M273.3052,135.5367 L247.3212,112.6207 C247.3212,112.6207 270.0792,109.9217 280.1542,117.0657 L311.0352,135.5367 L273.3052,135.5367 Z" id="Fill-41" fill="#FFFFFF"></path>
<path d="M273.3052,135.5367 L247.3212,112.6207 C247.3212,112.6207 270.0792,109.9217 280.1542,117.0657 L311.0352,135.5367 L273.3052,135.5367 Z" id="Stroke-43" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M381.6294,159.5826 L428.7104,159.5826 C428.7104,160.8056 349.0834,200.8806 336.3534,200.8806 L312.4304,200.8806 C311.0114,200.8806 309.8604,199.7306 309.8604,198.3116 C309.8604,198.3116 310.6914,196.0246 311.8624,195.7596 L380.2604,159.7356 C380.7094,159.6336 381.1694,159.5826 381.6294,159.5826" id="Fill-45" fill="#FFFFFF"></path>
<path d="M381.6294,159.5826 L428.7104,159.5826 C428.7104,160.8056 349.0834,200.8806 336.3534,200.8806 L312.4304,200.8806 C311.0114,200.8806 309.8604,199.7306 309.8604,198.3116 C309.8604,198.3116 310.6914,196.0246 311.8624,195.7596 L380.2604,159.7356 C380.7094,159.6336 381.1694,159.5826 381.6294,159.5826 Z" id="Stroke-47" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M280.8687,146.4806 C280.1687,146.4806 279.4707,146.5586 278.7877,146.7126 L261.4267,157.2356 C260.7217,157.3956 260.2207,158.0226 260.2207,158.7456 L260.2207,158.7736 C260.2207,159.6286 260.9137,160.3216 261.7677,160.3216 L272.1857,160.3216 C276.1937,160.3216 306.6537,146.4806 304.8377,146.4806 L280.8687,146.4806 Z" id="Fill-49" fill="#FFFFFF"></path>
<path d="M280.8687,146.4806 C280.1687,146.4806 279.4707,146.5586 278.7877,146.7126 L261.4267,157.2356 C260.7217,157.3956 260.2207,158.0226 260.2207,158.7456 L260.2207,158.7736 C260.2207,159.6286 260.9137,160.3216 261.7677,160.3216 L272.1857,160.3216 C276.1937,160.3216 306.6537,146.4806 304.8377,146.4806 L280.8687,146.4806 Z" id="Stroke-51" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<g id="Group-56" transform="translate(318.000000, 148.487000)">
<path d="M0.2681,0.3109 L48.6581,0.3109" id="Fill-53" fill="#FFFFFF"></path>
<path d="M0.2681,0.3109 L48.6581,0.3109" id="Stroke-55" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-60" transform="translate(380.000000, 148.487000)">
<path d="M0.3218,0.3109 L48.7108,0.3109" id="Fill-57" fill="#FFFFFF"></path>
<path d="M0.3218,0.3109 L48.7108,0.3109" id="Stroke-59" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-64" transform="translate(441.000000, 148.487000)">
<path d="M0.7788,0.3109 L49.1678,0.3109" id="Fill-61" fill="#FFFFFF"></path>
<path d="M0.7788,0.3109 L49.1678,0.3109" id="Stroke-63" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-68" transform="translate(500.000000, 148.487000)">
<path d="M0.2524,0.3109 L9.3524,0.3109" id="Fill-65" fill="#FFFFFF"></path>
<path d="M0.2524,0.3109 L9.3524,0.3109" id="Stroke-67" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<path d="M339.3218,270.1485 C319.7088,270.0735 329.0058,239.0095 353.8228,246.5335 C355.3628,203.3575 425.8698,172.0335 454.7488,230.3865 C463.0028,223.9065 481.4328,236.2755 477.2998,247.0075 C486.4368,247.8215 493.6248,248.9065 499.2138,250.3285 C512.1188,253.6105 509.4968,270.6565 496.1808,270.4855 L339.3218,270.1485 Z" id="Fill-69" fill="#FFFFFF"></path>
<path d="M339.3218,270.1485 C319.7088,270.0735 329.0058,239.0095 353.8228,246.5335 C355.3628,203.3575 425.8698,172.0335 454.7488,230.3865 C463.0028,223.9065 481.4328,236.2755 477.2998,247.0075 C486.4368,247.8215 493.6248,248.9065 499.2138,250.3285 C512.1188,253.6105 509.4968,270.6565 496.1808,270.4855 L339.3218,270.1485 Z" id="Stroke-71" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M746.4214,197.7638 L808.0964,198.0008 C813.0894,198.0198 815.2674,191.5628 811.1914,188.6778 C811.1344,188.6378 811.0764,188.5968 811.0184,188.5568 C805.2154,184.5348 797.5774,184.8688 797.5774,184.8688 C797.5774,184.8688 796.5694,163.2278 776.0244,163.1488 C765.8654,163.1098 757.5904,180.4428 757.5904,180.4428 C757.5904,180.4428 743.7724,180.3888 741.4434,191.2908 C740.7374,194.5928 743.0454,197.7508 746.4214,197.7638" id="Fill-73" fill="#FFFFFF"></path>
<path d="M746.4214,197.7638 L808.0964,198.0008 C813.0894,198.0198 815.2674,191.5628 811.1914,188.6778 C811.1344,188.6378 811.0764,188.5968 811.0184,188.5568 C805.2154,184.5348 797.5774,184.8688 797.5774,184.8688 C797.5774,184.8688 796.5694,163.2278 776.0244,163.1488 C765.8654,163.1098 757.5904,180.4428 757.5904,180.4428 C757.5904,180.4428 743.7724,180.3888 741.4434,191.2908 C740.7374,194.5928 743.0454,197.7508 746.4214,197.7638 Z" id="Stroke-75" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<g id="Group-80" transform="translate(583.000000, 249.487000)">
<path d="M0.3628,0.5136 L31.1238,0.5136" id="Fill-77" fill="#FFFFFF"></path>
<path d="M0.3628,0.5136 L31.1238,0.5136" id="Stroke-79" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-84" transform="translate(541.000000, 249.487000)">
<path d="M0.0962,0.5136 L19.8642,0.5136" id="Fill-81" fill="#FFFFFF"></path>
<path d="M0.0962,0.5136 L19.8642,0.5136" id="Stroke-83" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-88" transform="translate(627.000000, 249.487000)">
<path d="M0.0962,0.5136 L16.2212,0.5136" id="Fill-85" fill="#FFFFFF"></path>
<path d="M0.0962,0.5136 L16.2212,0.5136" id="Stroke-87" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-92" transform="translate(144.000000, 180.487000)">
<path d="M0.0962,0.5136 L29.0962,0.5136" id="Fill-89" fill="#FFFFFF"></path>
<path d="M0.0962,0.5136 L29.0962,0.5136" id="Stroke-91" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-96" transform="translate(267.000000, 202.487000)">
<path d="M0.4565,0.5136 L17.0965,0.5136" id="Fill-93" fill="#FFFFFF"></path>
<path d="M0.4565,0.5136 L17.0965,0.5136" id="Stroke-95" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-100" transform="translate(206.000000, 202.487000)">
<path d="M0.0962,0.5136 L26.8832,0.5136" id="Fill-97" fill="#FFFFFF"></path>
<path d="M0.0962,0.5136 L26.8832,0.5136" id="Stroke-99" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-104" transform="translate(421.000000, 84.487000)">
<path d="M0.2876,0.5136 L41.0966,0.5136" id="Fill-101" fill="#FFFFFF"></path>
<path d="M0.2876,0.5136 L41.0966,0.5136" id="Stroke-103" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-108" transform="translate(372.000000, 84.487000)">
<path d="M0.0962,0.5136 L7.0902,0.5136" id="Fill-105" fill="#FFFFFF"></path>
<path d="M0.0962,0.5136 L7.0902,0.5136" id="Stroke-107" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-112" transform="translate(387.000000, 63.487000)">
<path d="M0.4292,0.5136 L29.1652,0.5136" id="Fill-109" fill="#FFFFFF"></path>
<path d="M0.4292,0.5136 L29.1652,0.5136" id="Stroke-111" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-116" transform="translate(510.000000, 231.487000)">
<path d="M0.0962,0.5136 L54.0962,0.5136" id="Fill-113" fill="#FFFFFF"></path>
<path d="M0.0962,0.5136 L54.0962,0.5136" id="Stroke-115" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-120" transform="translate(649.000000, 104.487000)">
<path d="M0.396,0.8466 L43.096,0.8466" id="Fill-117" fill="#FFFFFF"></path>
<path d="M0.396,0.8466 L43.096,0.8466" id="Stroke-119" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<g id="Group-124" transform="translate(608.000000, 104.487000)">
<path d="M0.0962,0.8466 L18.8312,0.8466" id="Fill-121" fill="#FFFFFF"></path>
<path d="M0.0962,0.8466 L18.8312,0.8466" id="Stroke-123" stroke="#E1E4E5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

BIN
_site/assets/posts/slideshow-1/image1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

26
_site/assets/posts/teacup.svg

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="323px" height="254px" viewBox="0 0 323 254" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Teacup</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Monochrome-Images" transform="translate(-559.000000, -471.000000)">
<g id="Teacup" transform="translate(534.000000, 473.000000)">
<path d="M291.485,135.8834 C291.485,135.8834 324.465,118.5954 340.24,139.5744 C352.268,155.5704 344.531,182.8044 319.643,194.6874 C294.755,206.5704 253.094,206.5354 253.094,206.5354 L267.153,191.7674 C286.754,189.8384 294.486,190.9034 315.352,180.2784 C333.905,170.8294 335.09,144.1234 315.352,144.1234 C295.612,144.1234 283.033,163.1034 283.033,163.1034 L291.485,135.8834 Z" id="Fill-1" fill="#EFEFEF"></path>
<path d="M291.485,135.8834 C291.485,135.8834 324.465,118.5954 340.24,139.5744 C352.268,155.5704 344.531,182.8044 319.643,194.6874 C294.755,206.5704 253.094,206.5354 253.094,206.5354 L267.153,191.7674 C286.754,189.8384 294.486,190.9034 315.352,180.2784 C333.905,170.8294 335.09,144.1234 315.352,144.1234 C295.612,144.1234 283.033,163.1034 283.033,163.1034 L291.485,135.8834 Z" id="Stroke-3" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M210.0553,242.6613 C270.8153,221.2793 302.9093,149.9703 302.9093,97.8473 L27.6833,97.8473 C27.6833,153.9463 58.6373,221.2793 117.0073,242.6613 L210.0553,242.6613 Z" id="Fill-5" fill="#F4F4F4"></path>
<path d="M29.5294,98.818 C30.8394,107.625 32.8334,116.503 35.5284,125.257 C52.8534,181.519 105.5114,219.428 164.3804,219.428 L165.3104,219.428 C220.4774,219.428 270.4724,186.062 290.7444,134.755 C295.4664,122.806 298.8204,110.617 300.7974,98.818 L29.5294,98.818 Z" id="Fill-7" fill="#FCFCFC"></path>
<path d="M210.0553,242.6613 C270.8153,221.2793 302.9093,149.9703 302.9093,97.8473 L27.6833,97.8473 C27.6833,153.9463 58.6373,221.2793 117.0073,242.6613 L210.0553,242.6613 Z" id="Stroke-9" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M168.1529,-0.0004 C168.1529,-0.0004 152.7089,20.8736 168.1529,46.9666 C183.5969,73.0596 168.1529,87.8746 168.1529,87.8746" id="Stroke-11" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M143.088,19.0236 C138.998,43.9376 154.949,49.0656 156.091,63.2876" id="Stroke-13" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M188.0987,49.066 C199.7947,68.827 188.0987,80.047 188.0987,80.047" id="Stroke-15" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M56.087,239.2599 L56.772,239.4399 C81.46,245.9269 106.879,249.2099 132.405,249.2099 L195.085,249.2099 C220.937,249.2099 246.678,245.8419 271.66,239.1909 L272.336,239.0109 C275.905,238.0599 275.096,232.7809 271.406,232.9489 C248.377,233.9969 212.717,235.1319 166.306,235.1319 C119.204,235.1319 81.525,233.9629 57.038,232.9029 C53.169,232.7349 52.341,238.2759 56.087,239.2599" id="Fill-17" fill="#EFEFEF"></path>
<path d="M56.087,239.2599 L56.772,239.4399 C81.46,245.9269 106.879,249.2099 132.405,249.2099 L195.085,249.2099 C220.937,249.2099 246.678,245.8419 271.66,239.1909 L272.336,239.0109 C275.905,238.0599 275.096,232.7809 271.406,232.9489 C248.377,233.9969 212.717,235.1319 166.306,235.1319 C119.204,235.1319 81.525,233.9629 57.038,232.9029 C53.169,232.7349 52.341,238.2759 56.087,239.2599 Z" id="Stroke-19" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M78.2608,184.0372 L78.2538,147.7302 C78.2538,146.7762 78.5048,145.8402 78.9808,145.0152 L88.8328,127.9512 C89.8028,126.2722 91.5938,125.2372 93.5338,125.2372 L111.5578,125.2372 C113.4968,125.2372 115.2888,126.2722 116.2588,127.9512 L126.1108,145.0152 C126.5868,145.8402 126.8378,146.7762 126.8378,147.7292 L126.8378,184.0362 C126.8378,187.0342 124.4068,189.4642 121.4098,189.4642 L83.6888,189.4642 C80.6918,189.4642 78.2608,187.0352 78.2608,184.0372" id="Fill-21" fill="#EFEFEF"></path>
<path d="M78.2608,184.0372 L78.2538,147.7302 C78.2538,146.7762 78.5048,145.8402 78.9808,145.0152 L88.8328,127.9512 C89.8028,126.2722 91.5938,125.2372 93.5338,125.2372 L111.5578,125.2372 C113.4968,125.2372 115.2888,126.2722 116.2588,127.9512 L126.1108,145.0152 C126.5868,145.8402 126.8378,146.7762 126.8378,147.7292 L126.8378,184.0362 C126.8378,187.0342 124.4068,189.4642 121.4098,189.4642 L83.6888,189.4642 C80.6918,189.4642 78.2608,187.0352 78.2608,184.0372 Z" id="Stroke-23" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M102.5455,133.942 L102.5455,97.847 C102.5455,95.067 104.7995,92.812 107.5805,92.812 L108.7415,92.812 C111.4945,92.812 113.7265,95.044 113.7265,97.797 L113.7265,97.847" id="Stroke-25" stroke="#CECECE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
_site/assets/posts/touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

1
_site/assets/posts/touch-icon.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

350
_site/changelog/index.html

@ -0,0 +1,350 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Changelog | Blockstack</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="Changelog" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Docs" />
<meta property="og:description" content="Docs" />
<link rel="canonical" href="http://localhost:4000/changelog/" />
<meta property="og:url" content="http://localhost:4000/changelog/" />
<meta property="og:site_name" content="Blockstack" />
<script type="application/ld+json">
{"description":"Docs","author":{"@type":"Person","name":"Blockstack"},"@type":"WebPage","url":"http://localhost:4000/changelog/","headline":"Changelog","@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container uk-container-xsmall">
<article class="uk-article">
<h1 class="uk-article-title">Changelog</h1>
<div class="article-content">
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>
</div>
<div class="tm-timeline uk-margin-large-top">
<div class="tm-timeline-entry">
<div class="tm-timeline-time">
<h5>Oct 21, 2017</h5>
</div>
<div class="tm-timeline-body">
<h3>Version 1.0.0 <span class="uk-label">STABLE</span></h3>
<ul class="uk-list">
<li>Added Slideshow component</li>
<li>Added style support for radio and minusbox in Firefox</li>
<li>Removed class from Section component</li>
<li>Allow fullscreen mode for videos in Lightbox</li>
<li>Fixed responsive images in modal for IE11</li>
<li>Fix Grid and Margin component for cells with no height</li>
<li>Larger horizontal padding for form input and textarea</li>
</ul>
</div>
</div>
<div class="tm-timeline-entry">
<div class="tm-timeline-time">
<h5>Sep 01, 2017</h5>
</div>
<div class="tm-timeline-body">
<h3>Version 1.0.0 <span class="uk-label">BETA 1</span></h3>
<ul class="uk-list">
<li>Allow fullscreen mode for YouTube videos in Lightbox</li>
<li>Fix icons not displaying if connected in rapid succession</li>
<li>Fix scrollbar jumping in Switcher</li>
</ul>
</div>
</div>
<div class="tm-timeline-entry">
<div class="tm-timeline-time">
<h5>Aug 15, 2017</h5>
</div>
<div class="tm-timeline-body">
<h3>Version 0.6.0 <span class="uk-label"></span></h3>
<ul class="uk-list">
<li>Added style support for radio and checkbox in Firefox</li>
<li>Removed class from Section component</li>
<li>Add workaround to mitigate the duplicating icons issue</li>
<li>Fixed responsive images in modal for IE11</li>
</ul>
</div>
</div>
<div class="tm-timeline-entry">
<div class="tm-timeline-time">
<h5>Oct 21, 2017</h5>
</div>
<div class="tm-timeline-body">
<h3>Version 0.5.0 <span class="uk-label"></span></h3>
<ul class="uk-list">
<li>Media options now support any valid media query syntax</li>
<li>Added style support for radio and checkbox in Firefox</li>
<li>Fix whitespace trimming in dist</li>
</ul>
</div>
</div>
</div>
</article>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>

17
_site/collections.json

@ -0,0 +1,17 @@
{
"version": "THEVERSION",
"collections": [
{
"name": "core",
"repo": "https://github.com/blockstack/blockstack-core"
},
{
"name": "android",
"repo": "https://github.com/moxiegirl/blockstack-android"
},
{
"name": "browser",
"repo": "https://github.com/blockstack/blockstack-browser"
}
]
}

344
_site/contact/index.html

@ -0,0 +1,344 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Got Any Questions | Blockstack</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="Got Any Questions" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Docs" />
<meta property="og:description" content="Docs" />
<link rel="canonical" href="http://localhost:4000/contact/" />
<meta property="og:url" content="http://localhost:4000/contact/" />
<meta property="og:site_name" content="Blockstack" />
<script type="application/ld+json">
{"description":"Docs","author":{"@type":"Person","name":"Blockstack"},"@type":"WebPage","url":"http://localhost:4000/contact/","headline":"Got Any Questions","@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container uk-container-xsmall">
<article class="uk-article">
<h1 class="uk-article-title">Got Any Questions</h1>
<div class="article-content">
<h5 id="morbi-varius-in-accumsan-blandit-elit-ligula-velit-luctus-mattis-ante-nulla-nulla">Morbi varius in accumsan blandit, elit ligula velit, luctus mattis ante nulla nulla.</h5>
<p>Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
<div id="map" class="uk-width-1-1 uk-height-large uk-margin-medium-top uk-margin-medium-bottom"></div>
<script>
window.mapData = {"latitude": 40.6700,"longitude": -73.9400, "zoom": 16};
var lightStyles = [{"featureType":"water","elementType":"geometry","stylers":[{"color":"#e9e9e9"},{"lightness":17}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffffff"},{"lightness":17}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#ffffff"},{"lightness":29},{"weight":0.2}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":18}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":16}]},{"featureType":"poi","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":21}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#dedede"},{"lightness":21}]},{"elementType":"labels.text.stroke","stylers":[{"visibility":"on"},{"color":"#ffffff"},{"lightness":16}]},{"elementType":"labels.text.fill","stylers":[{"saturation":36},{"color":"#333333"},{"lightness":40}]},{"elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#f2f2f2"},{"lightness":19}]},{"featureType":"administrative","elementType":"geometry.fill","stylers":[{"color":"#fefefe"},{"lightness":20}]},{"featureType":"administrative","elementType":"geometry.stroke","stylers":[{"color":"#fefefe"},{"lightness":17},{"weight":1.2}]}]
function initMap() {
var myOptions = {
scrollwheel: false,
//draggable: false,
panControl: false,
disableDefaultUI: true,
zoom: window.mapData.zoom,
maxZoom: window.mapData.zoom,
minZoom: window.mapData.zoom,
center: new google.maps.LatLng(window.mapData.latitude, window.mapData.longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: lightStyles
};
var map = new google.maps.Map(document.getElementById('map'), myOptions);
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(window.mapData.latitude, window.mapData.longitude),
icon: {
url: "/assets/img/location.svg",
size: new google.maps.Size(28, 38),
scaledSize: new google.maps.Size(28, 38)
}
});
google.maps.event.addDomListener(window, 'resize', function() {
map.setCenter(myOptions.center);
});
}
</script>
<script async="" defer="" src="https://maps.googleapis.com/maps/api/js?key=&amp;callback=initMap"></script>
</div>
</article>
<h3 class="uk-margin-medium-top">Contact Form</h3>
<form class="uk-form-stacked uk-margin-medium-top" method="POST" action="https://formspree.io/my_name@gmail.com" accept-charset="UTF-8">
<div class="uk-margin-medium-bottom">
<label class="uk-form-label uk-margin-small-bottom" for="form-stacked-text">Name</label>
<div class="uk-form-controls">
<input class="uk-input uk-form-large uk-border-rounded" name="name" type="text" required>
</div>
</div>
<div class="uk-margin-medium-bottom">
<label class="uk-form-label uk-margin-small-bottom" for="form-stacked-text">Email</label>
<div class="uk-form-controls">
<input class="uk-input uk-form-large uk-border-rounded" name="_replyto" type="email" required>
</div>
</div>
<div class="uk-margin-medium-bottom">
<label class="uk-form-label uk-margin-small-bottom" for="form-stacked-text">Subject</label>
<div class="uk-form-controls">
<input class="uk-input uk-form-large uk-border-rounded" name="_subject" type="text">
</div>
</div>
<div class="uk-margin-medium-bottom">
<label class="uk-form-label uk-margin-small-bottom" for="form-stacked-text">Message</label>
<div class="uk-form-controls">
<textarea class="uk-textarea uk-form-large" name="message" rows="5" minlength="10" required></textarea>
</div>
</div>
<div>
<input type="hidden" name="_next" value="http://localhost:4000/thanks/">
<input type="text" name="_gotcha" style="display:none">
<input class="uk-button uk-button-primary uk-button-large uk-width-1-1 uk-border-rounded" type="submit" value="Send">
</div>
</form>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>

36
_site/core/README.md

@ -0,0 +1,36 @@
# Documentation
All Blockstack software documentation is either in this directory, or linked
from this file.
## FAQs
* [General FAQ](https://blockstack.org/faq)
* [Technical FAQ](faq_technical.md)
## System Design and Implementation
* [Blockstack Naming Service](blockstack_naming_service.md) (start here)
* [Atlas Peer Network](atlas_network.md)
* [Gaia Storage System](https://github.com/blockstack/gaia)
* [Transaction Formats](wire-format.md)
* [Glossary](glossary.md)
## Command-line Documentation
* [CLI walkthrough](basic_usage.md)
* [CLI reference](cli.md)
## Developer Documentation
* [blockstack.js](https://github.com/blockstack/blockstack.js)
* [Blockstack Browser](https://github.com/blockstack/blockstack-browser)
* [Blockstack Core API](https://core.blockstack.org)
* [Integration Test Framework](../integration_tests/README.md)
## Advanced Topics
* [How to Create a Namespace](namespace_creation.md)
* [How to link your OpenBazaar Store to your Blockstack ID](openbazaar.md)
* [How to build a Profile Search Index](search.md)
* [How to Run a Blockstack Subdomain Registrar](subdomains.md)

4
_site/core/advanced_usage.md

@ -0,0 +1,4 @@
# Advanced Usage
This document is deprecated, and contains references to commands that are no
longer valid. It has been moved to the [attic](attic/advanced_usage.md).

36
_site/core/aglio_templates/core.jade

@ -0,0 +1,36 @@
doctype
include mixins.jade
html
head
meta(charset="utf-8")
title= self.api.name || 'API Documentation'
link(rel="stylesheet", href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css")
style!= self.css
body.preload
#nav-background
div.container-fluid.triple
.row
block nav
+Nav(false)
.content
#right-panel-background
block content
+ContentTriple(false)
.middle
p.text-muted(style="text-align: center;")
script: include scripts.js
if self.livePreview
script(src="/socket.io/socket.io.js")
script.
var socket = io();
socket.on('refresh', refresh);
socket.on('reconnect', function () {
socket.emit('request-refresh');
});

357
_site/core/aglio_templates/mixins.jade

@ -0,0 +1,357 @@
mixin TryMe(action)
//- Give a "try-me" link for the public api endpoint
- var myUri = action.uriTemplate
- action.parameters.forEach( function (x) { myUri = myUri.replace( "{" + x.name + "}", x.example) } )
.title
strong
h4
div
div
span.method(class="badge get",style="float:left")
a.method(href=myUri, style="color:rgb(51, 122, 183);font-size:12pt")
= "Try It!"
| &nbsp;
p
div
| &nbsp;
mixin Badge(method)
//- Draw a badge for a given HTTP method
case method
when 'GET'
span.badge.get: i.fa.fa-arrow-down
when 'HEAD'
span.badge.head: i.fa.fa-info-circle
when 'OPTIONS'
span.badge.options: i.fa.fa-dot-circle-o
when 'POST'
span.badge.post: i.fa.fa-plus
when 'PUT'
span.badge.put: i.fa.fa-pencil
when 'PATCH'
span.badge.patch: i.fa.fa-pencil
when 'DELETE'
span.badge.delete: i.fa.fa-times
default
span.badge: i.fa.fa-dot-circle-o
mixin Nav(onlyPublic)
//- Draw a navigation bar, which includes links to individual
//- resources and actions.
nav
if self.api.navItems && self.api.navItems.length
.resource-group
.heading
.chevron
i.open.fa.fa-angle-down
a(href='#top') Overview
.collapse-content
ul: each item in self.api.navItems
li
a(href=item[1])!= item[0]
- if (onlyPublic){
- myGroups = self.api.resourceGroups.filter( filter_public_resourcegroups )
- }else{
- myGroups = self.api.resourceGroups.filter( filter_core_resourcegroups )
- }
each resourceGroup in myGroups || []
.resource-group
.heading
.chevron
i.open.fa.fa-angle-down
a(href=resourceGroup.elementLink)!= resourceGroup.name || 'Resource Group'
.collapse-content
ul
each item in resourceGroup.navItems || []
li
a(href=item[1])!= item[0]
- if (onlyPublic){
- myResources = resourceGroup.resources.filter( filter_public_resources )
- }else{
- myResources = resourceGroup.resources.filter( filter_core_resources )
- }
each resource in myResources || []
li
- if (onlyPublic){
- myActions = resource.actions.filter( filter_public_actions )
- }else{
- myActions = resource.actions.filter( filter_core_actions )
- }
if !self.condenseNav || (myActions.length != 1)
a(href=resource.elementLink)!= resource.name || 'Resource'
ul: each action in myActions || []
li: a(href=resource.elementLink)
+Badge(action.method)
!= action.name || action.method + ' ' + (action.attributes && action.attributes.uriTemplate || resource.uriTemplate)
else
- var action = myActions[0]
a(href=resource.elementLink)
+Badge(action.method)
!= action.name || resource.name || action.method + ' ' + (action.attributes && action.attributes.uriTemplate || resource.uriTemplate)
//- Link to the API hostname, e.g. api.yourcompany.com
each meta in self.api.metadata || {}
if meta.name == 'HOST'
p(style="text-align: center; word-wrap: break-word;")
a(href=meta.value)= meta.value
mixin Parameters(params)
//- Draw a definition list of parameter names, types, defaults,
//- examples and descriptions.
.title
strong URI Parameters
.collapse-button.show
span.close Hide
span.open Show
.collapse-content
dl.inner: each param in params || []
dt= self.urldec(param.name)
dd
code= param.type || 'string'
| &nbsp;
if param.required
span.required (required)
else
span (optional)
| &nbsp;
if param.default
span.text-info.default
strong Default:&nbsp;
span= param.default
| &nbsp;
if param.example
span.text-muted.example
strong Example:&nbsp;
span= param.example
!= self.markdown(param.description)
if param.values.length
p.choices
strong Choices:&nbsp;
each value in param.values
code= self.urldec(value.value)
= ' '
mixin RequestResponse(title, request, collapse)
.title
strong
= title
if request.name
| &nbsp;&nbsp;
code= request.name
if collapse && request.hasContent
.collapse-button
span.close Hide
span.open Show
+RequestResponseBody(request, collapse)
mixin RequestResponseBody(request, collapse, showBlank)
if request.hasContent || showBlank
div(class=collapse ? 'collapse-content' : ''): .inner
if request.description
.description!= self.markdown(request.description)
if Object.keys(request.headers).length
h5 Headers
pre: code
each item, index in request.headers
!= self.highlight(item.name + ': ' + item.value, 'http')
if index < request.headers.length - 1
br
div(style="height: 1px;")
if request.body
h5 Body
pre: code
!= self.highlight(request.body, null, ['json', 'yaml', 'xml', 'javascript'])
div(style="height: 1px;")
if request.schema
h5 Schema
pre: code
!= self.highlight(request.schema, null, ['json', 'yaml', 'xml'])
div(style="height: 1px;")
if !request.hasContent
.description.text-muted This response has no content.
div(style="height: 1px;")
mixin Examples(resourceGroup, resource, action)
each example in action.examples
each request in example.requests
+RequestResponse('Request', request, true)
each response in example.responses
+RequestResponse('Response', response, true)
mixin Content()
//- Page header and API description
header
h1#top!= self.api.name || 'API Documentation'
if self.api.descriptionHtml
!= self.api.descriptionHtml
//- Loop through and display information about all the resource
//- groups, resources, and actions.
each resourceGroup in self.api.resourceGroups || []
section.resource-group(id=resourceGroup.elementId)
h2.group-heading
!= resourceGroup.name || 'Resource Group'
= " "
a.permalink(href=resourceGroup.elementLink) &para;
if resourceGroup.descriptionHtml
!= resourceGroup.descriptionHtml
each resource in resourceGroup.resources || []
.resource(id=resource.elementId)
h3.resource-heading
!= resource.name || ((resource.actions[0] != null) && resource.actions[0].name) || 'Resource'
= " "
a.permalink(href=resource.elementLink) &nbsp;&para;
if resource.description
!= self.markdown(resource.description)
each action in resource.actions || []
.action(class=action.methodLower, id=action.elementId)
h4.action-heading
.name!= action.name
a.method(class=action.methodLower, href=action.elementLink)
= action.method
code.uri= self.urldec(action.uriTemplate)
if action.description
!= self.markdown(action.description)
h4 Example URI
.definition
span.method(class=action.methodLower)= action.method
| &nbsp;
span.uri
span.hostname= self.api.host
!= action.colorizedUriTemplate
//- A list of sub-sections for parameters, requests
//- and responses.
if action.parameters.length
+Parameters(action.parameters)
if action.examples
+Examples(resourceGroup, resource, action)
- function filter_public_actions(x){
- return (x.description.includes('+ Public Endpoint') || x.description.includes('+ Public Only Endpoint'))
- }
- function filter_public_resources(x){
- return (x.actions.filter( filter_public_actions ).length > 0)
- }
- function filter_public_resourcegroups(x){
- return (x.resources.filter( filter_public_resources ).length > 0)
- }
- function filter_core_actions(x){
- return !(x.description.includes('+ Public Only Endpoint'))
- }
- function filter_core_resources(x){
- return (x.actions.filter( filter_core_actions ).length > 0)
- }
- function filter_core_resourcegroups(x){
- return (x.resources.filter( filter_core_resources ).length > 0)
- }
mixin ContentTriple(onlyPublic, descriptionHtml)
.right
h5 API Endpoint
a(href=self.api.host)= self.api.host
.middle
if descriptionHtml
!= descriptionHtml
//- Loop through and display information about all the resource
//- groups, resources, and actions.
- if (onlyPublic){
- myGroups = self.api.resourceGroups.filter( filter_public_resourcegroups )
- }else{
- myGroups = self.api.resourceGroups.filter( filter_core_resourcegroups )
- }
each resourceGroup in myGroups || []
.middle
section.resource-group(id=resourceGroup.elementId)
h2.group-heading
!= resourceGroup.name || 'Resource Group'
= " "
a.permalink(href=resourceGroup.elementLink) &para;
if resourceGroup.descriptionHtml
!= resourceGroup.descriptionHtml
- if (onlyPublic){
- myResources = resourceGroup.resources.filter( filter_public_resources )
- }else{
- myResources = resourceGroup.resources.filter( filter_core_resources )
- }
each resource in myResources || []
if resource.public != null
.middle
.resource(id=resource.elementId)
a.permalink(href=resource.elementLink)
h3.resource-heading
!= resource.name || ((resource.actions[0] != null) && resource.actions[0].name) || 'Resource'
= " "
&para;
if resource.description
!= self.markdown(resource.description)
- if (onlyPublic){
- myActions = resource.actions.filter( filter_public_actions )
- }else{
- myActions = resource.actions.filter( filter_core_actions )
- }
each action in myActions || []
if action.examples
.right
.definition
span.method(class=action.methodLower)= action.method
| &nbsp;
span.uri
span.hostname= self.api.host
!= action.colorizedUriTemplate
.tabs
if action.hasRequest
.example-names
span Requests
- var requestCount = 0
each example in action.examples
each request in example.requests
- requestCount++
span.tab-button= request.name || 'example ' + requestCount
each example in action.examples
each request in example.requests
.tab
+RequestResponseBody(request, false, true)
.tabs
.example-names
span Responses
each response in example.responses
span.tab-button= response.name
each response in example.responses
.tab
+RequestResponseBody(response, false, true)
else
each example in action.examples
.tabs
.example-names
span Responses
each response in example.responses
span.tab-button= response.name
each response in example.responses
.tab
+RequestResponseBody(response, false, true)
.middle
.action(class=action.methodLower, id=action.elementId)
h4.action-heading
.name!= action.name
a.method(class=action.methodLower, href=action.elementLink)
= action.method
code.uri= self.urldec(action.uriTemplate)
if action.description
!= self.markdown(action.description)
//- A list of sub-sections for parameters, requests
//- and responses.
if action.parameters.length
+Parameters(action.parameters)
if onlyPublic
+TryMe(action)
hr.split

53
_site/core/aglio_templates/public.jade

@ -0,0 +1,53 @@
doctype
include mixins.jade
html
head
meta(charset="utf-8")
title= 'Blockstack Core'
link(rel="stylesheet", href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css")
style!= self.css
body.preload
#nav-background
div.container-fluid.triple
.row
block nav
+Nav(true)
.content
#right-panel-background
.middle
header
h1#top!= 'Getting Started'
p!= 'Welcome to this deployment of Blockstack Core v{{server_info.server_version}}. You can read the documentation and make RESTful calls to this node.'
p
table
tr
td!= 'Consensus hash'
td!= '{{server_info.consensus}}'
tr
td!= 'Last block seen'
td!= '{{server_info.last_block_seen}}'
tr
td!= 'Last block processed'
td!= '{{server_info.last_block_processed}}'
p!= 'Blockstack Core is open-source software released under a GPLv3 license. The code for this API is <a href="https://github.com/blockstack/blockstack-core/tree/master/api">available on Github</a> and you can deploy your own nodes by following <a href="https://github.com/blockstack/blockstack-core/tree/master/api">these instructions</a>.'
block content
+ContentTriple(true)
.middle
p.text-muted(style="text-align: center;")
script: include scripts.js
if self.livePreview
script(src="/socket.io/socket.io.js")
script.
var socket = io();
socket.on('refresh', refresh);
socket.on('reconnect', function () {
socket.emit('request-refresh');
});

223
_site/core/aglio_templates/scripts.js

@ -0,0 +1,223 @@
/* eslint-env browser */
/* eslint quotes: [2, "single"] */
'use strict';
/*
Determine if a string ends with another string.
*/
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
/*
Get a list of direct child elements by class name.
*/
function childrenByClass(element, name) {
var filtered = [];
for (var i = 0; i < element.children.length; i++) {
var child = element.children[i];
var classNames = child.className.split(' ');
if (classNames.indexOf(name) !== -1) {
filtered.push(child);
}
}
return filtered;
}
/*
Get an array [width, height] of the window.
*/
function getWindowDimensions() {
var w = window,
d = document,
e = d.documentElement,
g = d.body,
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
return [x, y];
}
/*
Collapse or show a request/response example.
*/
function toggleCollapseButton(event) {
var button = event.target.parentNode;
var content = button.parentNode.nextSibling;
var inner = content.children[0];
if (button.className.indexOf('collapse-button') === -1) {
// Clicked without hitting the right element?
return;
}
if (content.style.maxHeight && content.style.maxHeight !== '0px') {
// Currently showing, so let's hide it
button.className = 'collapse-button';
content.style.maxHeight = '0px';
} else {
// Currently hidden, so let's show it
button.className = 'collapse-button show';
content.style.maxHeight = inner.offsetHeight + 12 + 'px';
}
}
function toggleTabButton(event) {
var i, index;
var button = event.target;
// Get index of the current button.
var buttons = childrenByClass(button.parentNode, 'tab-button');
for (i = 0; i < buttons.length; i++) {
if (buttons[i] === button) {
index = i;
button.className = 'tab-button active';
} else {
buttons[i].className = 'tab-button';
}
}
// Hide other tabs and show this one.
var tabs = childrenByClass(button.parentNode.parentNode, 'tab');
for (i = 0; i < tabs.length; i++) {
if (i === index) {
tabs[i].style.display = 'block';
} else {
tabs[i].style.display = 'none';
}
}
}
/*
Collapse or show a navigation menu. It will not be hidden unless it
is currently selected or `force` has been passed.
*/
function toggleCollapseNav(event, force) {
var heading = event.target.parentNode;
var content = heading.nextSibling;
var inner = content.children[0];
if (heading.className.indexOf('heading') === -1) {
// Clicked without hitting the right element?
return;
}
if (content.style.maxHeight && content.style.maxHeight !== '0px') {
// Currently showing, so let's hide it, but only if this nav item
// is already selected. This prevents newly selected items from
// collapsing in an annoying fashion.
if (force || window.location.hash && endsWith(event.target.href, window.location.hash)) {
content.style.maxHeight = '0px';
}
} else {
// Currently hidden, so let's show it
content.style.maxHeight = inner.offsetHeight + 12 + 'px';
}
}
/*
Refresh the page after a live update from the server. This only
works in live preview mode (using the `--server` parameter).
*/
function refresh(body) {
document.querySelector('body').className = 'preload';
document.body.innerHTML = body;
// Re-initialize the page
init();
autoCollapse();
document.querySelector('body').className = '';
}
/*
Determine which navigation items should be auto-collapsed to show as many
as possible on the screen, based on the current window height. This also
collapses them.
*/
function autoCollapse() {
var windowHeight = getWindowDimensions()[1];
var itemsHeight = 64; /* Account for some padding */
var itemsArray = Array.prototype.slice.call(
document.querySelectorAll('nav .resource-group .heading'));
// Get the total height of the navigation items
itemsArray.forEach(function (item) {
itemsHeight += item.parentNode.offsetHeight;
});
// Should we auto-collapse any nav items? Try to find the smallest item
// that can be collapsed to show all items on the screen. If not possible,
// then collapse the largest item and do it again. First, sort the items
// by height from smallest to largest.
var sortedItems = itemsArray.sort(function (a, b) {
return a.parentNode.offsetHeight - b.parentNode.offsetHeight;
});
while (sortedItems.length && itemsHeight > windowHeight) {
for (var i = 0; i < sortedItems.length; i++) {
// Will collapsing this item help?
var itemHeight = sortedItems[i].nextSibling.offsetHeight;
if ((itemsHeight - itemHeight <= windowHeight) || i === sortedItems.length - 1) {
// It will, so let's collapse it, remove its content height from
// our total and then remove it from our list of candidates
// that can be collapsed.
itemsHeight -= itemHeight;
toggleCollapseNav({target: sortedItems[i].children[0]}, true);
sortedItems.splice(i, 1);
break;
}
}
}
}
/*
Initialize the interactive functionality of the page.
*/
function init() {
var i, j;
// Make collapse buttons clickable
var buttons = document.querySelectorAll('.collapse-button');
for (i = 0; i < buttons.length; i++) {
buttons[i].onclick = toggleCollapseButton;
// Show by default? Then toggle now.
if (buttons[i].className.indexOf('show') !== -1) {
toggleCollapseButton({target: buttons[i].children[0]});
}
}
var responseCodes = document.querySelectorAll('.example-names');
for (i = 0; i < responseCodes.length; i++) {
var tabButtons = childrenByClass(responseCodes[i], 'tab-button');
for (j = 0; j < tabButtons.length; j++) {
tabButtons[j].onclick = toggleTabButton;
// Show by default?
if (j === 0) {
toggleTabButton({target: tabButtons[j]});
}
}
}
// Make nav items clickable to collapse/expand their content.
var navItems = document.querySelectorAll('nav .resource-group .heading');
for (i = 0; i < navItems.length; i++) {
navItems[i].onclick = toggleCollapseNav;
// Show all by default
toggleCollapseNav({target: navItems[i].children[0]});
}
}
// Initial call to set up buttons
init();
window.onload = function () {
autoCollapse();
// Remove the `preload` class to enable animations
document.querySelector('body').className = '';
};

3061
_site/core/api-specs.md

File diff suppressed because it is too large

414
_site/core/atlas_network.md

@ -0,0 +1,414 @@
# Atlas Network
This document describes the Atlas network, a peer-to-peer content-addressed
storage system whose chunks' hashes are announced on a public blockchain.
Atlas allows users and developers to **permanently store** chunks of data that are
**replicated across every peer.** As long as at least one Atlas peer is online,
all chunks are available to clients.
This document is aimed at developers and technical users. The following
concepts are discussed:
* What the Atlas network offers developers
* How to load and store data in the Atlas network
* How the Atlas network works internally
* How the Atlas network compares to related content-addressed storage systems
The reader of this document is expected to be familiar with the [Blockstack
Naming Service](blockstack_naming_service.md) (BNS), as well as Blockstack's
storage system [Gaia](https://github.com/blockstack/gaia). We advise the reader
to familiarize themselves with both systems before approaching this document.
# Introduction
Atlas is designed to integrate with BNS in order to allow users to
store name state off-chain, encoded as a DNS zone file.
The overwhelmingly-common use-cases in Blockstack are:
* Storing a name's routing information for its owners' [Gaia](https://github.com/blockstack/gaia)
datastores.
* Storing BNS subdomain transactions and associated state.
Atlas is a middleware system in Blockstack. Most developers do not
interact with it directly. BNS clients like the
[Blockstack Browser](https://github.com/blockstack/blockstack-browser)
automatically generate zone files for the names they register, and automatically
propagate them to the Atlas network. BNS API endpoints, including our
[public endpoint](https://core.blockstack.org) and the
[blockstack.js](https://github.com/blockstack/blockstack.js) library,
will automatically fetch zone files from Atlas when they need to look
up data in Gaia (such as profiles and app data).
```
+--------------+ +---------------+ +----------------+
clients | Blockstack | | blockstack.js | | BNS API module |
| Browser | | | | |
+--------------+ +---------------+ +----------------+
^ ^ ^ ^ ^ ^
| | | | | |
| | | | | |
V | V | V |
+----------+ | +----------+ | +----------+ |
Gaia | Gaia hub | | | Gaia hub | | | Gaia hub | |
+----------+ | +----------+ | +----------+ |
| | |
| | |
V V V
+---------------------------------------------------------------+
Atlas | Atlas Peer Network |
+----------+------+----------+-----+----------+------+----------+
BNS | BNS node | | BNS node | | BNS node | | BNS node |
+----------+ +----------+ +----------+ +----------+
^ ^ ^ ^
| (indexing | | |
| blockchain) | | |
+---------------------------------------------------------------+
Blockchain | Blockchain Peer Network |
+---------------------------------------------------------------+
Figure 1: Location of Atlas in the Blockstack architecture. Each BNS node
implements an Atlas peer. An Atlas peer treats a name state value in BNS as
the hash of a DNS zone file. Atlas peers exchange zone files with one another
until they each have a full replica of all known zone files. Clients can look
up zone files for names using the name's stat value as a zone file hash. Clients
can broadcast zone files to the network if they match a previously-announced
hash. In practice, zone files store URLs to a name owner's Gaia hubs, thereby
allowing Blockstack apps to read and write data in Gaia.
```
Nevertheless, Atlas is a general-purpose content-addressed storage
system that advanced developers can use to **host data in an immutable
and durable manner.** Beyond its default use-case in Blockstack,
Atlas is ideal for tasks like:
* Announcing PGP public keys under a human-readable name
* Storing package hashes for a software release
* Securely deploying shell scripts to remote VMs
* Binding human-readable names to Tor .onion addresses
([example](https://github.com/blockstack-packages/blockstack-tor))
# Motivation
Atlas was designed to augment BNS. BNS allows each name to store a small
amount of state---on the order of 20 bytes. The size is so small because the
state must be recorded to a public blockchain, where the cost per byte is
high and the blockchain protocol limits the size of transactions.
To compensate for this, we developed an off-chain storage system allows BNS
names to bind and store a large amount of state to each name in a way that
*preserves the security properties of having written that state to the
blockchain*. Instead of storing 20 bytes of data on the blockchain, a BNS name
owner would store the *cryptograhpic hash* of its state, and then store the actual state
Atlas. This decouples the name's state size from the blockchain.
The reference implementation of Atlas currently allows up to 40kb of state to be
bound to a BNS name, instead of a measly 20 bytes. The 40kb of data is
replicated to each BNS node, where it is stored forever.
# How to Use the Atlas Network
While the Blockstack software stack expects that Atlas-hosted data is made up of
DNS zone files, Atlas itself does not enforce this (nor does it care about the
format of its chunks). It is designed as a general-purpose chunk store.
Nevertheless, the ubiquitous use of Atlas to store data as DNS zone files has
had an influence on its API design---fields and method names frequently allude
to zone files and zone file hashes. This is intentional.
The [public BNS API endpoint](https://core.blockstack.org) does not support
resolving Atlas chunks that do not encode Gaia routing information or subdomain
information. To directly interact with Atlas, developers will need to install
[Blockstack Core](https://github.com/blockstack/blockstack-core) and use its
Python client libraries for these examples.
## Looking up Chunks
All Atlas chunks are addressed by the RIPEMD160 hash of the SHA256 hash of the
chunk data. A client can query up to 100 chunks in one RPC call.
A client can look up a chunk with the `get_zonefiles()` method. If successful,
the returned payload will be a `dict` with a `zonefiles` key that maps the chunk
hashes to their respective data.
```python
>>> import blockstack
>>> data = blockstack.lib.client.get_zonefiles('https://node.blockstack.org:6263', ['1b89a685f4c4ea245ce9433d0b29166c22175ab4'])
>>> print data['zonefiles']['1b89a685f4c4ea245ce9433d0b29166c22175ab4']
$ORIGIN duckduckgo_tor.id
$TTL 3600
tor TXT "3g2upl4pq6kufc4m.onion"
>>>
```
(This particular chunk happens to be associated with the BNS name
`duckduckgo_tor.id`).
## Adding a New Chunk
The only way to add a chunk to Atlas is to do so through an on-chain name in
BNS. Adding a new chunk is a two-step process:
* The name owner announces the chunk hash as a name's state
via a `NAME_REGISTRATION`, `NAME_UPDATE`, `NAME_RENEWAL`, or `NAME_IMPORT` transaction.
* Once the transaction is confirmed and processed by BNS, the name owner
broadcasts the matching zone file.
Setting a name's state to be the hash of a chunk is beyond the scope of this
document, since it needs to be done through a BNS client.
See the relevant documentation for
[blockstack.js](https://github.com/blockstack/blockstack.js) and the [Blockstack
Browser](https://github.com/blockstack/blockstack-browser) for doing this.
Once the name operation is confirmed, you can announce the data to the
Atlas network. You can do so with the Python client as follows:
```python
>>> import blockstack
>>> import base64
>>> data = "..." # this is the chunk data you will announce
>>> data_b64 = base64.b64encode(data)
>>> result = blockstack.lib.client.put_zonefiles('https://node.blockstack.org:6263', [data_b64])
>>> assert result['saved'][0] == 1
>>>
```
At most five chunks can be announced in one RPC call.
Note that the data must be base64-encoded before it can be announced.
When the `put_zonefiles()` method succeeds, it returns a `dict` with a list
under the `saved` key. Here, `result['saved'][i]` will be 1 if the `i`th
chunk given to `put_zonefiles()` was saved by the node, and 0 if not.
The node will not save a chunk if it is too big, or if it has not yet processed
the name operation that contained the chunk's hash.
The `put_zonefiles()` method is idempotent.
## Propagating Chunks
Atlas peers will each store a copy of the chunks you announce. In the
background, they will asynchronously announce to one another which chunks they
have available, and replicate them to one another in a rarest-first order (much
like how BitTorrent works). Eventually, every Atlas peer will receive the
chunk.
However, developers can accelerate this process by eagerly propagating chunks.
To do so, they can ask an Atlas peer for its immediate neighbors in the Atlas
peer graph, and replicate the chunk to each of them as well.
For example, this code will replicate the chunk to not only
`https://node.blockstack.org:6263`, but also to its immediate neighbors.
```python
>>> import blockstack
>>> import base64
>>> data = "..." # this is the chunk you will replicate widely
>>> data_b64 = base64.b64encode(data)
>>>
>>> result = blockstack.lib.client.get_atlas_peers('https://node.blockstack.org:6263')
>>> neighbors = result['peers']
>>> print ", ".join(neighbors)
13.65.207.163:6264, 52.225.128.191:6264, node.blockstack.org:6264, 23.102.162.7:6264, 52.167.230.235:6264, 23.102.162.124:6264, 52.151.59.26:6264, 13.92.134.106:6264
>>>
>>> for neighbor in neighbors:
... result = blockstack.lib.client.put_zonefiles(neighbor, [data_b64])
... assert result['saved'][0] == 1
...
>>>
```
This is not strictly necessary, but it does help accelerate chunk replication
and makes it less likely that a chunk will get lost due to individual node
failures.
# How Atlas Works
Atlas was designed to overcome the structural weaknesses inherent to all
distributed hash tables. In particular, it uses an unstructured peer network to
maximize resilience against network link failure, and it uses the underlying
blockchain (through BNS) to rate-limit chunk announcements.
## Peer Selection
Atlas peers self-organize into an unstructured peer-to-peer network.
The Atlas peer network is a [random K-regular
graph](https://en.wikipedia.org/wiki/Random_regular_graph). Each node maintains
*K* neighbors chosen at random from the set of Atlas peers.
Atlas nodes select peers by carrying out an unbiased random walk of the peer
graph. When "visiting" a node *N*, it will ask for *N*'s neighbors and then
"step" to one of them with a probability dependent on *N*'s out-degree and the
neighbor's in-degree.
The sampling algorithm is based on the Metropolis-Hastings (MH) random graph walk
algorithm, but with a couple key differences. In particular, the algorithm
attempts to calculate an unbiased peer graph sample that accounts for the fact
that most nodes will be short-lived or unreliable, while a few persistent nodes
will remain online for long periods of time. The sampling algorithm accounts
for this with the following tweaks:
* If the neighbors of the visited node *N* are all unresponsive, the random
walk resets to a randomly-chosen known neighbor. There is no back-tracking on
the peer graph in this case.
* The transition probability from *N* to a live neighbor is *NOT* `min(1,
degree(neighbor)/degree(N))` like it is in the vanilla MH algorithm. Instead,
the transition probability discourages backtracking to the previous neighbor *N_prev*,
but in a way that still guarantees that the sampling will remain unbiased.
* A peer does not report its entire neighbor set when queried,
but only reports a random subset of peers that have met a minimium health threshold.
* A new neighbor is only selected if it belongs to the same [BNS
fork-set](blockstack_naming_service.md#bns-forks) (i.e. it reports
as having a recent valid consensus hash).
The algorithm was adapted from the work from [Lee, Xu, and
Eun](https://arxiv.org/pdf/1204.4140.pdf) in the proceedings of
ACM SIGMETRICS 2012.
### Comparison to DHTs
The reason Atlas uses an unstructured random peer network
instead of a [distributed hash table](https://en.wikipedia.org/wiki/Distributed_hash_table)
(DHT) is that DHTs are susceptbile to Sybil attacks. An adaptive adversary can
insert malicious nodes into the DHT in order to stop victims from
resolving chunks or finding honest neighbors.
#### Chunk Censorship
In a DHT, an attacker can censor a chunk by inserting nodes into the peers' routing tables
such that the attacker takes control over all of the chunk's hash buckets.
It can do so at any point in time after the chunk was first stored,
because only the peers who maintain the chunk's hash bucket have to store it.
This is a *fundamental* problem with structured overlay networks
that perform request routing based on content hash---they give the attacker
insight as to the path(s) the queries take through the peer graph, and thus
reduce the number of paths the attacker must disrupt in order to censor the
chunk.
Atlas uses an unstructured overlay network combined with a 100% chunk
replication strategy in order to maximize
the amount of work an adversary has to do to censor a chunk.
In Atlas, all peers replicate a chunk, and the paths the chunk take through the
network are *independent* of the content and *randomized* by the software
(so the paths cannot be predicted in advance). The attacker's only
recourse is to quickly identify the nodes that can serve the chunk and partition them from
the rest of the network in order to carry out a censorship attack.
This requires them to have visibility into the vast majority of network links in
the Atlas network (which is extremely difficult to do, because in practice Atlas
peers maintain knowledge of up to 65536 neighbors and only report 10 random peers
when asked).
#### Neighbor Censorship
Another problem with DHTs is that their overlay
network structure is determined by preferential attachment. Not every peer that
contacts a given DHT node has an equal chance of becoming its neighbor.
The node will instead rank a set of peers as being more or less ideal
for being neighbors. In DHTs, the degree of preference a node exhibits to
another node is usually a function of the node's self-given node identifier
(e.g. a node might want to select neighbors based on proximity in the key
space).
The preferential attachment property means that an adaptive adversary can game the node's
neighbor selection algorithm by inserting malicious nodes that do not
forward routing or lookup requests. The attacker does not even have to eclipse
the victim node---the victim node will simply prefer to talk to the attacker's unhelpful nodes
instead of helpful honest nodes. In doing so, the attacker can prevent honest peers from discovering each
other and each other's chunks.
Atlas's neighbor selection strategy does not exhibit preferential attachment
based on any self-reported node properties. A
node is selected as a neighbor only if it is reached through an unbiased random graph
walk, and if it responds to queries correctly.
In doing so, an attacker is forced to completely eclipse a set of nodes
in order to cut them off from the rest of the network.
## Chunk Propagation
Atlas nodes maintain an *inventory* of chunks that are known to exist. Each
node independently calculates the chunk inventory from its BNS database.
Because the history of name operations in BNS is linearized, each node can
construct a linearized sub-history of name operations that can set chunk
hashes as their name state. This gives them a linearized sequence of chunks,
and every Atlas peer will independently arrive at the same sequence by reading
the same blockchain.
Atlas peers keep track of which chunks are present and which are absent. They
each construct an *inventory vector* of chunks *V* such that *V[i]* is set to 1
if the node has the chunk whose hash is in the *i*th position in the chunk
sequence (and set to 0 if it is absent).
Atlas peers exchange their inventory vectors with their neighbors in order to
find out which chunks they each have. Atlas nodes download chunks from
neighbors in rarest-first order in order to prioritize data replication for the
chunks that are currently most at-risk for disappearing due to node failure.
```
Name operation | chunk hashes | chunk data | Inventory
history | as name state | | vector
+-------------------+
| NAME_PREORDER |
+-------------------+----------------+
| NAME_REGISTRATION | chunk hash | "0123abcde..." 1
+-------------------+----------------+
| NAME_UPDATE | chunk hash | (null) 0
+-------------------+----------------+
| NAME_TRANSFER |
+-------------------+
| NAME_PREORDER |
+-------------------+----------------+
| NAME_IMPORT | chunk hash | "4567fabcd..." 1
+-------------------+----------------+
| NAME_TRANSFER |
+-------------------|
. . .
Figure 2: Relationship between Atlas node chunk inventory and BNS name state.
Some name operations announce name state in the blockchain, which Atlas
interprets as a chunk hash. The Atlas node builds up a vector of which chunks
it has and which ones it does not, and announces it to other Atlas peers so
they can fetch chunks they are missing. In this example, the node's
inventory vector is [1, 0, 1], since the 0th and 2nd chunks are present
but the 1st chunk is missing.
```
## Querying Chunk Inventories
Developers can query a node's inventory vector as follows:
```python
>>> import blockstack
>>> result = blockstack.lib.client.get_zonefile_inventory("https://node.blockstack.org:6263", 0, 524288)
>>> print len(result['inv'])
11278
>>>
```
The variable `result['inv']` here is a big-endian bit vector, where the *i*th
bit is set to 1 if the *i*th chunk in the chunk sequence is present. The bit at
`i=0` (the earliest chunk) refers to the leftmost bit.
A sample program that inspects a set of Atlas nodes' inventory vectors and determines
which ones are missing which chunks can be found
[here](https://github.com/blockstack/atlas/blob/master/atlas/atlas-test).
# Appendix 1: Feature Comparison
Atlas is not the only peer-to-peer content-addressible chunk store in existance. The following
feature table describes Atlas in relation to other popular chunk stores.
| **Features** | Atlas | BitTorrent | [DAT](https://datproject.org/) | [IPFS](https://ipfs.io) | [Swarm](https://github.com/ethersphere/swarm) |
|-----------------------------|-------|------------|--------------------------------|-------------------------|-----------------------------------------------|
| Each peer stores all chunks | X | X | | | |
| Replicas are permanent [1] | X | X | X | | |
| Replicas are free | | X | X | X | |
| Sybil-resistant chunk discovery | X | X | | | X |
| Sybil-resistant peer discovery | X | | | | |
| Fixed chunk size | X | | X | X | X |
[1] Here, "permanent" means that once a peer has data, they will never evict it
as part of the protocol.

4
_site/core/attic/README.md

@ -0,0 +1,4 @@
# Legacy Documentation
Documents here are out-of-date but preserved for posterity. Do not rely on
them.

124
_site/core/attic/advanced_usage.md

@ -0,0 +1,124 @@
# Advanced Usage
This section details some of the advanced features in the CLI.
## A Word of Warning
Advanced features are meant to be used by experienced Blockstack users and developers, They receive less UI/UX testing than basic features, and their interfaces are expected to change to accomodate bugfixes and security fixes. Moreover, improper use of some advanced methods can cost you money, corrupt your profile, or compromise your wallet. Once they receive sufficient testing, an advanced feature may become a basic-mode feature in a subsequent release.
**Do not use advanced mode unless you know what you are doing!**
## Activating Advanced Mode
To activate advanced mode, use the command `blockstack set_advanced_mode on`.
To deactivate it later (recommended), use the command `blockstack set_advanced_mode off`.
## Changing or Using Exiting Keys
If you already have a payment key you want to use, or an owner key you want to migrate over, you can generate a wallet directly with `import_wallet`. We recommend using this command interactively, so you know which keys correspond to which usages.
## Accounts
With the accounts methods, you can directly manage your social proofs, link existing services to your profile, and store small bits of information.
The account management methods are:
* `get_account`: Look up an account in a name's profile. There can be more than one match.
* `list_accounts`: List all accounts in a name's profile.
* `put_account`: Add or update an account in a name's profile.
* `delete_account`: Remove an account from a name's profile. This may need to be done more than once, if there are duplicates of the account.
## Advanced Blockstack ID Queries
Beyond `lookup` and `whois`, there are a few other more advanced queries you can run on Blockstack IDs. These include:
### Listing Blockstack IDs
* `get_all_names`: Get the list of every single Blockstack ID in existance.
* `get_names_owned_by_address`: Get the list of names owned by a particular ownership address.
### Querying the Blockchain
* `get_name_blockchain_record`: Get the raw database record for a Blockstack ID. It will contain a *compressed* history of all name operations that have affected it. This is meant primarily for debugging purposes; to get an easier-to-parse listing of the information this command returns, use `get_name_blockchain_history`.
* `get_name_blockchain_history`: Get the set of all prior states a Blockstack ID has been in, keyed by the block heights at which the state-change was processed.
* `get_records_at`: Get the list of name operation records processed at a particular block height.
* `list_update_history`: Get the list of all zonefile hashes that a Blockstack ID has ever had.
### Zonefiles
* `get_name_zonefile`: Get only a Blockstack ID's zonefile.
* `list_zonefile_history`: Get the list of all zonefiles a Blockstack ID has ever had. **NOTE:** There is no guarantee that the server will hold copies of old zonefiles. This command is meant mainly for determining which historic zonefiles a server has processed.
* `set_zonefile_hash`: This is the counterpart to `update`, but instead of setting the zonefile directly and uploading it to storage, you can use this command to directly set the data hash for a Blockstack ID. **NOTE:** You should ensure that the associated zonefile data has been replicated off-chain to a place where other users can get at it.
### Lightweight Queries
The lightweight lookup protocol for Blockstack is called *Simplified Name Verification* (SNV). This command returns a prior blockchain-level record given a more recent known-good consensus hash, serial number, or transaction ID of a transaction that contains a consensus hash. The CLI does not need to trust the Blockstack server to use these commands.
* `lookup_snv`: Use the Merkle skip-list in the name database to look up a historic name operation on a Blockstack ID.
## Consensus Queries
You can query consensus hash information from the server with the following commands:
* `consensus`: Get the consensus hash at a particular block height
## Namespace Queries
In addition to querying Blockstack IDs, the CLI has advanced commands for querying namespaces. These include:
* `get_namespace_blockchain_record`: Get the raw database record for a Blockstack namespace. It will contain a *compressed* history of all namespace operations that have affected it.
* `get_names_in_namespace`: Get the list of every Blockstack ID in a particular namespace.
* `get_namespace_cost`: Get the cost required to preorder a namespace. Does *not* include the cost to reveal and ready it, nor does it include the transaction fees.
## Namespace Creation
**WARNING:** We do not recommend that you try to do this by yourself. Creating a namespace is **EXTREMELY EXPENSIVE**. If you are interested in creating your own namespace, please contact the Blockstack developers on the [Blockstack Slack](http://chat.blockstack.org).
These methods allow you to create a namespace. There are three steps: preordering, revealing, and readying. Preordering a namespace is like preordering a name--you announce the hash of the namespace ID and the address that will control it. Revealing a namespace not only reveals the namespace ID, but also sets the pricing and lifetime rules for names in the namespace. After revealing the namespace, the namespace controller can pre-populate the namespace by importing Blockstack IDs. Once the namespace has been pre-populated, the controller sends a final transaction that readies the namespace for general use.
* `namespace_preorder`: Preorder a namespace.
* `namespace_reveal`: Reveal a namespace, and set its pricing and lifetime parameters. **NOTE:** This must be done within 144 blocks of sending the namespace preorder transaction.
* `name_import`: Import a name into a revealed (but not readied) namespace. You can set its owner address and zonefile hash directly.
* `namespace_ready`: Open a namespace for general registrations.
## Data Storage
Blockstack allows users to store arbitrary data to any set of storage providers for which the CLI has a driver. The data will be signed by the user's data key, so when other users read the data later on, they can verify that it is authentic (i.e. the storage provider is not trusted). Moreover, Blockstack is designed such that users don't have to know or care about which storage providers were used--as far as users can see, storage providers are just shared hard drives.
There are two types of data supported by Blockstack: *mutable* data, and *immutable* data. Mutable data is linked by the profile, and can be written as fast and as frequently as the storage provider allows. Mutable data is addressed by URL.
**WARNING:** While mutable data guarantees end-to-end authenticity, there is a chance that a malicious storage provider can serve new readers stale versions of the data. That is, users who have read the latest data already will not get tricked into reading stale data, but users who have *not yet* read the latest data *can* be tricked (i.e. the CLI keeps a version number for mutable data to do so). This must be taken into account if you intend to use this API.
Immutable data, however, is content-addressed, and its cryptographic hash is stored to the user's zonefile. Writing immutable data will entail updating the zonefile and sending an `update` transaction (handled internally), so it will be slow by comparison. This has the advantage that storage providers cannot perform the aforementioned stale data attack, but has the downside that writes cost money and take a long time to complete.
That said, we recommend using the mutable data API with several different storage providers whenever possible.
### Mutable Data
The following commands affect mutable data:
* `get_mutable`: Use the profile to look up and fetch a piece of mutable data.
* `put_mutable`: Add a link to mutable data to the profile, and replicate the signed data itself to all storage providers. Other users will need the data's name to read it with `get_mutable`.
* `delete_mutable`: Remove a link to mutable data from the profile, and ask all storage providers to delete the signed data.
### Immutable Data
The following commnds affect immutable data:
* `get_immutable`: Look up and fetch a piece of immutable data. You can supply either the name of the data, or its hash (both are stored in the zonefile, so there is no gain or loss of security in this choice).
* `put_immutable`: Replicate a piece of data to all storage providers, add its name and hash to the zonefile, and issue an `update` to upload the new zonefile to Blockstack servers and write the hash to the blockchain.
* `delete_immutable`: Remove the link to the data from the zonefile, ask all storage providers to delete the data, and issue an `update` to upload the new zonefile to Blockstack servers and write the new hash to the blockchain.
* `list_immutable_data_history`: Given the name of a piece of immutable data, query the zonefile history to find the historic list of hashes it has had. **NOTE:** Like `list_zonefile_history` above, this only returns data hashes for the data if the Blockstack server has the historic zonefile.
## Fault Recovery
Sometimes, things beyond our control can happen. Transactions can get stuck, storage providers can go offline or corrupt data, and so on. These commands are meant to assist in recovering from these problems:
* `set_profile`: Directly set a Blockstack ID's profile. All previous accounts, data links, etc. must be included in the new profile, since the old profile (if still present) will be overwritten by the one given here.
* `convert_legacy_profile`: Given a legacy profile taken from a resolver, directly convert it into a new profile. This can be used with `set_profile` to recover from a failed profile migration.
* `unqueue`: If a transaction gets lost or stuck, you can remove it from the CLI's transaction queue with this command. This will allow you to re-try it.
* `rpcctl`: This lets you directly start or stop the Blockstack CLI's background daemon, which lets you recover from any crashes it experiences (you can find a trace of its behavior in `~/.blockstack/api_endpoint.log`)
## Programmatic Access
Other programs may want to make RPC calls the Blockstack CLI daemon. They can do so using either the `blockstack_client` Python package, or they can do so via the CLI as follows:
* `rpc`: Issue a JSON RPC call. Takes a raw JSON string that encodes a list of arguments.

BIN
_site/core/attic/figures/gaia-authentication.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
_site/core/attic/figures/gaia-connect.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
_site/core/attic/figures/gaia-getfile.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
_site/core/attic/figures/gaia-listdir.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
_site/core/attic/figures/gaia-putfile.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

461
_site/core/attic/gaia.md

@ -0,0 +1,461 @@
# LEGACY DOCUMENTATION
Please see the [latest Gaia documentation](https://github.com/blockstack/gaia)
Gaia: The Blockstack Storage System
====================================
The Blockstack storage system, called "Gaia", is used to host each user's data
without requiring users to run their own servers.
Gaia works by hosting data in one or more existing storage systems of the user's choice.
These storage systems include cloud storage systems like Dropbox and Google
Drive, they include personal servers like an SFTP server or a WebDAV server, and
they include decentralized storage systems like BitTorrent or IPFS. The point
is, the user gets to choose where their data lives, and Gaia enables
applications to access it via a uniform API.
A high-level analogy is to compare Gaia to the VFS and block layer in a UNIX
operating system kernel, and to compare existing storage systems to block
devices. Gaia has "drivers" for each storage system that allow it to load,
store, and delete chunks of data via a uniform interface, and it gives
applications a familiar API for organizing their data.
Applications interface with Gaia via the [Blockstack Core
API](https://github.com/blockstack/blockstack-core/tree/master/api). Javascript
applications connect to Gaia using [Blockstack Portal](https://github.com/blockstack/blockstack-portal),
which helps them bootstrap a secure connection to Blockstack Core.
# Datastores
Gaia organizes data into datastores. A **datastore** is a filesystem-like
collection of data that is backed by one or more existing storage systems.
When a user logs into an application, the application will create or connect to
the datastore that holds the user's data. Once connected, it can proceed to
interact with its data via POSIX-like functions: `mkdir`, `listdir`, `rmdir`,
`getFile`, `putFile`, `deleteFile`, and `stat`.
A datastore has exactly one writer: the user that creates it. However, all data
within a datastore is world-readable by default, so other users can see the
owner's writes even when the owner is offline. Users manage access controls
by encrypting files and directories to make them readable to other specific users.
All data in a datastore is signed by a datastore-specific key on write, in order
to guarantee that readers only consume authentic data.
The application client handles all of the encryption and signing. The other
participants---Blockstack Portal, Blockstack Core, and the storage
systems---only ferry data back and forth between application clients.
## Data Organization
True to its filesystem inspiration, data in a datastore is organized into a
collection of inodes. Each inode has two parts:
* a **header**, which contains:
* the inode type (i.e. file or directory)
* the inode ID (i.e. a UUID4)
* the hash of the data it stores
* the size of the data it stores
* a signature from the user
* the version number
* the ID of the device from which it was sent (see Advanced Topics below)
* a **payload**, which contains the raw bytes to be stored.
* For files, this is just the raw bytes.
* For directories, this is a serialized data structure that lists the names
and inode IDs of its children, as well as a copy of the header.
The header has a fixed length, and is somewhat small--only a few hundred bytes.
The payload can be arbitrarily large.
## Data Consistency
The reason for organizing data this way is to make cross-storage system reads
efficient, even when there are stale copies of the data available. In this
organization, reading an inode's data is a matter of:
1. Fetching all copies of the header
2. Selecting the header with the highest version number
3. Fetching the payload from the storage system that served the latest header.
This way, we can guarantee that:
* The inode payload is fetched *once* in the common case, even if there are multiple stale copies of the inode available.
* All clients observe the *strongest* consistency model offerred by the
underlying storage providers.
* All readers observe a *minimum* consistency of monotonically-increasing reads.
* Writers observe sequential consistency.
This allows Gaia to interface with decentralized storage systems that make
no guarantees regarding data consistency.
*(Aside 1: The Core node keeps track of the highest last-seen inode version number,
so if all inodes are stale, then no data will be returned).*
*(Aside 2: In step 3, an error path exists whereby all storage systems will be
queried for the payload if the storage system that served the fresh inode does
not have a fresh payload).*
# Accessing the Datastore
Blockstack applications get access to the datastore as part of the sign-in
process. Suppose the user wishes to sign into the application `foo.app`. Then,
the following protocol is executed:
![Gaia authentication](/docs/figures/gaia-authentication.png)
1. Using `blockstack.js`, the application authenticates to Blockstack Portal via
`makeAuthRequest()` and `redirectUserToSignIn()`.
2. When Portal receives the request, it contacts the user's Core node to get the
list of names owned by the user.
3. Portal redirects the user to a login screen, and presents the user with the
list of names to use. The user selects which name to sign in as.
4. Now that Portal knows which name to use, and which application is signing in,
it loads the datastore private key and requests a Blockstack Core session
token. This token will be used by the application to access Gaia.
5. Portal creates an authentication response with `makeAuthResponse()`, which it
relays back to the application.
6. The application retrieves the datastore private key and the Core session
token from the authentication response object.
## Creating a Datastore
Once the application has a Core session token and the datastore private key, it
can proceed to connect to it, or create it if it doesn't exist. To do so, the
application calls `datastoreConnectOrCreate()`.
This method contacts the Core node directly. It first requests the public
datastore record, if it exists. The public datastore record
contains information like who owns the datastore, when it was created, and which
drivers should be used to load and store its data.
![Gaia connect](/docs/figures/gaia-connect.png)
Suppose the user signing into `foo.app` does not yet have a datastore, and wants
to store her data on storage providers `A`, `B`, and `C`. Then, the following
protocol executes:
1. The `datastoreConnectOrCreate()` method will generate a signed datastore record
stating that `alice.id`'s public key owns the datastore, and that the drivers
for `A`, `B`, and `C` should be loaded to access its data.
2. The `datastoreConnectOrCreate()` method will call `mkdir()` to create a
signed root directory.
3. The `datastoreConnectOrCreate()` method will send these signed records to the Core node.
The Core node replicates the root directory header (blue path), the root
direcory payload (green path), and the datastore record (gold path).
4. The Core node then replicates them with drivers `A`, `B`, and `C`.
Now, storage systems `A`, `B`, and `C` each hold a copy of the datastore record
and its root directory.
*(Aside: The datastore record's consistency is preserved the same way as the
inode consistency).*
## Reading Data
Once the application has a Core session token, a datastore private key, and a
datastore connection object, it can proceed to read it. The available methods
are:
* `listDir()`: Get the contents of a directory
* `getFile()`: Get the contents of a file
* `stat()`: Get a file or directory's header
Reading data is done by path, just as it is in UNIX. At a high-level, reading
data involes (1) resolving the path to the inode, and (2) reading the inode's
contents.
Path resolution works as it does in UNIX: the root directory is fetched, then
the first directory in the path, then the second directory, then the third
directory, etc., until either the file or directory at the end of the path is
fetched, or the name does not exist.
### Authenticating Data
Data authentication happens in the Core node,.
This is meant to enable linking files and directories to legacy Web
applications. For example, a user might upload a photo to a datastore, and
create a public URL to it to share with friends who do not yet use Blockstack.
By default, the Core node serves back the inode payload data
(`application/octet-stream` for files, and `application/json` for directories).
The application client may additionally request the signatures from the Core
node if it wants to authenticate the data itself.
### Path Resolution
Applications do not need to do path resolution themselves; they simply ask the
Blockstack Core node to do so on their behalf. Fetching the root directory
works as follows:
1. Get the root inode ID from the datastore record.
2. Fetch all root inode headers.
3. Select the latest inode header, and then fetch its payload.
4. Authenticate the data.
For example, if a client wanted to read the root directory, it would call
`listDir()` with `"/"` as the path.
![Gaia listdir](/docs/figures/gaia-listdir.png)
The blue paths are the Core node fetching the root inode's headers. The green
paths are the Core node selecting the latest header and fetching the root
payload. The Core node would reply the list of inode names within the root
directory.
Once the root directory is resolved, the client simply walks down the path to
the requested file or directory. This involves iteratively fetching a
directory, searching its children for the next directory in the path, and if it
is found, proceeding to fetch it.
### Fetching Data
Once the Core node has resolved the path to the base name, it looks up the inode
ID from the parent directory and fetches it from the backend storage providers
via the relevant drivers.
For example, fetching the file `/bar` works as follows:
![Gaia getFile](/docs/figures/gaia-getfile.png)
1. Resolve the root directory (blue paths)
2. Find `bar` in the root directory
3. Get `bar`'s headers (green paths)
4. Find the latest header for `bar`, and fetch its payload (gold paths)
5. Return the contents of `bar`.
## Writing Data
There are three steps to writing data:
* Resolving the path to the inode's parent directory
* Creating and replicating the new inode
* Linking the new inode to the parent directory, and uploading the new parent
directory.
All of these are done with both `putFile()` and `mkdir()`.
### Creating a New Inode
When it calls either `putFile()` or `mkdir()`, the application client will
generate a new inode header and payload and sign them with the datastore private
key. Once it has done so successfully, it will insert the new inode's name and
ID into the parent directory, give the parent directory a new version number,
and sign and replicate it and its header.
For example, suppose the client attempts to write the data `"hello world"` to `/bar`.
To do so:
![Gaia putFile](/docs/figures/gaia-putfile.png)
1. The client executes `listDir()` on the parent directory, `/` (blue paths).
2. If an inode by the name of `bar` exists in `/`, then the method fails.
3. The client makes a new inode header and payload for `bar` and signs them with
the datastore private key. It replicates them to the datastore's storage
drivers (green paths).
4. The client adds a record for `bar` in `/`'s data obtained from (1),
increments the version for `/`, and signs and replicates `/`'s header and
payload (gold paths).
### Updating a File or Directory
A client can call `putFile()` multiple times to set the file's contents. In
this case, the client creates, signs, and replicates a new inode header and new
inode payload for the file. It does not touch the parent directory at all.
In this case, `putFile()` will only succeed if the parent directory lists an
inode with the given name.
A client cannot directly update the contents of a directory.
## Deleting Data
Deleting data can be done with either `rmdir()` (to remove an empty directory)
or `deleteFile()` (to remove a file). In either case, the protocol executed is
1. The client executes `listDir()` on the parent directory
2. If an inode by the given name does not exist, then the method fails.
3. The client removes the inode's name and ID from the directory listing, signs
the new directory, and replicates it to the Blockstack Core node.
4. The client tells the Blockstack Core node to delete the inode's header and
payload from all storage systems.
# Advanced Topics
These features are still being implemented.
## Data Integrity
What happens if the client crashes while replicating new inode state? What
happens if the client crashes while deleting inode state? The data hosted in
the underlying data stores can become inconsistent with the directory structure.
Given the choice between leaking data and rendering data unresolvable, Gaia
chooses to leak data.
### Partial Inode-creation Failures
When creating a file or directory, Gaia stores four records in this order:
* the new inode payload
* the new inode header
* the updated parent directory payload
* the updated parent directory header
If the new payload replicates successfully but the new header does not, then the
new payload is leaked.
If the new payload and new header replicate successfully, but neither parent
directory record succeeds, then the new inode header and payload are leaked.
If the new payload, new header, and updated parent directory payload replicate
successfully, but the updated parent header fails, then not only are the new
inode header and payload leaked, but also *reading the parent directory will
fail due to a hash mismatch between its header and inode*. This can be detected
and resolved by observing that the copy of the header in the parent directory
payload has a later version than the parent directory header indicates.
### Partial Inode-deletion Failures
When deleting a file or directory, Gaia alters records in this order:
* update parent directory payload
* update parent directory header
* delete inode header
* delete inode payload
Similar to partial failures from updating parent directories when creating
files, if the client replicates the new parent directory inode payload but fails
before it can update the header, then clients will detect on the next read that
the updated payload is valid because it has a signed inode header with a newer
version.
If the client successfully updates the parent directory but fails to delete
either the inode header or payload, then they are leaked. However, since the
directory was updated, no correct client will access the deleted inode data.
### Leak Recovery
Gaia's storage drivers are designed to keep the inode data they store in a
"self-contained" way (i.e. within a single folder or bucket). In the future,
we will implement a `fsck`-like tool that will scan through a datastore and find
the set of inode headers and payloads that are no longer referenced and delete
them.
## Multi-Device Support
Contemporary users read and write data across multiple devices. In this
document, we have thus far described datastores with the assumption that there
is a single writer at all times.
This assumption is still true in a multi-device setting, since a user is
unlikely to be writing data with the same application simultaneously from two
different devices.
However, an open question is how multiple devices can access the same
application data for a user. Our design goal is to **give each device its own
keyring**, so if it gets lost, the user can revoke its access without having to
re-key her other devices.
To do so, we'll expand the definition of a datastore to be a **per-user,
per-application, and per-device** collection of data. The view of a user's
application data will be constructed by merging each device-specific
datastore, and resolving conflicts by showing the "last-written" inode (where
"last-written" is determined by a loosely-synchronized clock).
For example, if a user uploads a profile picture from their phone, and then
uploads a profile picture from their tablet, a subsequent read will query the
phone-originated picture and the tablet-originated picture, and return the
tablet-originated picture.
The aforementioned protocols will need to be extended to search for inode
headers not only on each storage provider, but also search for inodes on the
same storage provider that may have been written by each of the user's devices.
Without careful optimization, this can lead to a lot of inode header queries,
which we address in the next topic.
## A `.storage` Namespace
Blockstack Core nodes can already serve as storage "gateways". That is, one
node can ask another node to store its data and serve it back to any reader.
For example, Alice can make her Blockstack Core node public and program it to
store data to her Amazon S3 bucket and her Dropbox account. Bob can then post data to Alice's
node, causing her node to replicate data to both providers. Later, Charlie can
read Bob's data from Alice's node, causing Alice's node to fetch and serve back
the data from her cloud storage. Neither Bob nor Charlie have to set up accounts on
Amazon S3 and Dropbox this way.
Since Alice is on the read/write path between Bob and Charlie and cloud storage,
she has the opportunity to make optimizations. First, she can program her
Core node to synchronously write data to
local disk and asynchronously back it up to S3 and Dropbox. This would speed up
Bob's writes, but at the cost of durability (i.e. Alice's node could crash
before replicating to the cloud).
In addition, Alice can program her Core node to service all reads from disk. This
would speed up Charlie's reads, since he'll get the latest data without having
to hit back-end cloud storage providers.
Since Alice is providing a service to Bob and Charlie, she will want
compensation. This can be achieved by having both of them send her money via
the underlying blockchain.
To do so, she would register her node's IP address in a
`.storage` namespace in Blockstack, and post her rates per GB in her node's
profile and her payment address. Once Bob and Charlie sent her payment, her
node would begin accepting reads and writes from them up to the capacity
purchased. They would continue sending payments as long as Alice provides them
with service.
Other experienced node operators would register their nodes in `.storage`, and
compete for users by offerring better durability, availability, performance,
extra storage features, and so on.

324
_site/core/basic_usage.md

@ -0,0 +1,324 @@
# Basic Usage
This section describes the basic features of Blockstack CLI. This document is meant to supplement the built-in documentation in the tool.
If at any point you forget how to use a particular CLI command, you can just type `blockstack <NAME OF COMMAND>`, and you will be interactively prompted for each piece of data it needs.
## Client Setup
By default, the CLI tool will automatically configure itself with sensible defaults. If you don't like the defaults, you can change them by running `blockstack configure`.
In particular, you can enable the advanced features with `blockstack set_advanced_mode on`. Please see the `advanced_usage.md` file for details.
## Wallet Setup
Blockstack uses its own wallet, stored to `~/.blockstack/wallet.json`. You do not need a wallet to do lookups.
Blockstack will set up a wallet for you when you try to do something that requires payment (e.g. registering a name). When prompted, you will be asked for a wallet password. This password will be used to encrypt your private keys, and must be at least 16 characters. We recommend using a random string of words that you can easily memorize, since **there is no way to recover your wallet if you forget your password.**
Once you generate a wallet, **make a back-up to a USB key**. You can also print it out, since it's just a string of plain text.
## Doing Lookups
There are two kinds of lookups: a `whois` and a `lookup`. The `whois` queries only information found in the blockchain, whereas a `lookup` queries off-chain data.
A `lookup` fetches the off-chain profile and zonefile. For example:
```
$ blockstack lookup guylepage3.id
{
"profile": {
"@type": "Person",
"account": [
{
"@type": "Account",
"identifier": "1Mp5vKwCbekeWetMHLKDD2fDLJzw4vKxiQ",
"role": "payment",
"service": "bitcoin"
},
{
"@type": "Account",
"identifier": "guylepage3",
"proofType": "http",
"proofUrl": "https://twitter.com/guylepage3/status/731252874886385665",
"service": "twitter"
},
{
"@type": "Account",
"identifier": "g3lepage",
"proofType": "http",
"proofUrl": "https://www.facebook.com/g3lepage/posts/10154223148908760",
"service": "facebook"
},
{
"@type": "Account",
"identifier": "guylepage3",
"proofType": "http",
"proofUrl": "https://gist.github.com/guylepage3/06f522444fb71f1daf01a534396d1f9e",
"service": "github"
}
],
"address": {
"@type": "PostalAddress",
"addressLocality": "New York, NY"
},
"description": "@blockstackorg developer. 1st hire, Design Partner @blockstacklabs (YC/USV backed) entrepreneur, blockchain, creative, marketing, surf, triathlon, ironman",
"graph": {
"url": "https://s3.amazonaws.com/grph/guylepage3"
},
"image": [
{
"@type": "ImageObject",
"contentUrl": "https://s3.amazonaws.com/dx3/guylepage3",
"name": "cover"
},
{
"@type": "ImageObject",
"contentUrl": "https://s3.amazonaws.com/kd4/guylepage3",
"name": "avatar"
}
],
"name": "Guy Lepage",
"website": [
{
"@type": "WebSite",
"url": "http://blockstack.com/team"
}
]
},
"zonefile": {
"$origin": "guylepage3.id",
"$ttl": 3600,
"uri": [
{
"name": "_http._tcp",
"priority": 10,
"target": "https://blockstack.s3.amazonaws.com/guylepage3.id",
"weight": 1
}
]
}
}
```
There will always be two keys defined: `profile` and `zonefile`. The hash of the contents of the `zonefile` object are stored in the blockchain, and the Blockstack servers hold copies of zonefile data. The `profile` object is constructed from a **signed JSON web token** (JWT), which is hosted on the storage providers of the user's choice (as determined in the `client.ini` config file). A modern zonefile points to where the profile JWT is hosted.
The `whois` query is more low-level, and pulls up information that's hosted only in the blockchain. Here's a sample `whois` query:
```
$ blockstack whois muneeb.id
{
"approx_expiration_date": "2016 Sep 09 13:12:31 UTC",
"block_preordered_at": 373821,
"block_renewed_at": 373821,
"expire_block": 426416,
"has_zonefile": true,
"last_transaction_height": 402804,
"last_transaction_id": "904c5f187ab143d187e26afaddaa6061059451407193fbfc4c4a9b0baa24dbd7",
"owner_address": "1QJQxDas5JhdiXhEbNS14iNjr8auFT96GP",
"owner_script": "76a914ff95f5612a26a81e919e4b6e63fdd929fd115d6d88ac",
"zonefile_hash": "3085137b19ce56092f5cb91b7f78d073c815dbc1"
}
```
This information includes the block heights at which the name was preordered (for the first time ever), when it was registered to its curent owner, when it will expire, and when the last transaction (whose ID is given) that affected the name was seen. It also encodes the hash of the zonefile (stored off-chain), the owner's address (public key hash), and owner script (scriptPubKey from Bitcoin).
Note that the `approx_expiration_data` is *approxmiate*. The system uses the `expire_block` to determine when exactly the name expires; the date is extrapolated from the average block time. You should renew your name well before it expires, just to be sure the transaction gets accepted. We recommend doing it 1,000 blocks before it is set to expire.
### A Note on Legacy Profiles
Older profiles used a different structure for storing information. Looking them up will produce a "legacy" zonefile, as well as the profile it represents.
Legacy zonefiles do not look like DNS zonefiles at all. For example:
```
$ blockstack lookup muneeb.id
{
"profile": {
"@type": "Person",
"account": [
{
"@type": "Account",
"identifier": "muneeb",
"proofType": "http",
"service": "twitter"
},
{
"@type": "Account",
"identifier": "muneeb.ali",
"proofType": "http",
"service": "facebook"
},
{
"@type": "Account",
"identifier": "muneeb-ali",
"proofType": "http",
"service": "github"
},
{
"@type": "Account",
"identifier": "1LNLCwtigWAvLkNakUK4jnmmvdVvmULeES",
"role": "payment",
"service": "bitcoin"
},
{
"@type": "Account",
"contentUrl": "http://muneebali.com/static/files/key.asc",
"identifier": "9862A3FB338BE9EB6C6A5E05639C89272AFEC540",
"role": "key",
"service": "pgp"
}
],
"address": {
"@type": "PostalAddress",
"addressLocality": "New York, NY"
},
"description": "Co-founder of Onename (YC S14), final-year PhD candidate at Princeton. Interested in distributed systems and blockchains.",
"image": [
{
"@type": "ImageObject",
"contentUrl": "https://s3.amazonaws.com/kd4/muneeb",
"name": "avatar"
},
{
"@type": "ImageObject",
"contentUrl": "https://s3.amazonaws.com/dx3/muneeb",
"name": "cover"
}
],
"name": "Muneeb Ali",
"website": [
{
"@type": "WebSite",
"url": "http://muneebali.com"
}
]
},
"zonefile": {
"avatar": {
"url": "https://s3.amazonaws.com/kd4/muneeb"
},
"bio": "Co-founder of Onename (YC S14), final-year PhD candidate at Princeton. Interested in distributed systems and blockchains.",
"bitcoin": {
"address": "1LNLCwtigWAvLkNakUK4jnmmvdVvmULeES"
},
"cover": {
"url": "https://s3.amazonaws.com/dx3/muneeb"
},
"facebook": {
"proof": {
"url": "https://facebook.com/muneeb.ali/posts/10152524743274123"
},
"username": "muneeb.ali"
},
"github": {
"proof": {
"url": "https://gist.github.com/muneeb-ali/0f00d4da967646ee0bc3"
},
"username": "muneeb-ali"
},
"graph": {
"followee_count": 4,
"url": "https://s3.amazonaws.com/grph/muneeb"
},
"location": {
"formatted": "New York, NY"
},
"name": {
"formatted": "Muneeb Ali"
},
"pgp": {
"fingerprint": "9862A3FB338BE9EB6C6A5E05639C89272AFEC540",
"url": "http://muneebali.com/static/files/key.asc"
},
"twitter": {
"proof": {
"url": "https://twitter.com/muneeb/status/483765788478689280"
},
"username": "muneeb"
},
"v": "0.2",
"website": "http://muneebali.com"
}
}
```
## Blockstack Wallet
The Blockstack wallet has three keys: your payment key, your ownership key (i.e. the key that owns the names), and your data key (i.e. the key that signs your profile data).
In the basic mode of operation, you can query information about them with these commands:
* `blockstack balance`: Query your payment account balance (excludes transactions with less than 6 confirmations).
* `blockstack deposit`: Get your payment address information. This is the address that **pays for names and transaction fees**.
* `blockstack import`: Get your name owner address. This is the address for **transferring a name to a different wallet**.
* `blockstack names`: See the list of names that are owned by your owner address.
## Registering a Name
To register a name, simply type:
```
$ blockstack register <YOUR NAME>.id
```
At this time, the name must end in `.id`. It will be registered in the `.id` namespace, since only the `.id` namespace exists (see [here](https://blockstack.org/docs/namespaces) for details).
You will be prompted to confirm the purchase, and (if you haven't entered it yet), you will be prompted for your wallet password.
If you'd like to see the price of a name, without actually purchasing it, you can use `blockstack price <YOUR NAME>.id`.
### A Note on Transaction Fees
The total name cost includes all the relevant transaction fees. However, fee prices are dynamic, and may change during the registration (which requires issuing three transactions).
To ensure timely registration, you should fill your payment address with **at least +0.001 BTC more than the name cost**.
## Migrating an Existing Name to the New Profile Schema
Some advanced options are disabled for older names registered through [Onename](https://onename.com). To enable them, you will need to migrate your name's off-chain data.
To do so, run `blockstack migrate <YOUR NAME>.id`. It will take about an hour and a half to complete, but only needs to be done once, and only if your name has a legacy zonefile (see above).
## Checking the Blockstack Server
You can track the progress of your name transactions with `blockstack info`, which will show you which names have unconfirmed transactions (and what kind they are). The CLI waits for 10 confirmations before considering it confirmed.
When registering a name, a name will pass through three states: `preorder`, `register`, and `update`. The first step registers your public key and the hash of the name, and waits for it to be confirmed (so no one can front-run you when you reveal the name). The second step reveals the name in the blockchain; you can look at the transaction in a block explorer and find it in the `OP_RETURN` data. The third stage sets up your zonefile and your profile, and writes your zonefile's hash to the blockchain.
## Other Operations
### Transferring a Name
You can send a name to a new ownership address with `blockstack transfer <YOUR NAME>.id <NEW ADDRESS>`.
### Renewing a Name
Names do not last forever, and must be periodically renewed. You can see when a name expires using `whois`, and renew it with `blockstack renew <YOUR NAME>.id`.
**If you do not renew your name, someone else can register it, and you will not be able to get it back.** The best alternative is to try to ask the new owner if (s)he will sell it back to you.
### Revoking a Name
If you lose your Blockstack wallet or the device(s) that host it, you have the option of revoking the name using a backed up copy of your wallet. To do so, type `blockstack revoke <YOUR NAME>.id`.
### Updating a Name's Zonefile
**OpenBazaar Users**: If you are trying to add your OpenBazaar GUID to your Blockstack ID, please follow [these instructions](https://github.com/blockstack/blockstack-cli/blob/master/docs/openbazaar.md) instead.
**CAUTION**: You almost never want to update your name's zonefile, since it's slow, tedious, and costs money. It is meant primarily for recovering from zonefile loss, for changing where people find your profile, and for changing your data public key. If you want to store data in your profile, please see the [data storage](https://github.com/blockstack/blockstack-cli/blob/master/docs/advanced_usage.md#data-storage) and [accounts](https://github.com/blockstack/blockstack-cli/blob/master/docs/advanced_usage.md#accounts) commands in the [advanced usage](https://github.com/blockstack/blockstack-cli/blob/master/docs/advanced_usage.md) section (but read the [warnings](https://github.com/blockstack/blockstack-cli/blob/master/docs/advanced_usage.md#a-word-of-warning) first).
If you want to change the name's zonefile, you can do so with `blockstack update`. You must specify the new zonefile to do so. For example:
```
$ blockstack update judecn.id '$ORIGIN judecn.id
> $TTL 3600
> pubkey TXT "pubkey:data:04cabba0b5b9a871dbaa11c044066e281c5feb57243c7d2a452f06a0d708613a46ced59f9f806e601b3353931d1e4a98d7040127f31016311050bedc0d4f1f62ff"
> _file URI 10 1 "file:///home/jude/.blockstack/storage-disk/mutable/judecn.id"
> _https._tcp URI 10 1 "https://blockstack.s3.amazonaws.com/judecn.id"
> _http._tcp URI 10 1 "http://node.blockstack.org:6264/RPC2#judecn.id"
> _dht._udp URI 10 1 "dht+udp://fc4d9c1481a6349fe99f0e3dd7261d67b23dadc5"
> '
```
The zonefile can be any valid DNS zonefile, but must follow these extra rules:
* There must be only one `$ORIGIN`, and it must be the blockstack ID.
* There must be at least one `URI` resource record.
* If you want to set a new data keypair, you must do so via a `TXT` record named `pubkey`, and the text field must start with `pubkey:data:` (as per the example). It must be an ECDSA public key.
**WARNING**: Each of the URLs must refer to the **signed JSON Web Token** (JWT) that encodes your profile data. The JWT can be signed either with the private key that owns your name, or with a private key that matches the `pubkey:data:` TXT record. If you do not do this, your profile **will not be readable** to the Blockstack CLI tool or to any public profile resolvers.

1342
_site/core/blockstack_naming_service.md

File diff suppressed because it is too large

530
_site/core/cli.md

@ -0,0 +1,530 @@
# Blockstack CLI
Blockstack CLI is both a command-line interface (CLI) tool, a system service (daemon), and a client (Python library) for interacting with Blockstack. It talks to Blockstack Core and provides an interface for interacting with it.
## Architecture Overview
Most of the complexity of Blockstack lives in its client library. Specifically, the library does the following:
* Generating and sending name operation transactions.
* Reading, writing, and deleting data in your storage providers (and reading other peoples' data from their storage providers).
* Handling data authenticity, encryption, and validation.
* Querying a Blockstack Server for blockchain-hosted information.
The CLI tool is a wrapper around the library. Most of its commands are thin wrappers around library functions.
In addition to a CLI tool and library, Blockstack CLI comes with a system service that runs in the background as a daemon. The daemon does the following:
* Acts as a personal registrar. It queues up all your name operation transactions, waits for them to be confirmed by the blockchain, sends them out, and replicates your zonefile and profile as needed.
* Hosts your wallet. Your wallet is never stored in plaintext; it only lives in the daemon's RAM (for when it needs to send out transactions).
* Allows programmatic access to a subset of CLI commands. This allows other programs on your computer to do things like look up Blockstack IDs, query their data, and so on. For security, the daemon will never serve the wallet via the API, nor does it expose any API call that can change data or send transactions (it is effectively a read-only API).
## Files
These files are created by Blockstack CLI:
### Files You Can Edit
These files define how the CLI behaves.
* `~/.blockstack/client.ini`: This is the CLI config file. You can interactively modify it with `blockstack configure`.
* `~/.blockstack/wallet.json`: This is your JSON-encoded wallet. It contains your password-encrypted keys.
### Files You Can Read
These files are useful primarily for troubleshooting.
* `~/.blockstack/api_endpoint.log`: This is the log for the system service that manages your wallet, sends your name operations, and accesses your profile and data. It's a great source for troubleshooting.
* `~/.blockstack/api_endpoint.pid`: This contains the PID of the system service.
* `~/.blockstack/metadata/`: This directory contains versioning information for mutable data from other profiles you have read. It gets used to stop malicious storage providers from serving you older versions of the data you've already seen.
* `~/.blockstack/storage-disk/`: If you use the `disk` storage driver (it is activated by default), then this is where it holds your zonefiles, profiles, and data.
### Files You Should NOT Edit
You shouldn't touch these files unless you're a developer, and even then, you should only do so at your own risk.
* `~/.blockstack/queues.db`: This is a SQLite database that contains queued-up transactions for name operations. If you want to remove any stuck transactions, use `blockstack unqueue` in the [advanced](https://github.com/blockstack/blockstack-cli/blob/master/docs/advanced_usage.md) usage.
* `~/.blockstack/registrar.lock`: This is a lockfile held by a thread in the registrar thread in the CLI daemon.
* `~/.blockstack/blockchain_headers.dat`: SPV headers.
* `~/.blockstack/client.uuid`: Used for anonymous statistics gathering purposes (which you can disable using `blockstack configure`). If you remove it, a new one will be generated.
## Getting Help
If you ever need help with these instructions or want to learn more, please join the [Blockstack Slack](https://blockstack.slack.com) and drop us a line on the \#cli channel.
## Installation
Installing the command line interface and client library:
### Debian + Ubuntu
Via APT:
```
$ curl https://raw.githubusercontent.com/blockstack/packaging/master/repo-key.pub | sudo apt-key add -
$ sudo sh -c "echo \"deb http://packages.blockstack.com/repositories/ubuntu xenial main\" > /etc/apt/sources.list.d/blockstack.list"
$ sudo apt-get update
$ sudo apt-get install blockstack
```
Via pip:
```
$ sudo apt-get update && sudo apt-get install -y python-pip python-dev libssl-dev libffi-dev rng-tools
$ sudo pip install blockstack --upgrade
```
### OS X
```bash
$ brew install libffi openssl
$ sudo pip install blockstack --upgrade
```
We recommend installing the CLI inside of a [virtual environment](http://docs.python-guide.org/en/latest/dev/virtualenvs/), in which case you can drop the "sudo" at the beginning like so:
```bash
$ pip install blockstack --upgrade
```
If the installation command above fails, see the [troubleshooting section](#troubleshooting-installation).
### Windows Subsystem for Linux
Installation will mirror `Debian + Ubuntu`, above, with an additional package.
```bash
$ sudo apt-get update && sudo apt-get install -y python-pip python-dev libssl-dev libffi-dev
```
```bash
$ sudo pip install functools32
$ sudo pip install blockstack
```
## Command-Line Reference
### Listing All Commands
```bash
$ blockstack
usage: blockstack [-h]
...
Blockstack cli version 0.14.0
positional arguments:
balance Get the account balance
configure Interactively configure the client
deposit Display the address with which to receive bitcoins
import Display the address with which to receive names
info Get details about pending name commands
lookup Get the zone file and profile for a particular name
migrate Migrate a profile to the latest profile format
names Display the names owned by local addresses
ping Check server status and get server details
price Get the price of a name
register Register a name
renew Renew a name
revoke Revoke a name
set_advanced_mode Enable advanced commands
transfer Transfer a name to a new address
update Set the zone file for a name
whois Look up the blockchain info for a name
optional arguments:
-h, --help show this help message and exit
```
### Info (or ping or status)
```bash
$ blockstack info
```
##### Examples
```bash
$ blockstack info
{
"advanced_mode": false,
"cli_version": "0.14.0",
"consensus_hash": "106d4648661d49e16d103b071e26617e",
"last_block_processed": 420518,
"last_block_seen": 420596,
"server_alive": true,
"server_host": "40.76.8.249",
"server_port": "6264",
"server_version": "0.14.0"
}
```
### Config
```bash
$ blockstack configure
```
##### Examples
```bash
$ blockstack configure
# ... interactive prompts ...
{
"path": "/home/jude/.blockstack/client.ini"
}
```
### Cost
```bash
$ blockstack price <name>
```
##### Examples
```bash
$ blockstack price $(whoami).id
{
"name_price": {
"btc": "0.00025",
"satoshis": "25000"
},
"preorder_tx_fee": {
"btc": "0.00047406",
"satoshis": "47406"
},
"register_tx_fee": {
"btc": "0.00046184",
"satoshis": "46184"
},
"total_estimated_cost": {
"btc": "0.00188394",
"satoshis": "188394"
},
"update_tx_fee": {
"btc": "0.00069804",
"satoshis": "69804"
}
}
```
### Whois
```bash
$ blockstack whois <name>
```
##### Examples
```bash
$ blockstack whois fredwilson.id
{
"block_preordered_at": 374084,
"block_renewed_at": 374084,
"expire_block": 426679,
"has_zonefile": true,
"last_transaction_id": "2986ec31ec957692d7f5bc58a3b02d2ac2d1a60039e9163365fc954ff51aeb5a",
"owner_address": "1F2nHEDLRJ39XxAvSxwQhJsaVzvS5RHDRM",
"owner_script": "76a91499e7f97f5d2c77b4f32b4ed9ae0f0385c45aa5c788ac",
"zonefile_hash": "1a587366368aaf8477d5ddcea2557dcbcc67073e"
}
```
```bash
$ blockstack whois $(whoami)_$(date +"%m_%d").id
Not found.
```
### Lookup
```bash
$ blockstack lookup <name>
```
##### Examples
```bash
$ blockstack lookup fredwilson.id
{
"profile": {
"avatar": {
"url": "https://s3.amazonaws.com/kd4/fredwilson1"
},
"bio": "I am a VC",
...
}
```
```bash
$ blockstack lookup $(whoami)_$(date +"%m_%d").id
Not found.
```
### Register
```bash
$ blockstack register <name>
```
##### Example
```bash
$ blockstack register $(whoami)_$(date +"%m_%d").id
Registering muneeb_02_22.id will cost 0.0002225 BTC. Continue? (y/n): y
{
"transaction_hash": "f576313b2ff4cc7cb0d25545e1e38e2d0d48a6ef486b7118e5ca0f8e8b98ae45",
"message": "The name has been queued up for registration and will take a few hours to go through. You can check on the status at any time by running 'blockstack info'."
"success": true
}
```
```bash
$ blockstack register fredwilson.id
fredwilson.id is already registered.
```
### Update
```bash
$ blockstack update <name> <data string or file with data>
```
##### Examples
```bash
$ echo > new_zone_file.txt <<EOF
$ORIGIN swiftonsecurity.id
$TTL 3600
pubkey TXT "pubkey:data:04cabba0b5b9a871dbaa11c044066e281c5feb57243c7d2a452f06a0d708613a46ced59f9f806e601b3353931d1e4a98d7040127f31016311050bedc0d4f1f62ff"
_file IN URI 10 1 "file:///Users/TaylorSwift/.blockstack/storage-disk/mutable/swiftonsecurity.id"
_https._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/swiftonsecurity.id"
_http._tcp IN URI 10 1 "http://node.blockstack.org:6264/RPC2#swiftonsecurity.id"
_dht._udp IN URI 10 1 "dht+udp://fc4d9c1481a6349fe99f0e3dd7261d67b23dadc5"
EOF
$ blockstack update swiftonsecurity.id new_zone_file.txt
{
"success": true,
"transaction_hash": "4e1f292c09ad8e03a5f228b589d9a7dc3699b495862bee3b40f2432ac497b134",
"message": "The name has been queued up for update and will take ~1 hour to process. You can check on the status at any time by running 'blockstack info'."
}
```
```bash
$ blockstack update muneeb.id '{"$origin": "muneeb.id", "$ttl": "3600", "uri": [{"name": "@", "priority": "10", "weight": "1", "target": "https://muneeb.ali/muneeb.id"}]}'
{
"success": true,
"transaction_hash": "4e1f292c09ad8e03a5f228b589d9a7dc3699b495862bee3b40f2432ac497b134",
"message": "The name has been queued up for update and will take ~1 hour to process. You can check on the status at any time by running 'blockstack info'."
}
```
```bash
$ blockstack update fredwilson.id '{}'
Invalid $origin; must use your name
$ blockstack update fredwilson.id '{"$origin": "fredwilson.id"}'
Missing $ttl; please supply a positive integer
$ blockstack update fredwilson.id '{"$origin": "fredwilson.id", "$ttl": "3600"}'
Zonefile is missing or has invalid URI and/or TXT records
$ blockstack update fredwilson.id '{"$origin": "fredwilson.id", "$ttl": "3600", "uri": [{"name": "@", "priority": "10", "weight": "1", "target": "https://blockstack.s3.amazonaws.com/fredwilson.id"}]}'
fredwilson.id is not in your possession.
```
### Transfer
```bash
$ blockstack transfer <name> <address>
```
##### Examples
```bash
$ blockstack transfer $(whoami)_$(date +"%m_%d").id 1Jbcrh9Lkwm73jXyxramFukViEtktwq8gt
{
"transaction_hash": "8a68d52d70cf06d819eb72a9a58f4dceda942db792ceb35dd333f43f55fa8713",
"message": "The name has been queued up for transfer and will take ~1 hour to process. You can check on the status at any time by running 'blockstack info'."
"success": true
}
```
```bash
$ blockstack transfer fredwilson.id 1Jbcrh9Lkwm73jXyxramFukViEtktwq8gt
fredwilson.id is not in your possession.
```
### Balance
```bash
$ blockstack balance
```
##### Examples
```bash
$ blockstack balance
{
"addresses": [
{
"address": "16yE3e928JakaXbympwSywyrJPM9cuL4wZ",
"bitcoin": 0.00959454,
"satoshis": 959454
}
],
"total_balance": {
"bitcoin": 0.00959454,
"satoshis": 959454
}
}
```
### Names
```bash
$ blockstack names
```
##### Examples
```bash
$ blockstack names
{
"addresses": [
{
"address": "16CtpS8LhmW3bGtVC69UGZ3wSwvi95BE8E",
"names_owned": [
"testregistration001.id",
"testregistration002.id"
]
}
],
"names_owned": [
"testregistration001.id",
"testregistration002.id"
]
}
```
### Deposit
```bash
$ blockstack deposit
```
##### Examples
```bash
$ blockstack deposit
{
"address": "1EHgqHVpA1tjn6RhaVj8bx6y5NGvBwoMNS",
"message": "Send bitcoins to the address specified.",
}
```
### Import
```bash
$ blockstack import
```
##### Examples
```bash
$ blockstack import
{
"address": "1Jbcrh9Lkwm73jXyxramFukViEtktwq8gt"
"message": "Send the name you want to receive to the address specified.",
}
```
## Troubleshooting Installation
**a) Error installing pycrypto**
If you see the following error, while pycrpyto installs on OS X:
```bash
error: command 'cc' failed with exit status 1
```
Try installing it with the following:
```bash
$ ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future pip install pycrypto
```
**b) Blockstack hangs while running in a VM**
If Blockstack hangs while performing one of the above operations while running in a VM, and you hit Ctrl+C, you
may see a stack trace like this:
```
Traceback (most recent call last):
File "/home/dev/blockstack-venv/bin/blockstack", line 67, in <module>
result = run_cli()
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/blockstack_client/cli.py", line 287, in run_cli
result = method( args, config_path=config_path )
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/blockstack_client/actions.py", line 479, in cli_price
fees = get_total_registration_fees( fqu, payment_privkey_info, owner_privkey_info, proxy=proxy, config_path=config_path, payment_address=payment_address )
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/blockstack_client/actions.py", line 271, in get_total_registration_fees
preorder_tx_fee = estimate_preorder_tx_fee( name, data['satoshis'], payment_address, utxo_client, owner_privkey_params=get_privkey_info_params(owner_privkey_info), config_path=config_path, include_dust=True )
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/blockstack_client/backend/nameops.py", line 116, in estimate_preorder_tx_fee
fake_privkey = make_fake_privkey_info( owner_privkey_params )
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/blockstack_client/backend/nameops.py", line 103, in make_fake_privkey_info
return virtualchain.make_multisig_wallet( m, n )
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/virtualchain/lib/blockchain/bitcoin_blockchain/multisig.py", line 82, in make_multisig_wallet
pk = BitcoinPrivateKey().to_wif()
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/pybitcoin/privatekey.py", line 55, in __init__
secret_exponent = random_secret_exponent(self._curve.order)
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/pybitcoin/privatekey.py", line 32, in random_secret_exponent
random_hex = hexlify(dev_random_entropy(32))
File "/home/dev/blockstack-venv/local/lib/python2.7/site-packages/utilitybelt/entropy.py", line 38, in dev_random_entropy
return open("/dev/random", "rb").read(numbytes)
KeyboardInterrupt
```
If so, the reason is because the VM does not have enough entropy. This causes reads to `/dev/random` to block
for a long time.
The solution is to install `rng-tools` and configure it to seed `/dev/random` with entropy from `/dev/urandom`.
Please see your distribution documentation for setting up `rng-tools`.
If the issue you are experiencing is not listed here, please
[report it as a new issue](https://github.com/blockstack/blockstack-client/issues/new).
## Running Your Server
The CLI by default talks to a remote server, but you can easily start your own server.
Open a new terminal window and run the following command:
```bash
$ blockstack-server start --foreground
```
You can now switch the cli to use the local server:
```bash
$ blockstack configure
...
server (default: 'node.blockstack.org'): 127.0.0.1
...
```
[More information on the Blockstack Server(http://github.com/blockstack/blockstack-server)
## Client Library
You can also import the blockstack client and write your own programs.
Here is some example code to get you started:
```python
from blockstack_client import client
from blockstack_client.utils import print_result as pprint
client.session(server_host='127.0.0.1', server_port=6264)
resp = client.ping()
pprint(resp)
```

385
_site/core/faq_technical.md

@ -0,0 +1,385 @@
# Blockstack Technical FAQ
This document lists frequently-asked questions and answers to technical
questions about Blockstack.
If you are new to Blockstack, you should read the
[non-technical FAQ](https://blockstack.org/faq) first.
If you have a technical question that gets frequently asked on the
[forum](https://forum.blockstack.org) or [Slack](https://blockstack.slack.com),
feel free to send a pull-request with the question and answer.
# General Questions
## What is Blockstack?
Blockstack is a new Internet for decentralized applications. Blockstack
applications differ from Web applications in two ways:
* **Users own their identities**. The user brings their identity to the
applications; applications do not require the user to create accounts and
passwords.
* **Users own their data**. Users control who can read it, and where it gets stored.
The application does not need to worry about hosting any user data.
The Blockstack project provides all of the infrastructure required for building
these kinds of applications.
## Is Blockstack decentralized?
Yes! The components that make up Blockstack do not have any central points of
control.
* The [Blockstack Naming Service](blockstack_naming_service.md) runs on top of
the Bitcoin blockchain, which itself is decentralized. It binds Blockstack
IDs to a small amount of on-chain data (usually a hash of off-chain data).
* The [Atlas Peer Network](atlas_network.md) stores chunks of data referenced by
names in BNS. It operates under similar design principles to BitTorrent, and
has no single points of failure. The network is self-healing---if a node
crashes, it quickly recovers all of its state from its peers.
* The [Gaia storage system](https://github.com/blockstack/gaia) lets users
choose where their application data gets hosted. Gaia reduces all storage
systems---from cloud storage to peer-to-peer networks---to dumb, interchangeable
hard drives. Users have maximum flexibility and control over their data in a
way that is transparent to app developers.
## Are Blockstack applications usable today?
Yes! Blockstack applications are as easy to use as normal Web applications, if
not easier. Moreover, they are just as performant if not more so.
If you install the [Blockstack
Browser](https://github.com/blockstack/blockstack-browser), or use our
[Web-hosted Blockstack Browser](https://browser.blockstack.org), you can get
started with them right away.
## Where does Blockstack keep my user account?
Your user account is ultimately controlled by a [private
key](https://en.wikipedia.org/wiki/Public-key_cryptography). You and only you
know what the private key is, and using your private key, you can prove to other
people that you own a particular piece of data (such as your Blockstack ID).
Your private key resides within your locally-running Blockstack Browser.
It never leaves your computer.
Your public keys are stored off-chain, and the *hash* of your public key is
stored on the Bitcoin blockchain. The [Blockstack Naming
Service](blockstack_naming_service.md) allows anyone to look up your public key
hash, given your Blockstack ID.
## Where does Blockstack keep my app data?
As a Blockstack user, you can choose exactly where your data gets stored.
Blockstack uses a decentralized storage system called
[Gaia](https://github.com/blockstack/gaia) to host your data. Gaia is different
from other storage systems because it lets you securely host your data wherever you want---in cloud
storage providers, on your personal server, or in another decentralized storage
system like BitTorrent or IPFS.
When you register, you are given a default Gaia hub that replicates your
data to a bucket in Microsoft Azure. However, you can configure and
deploy your own Gaia hub and have Blockstack store your data there instead.
The [Blockstack Naming Service](blockstack_naming_service.md) and the [Atlas
network](atlas_network.md) work together to help other users discover your
app-specific public data, given your Blockstack ID.
# Blockstack IDs
## What is a Blockstack ID?
Blockstack IDs are usernames. Unlike normal Web app usernames, Blockstack IDs
are usable *across every Blockstack app.* They fill a similar role to
centralized single-signon services like Facebook or Google. However, you and
only you control your Blockstack ID, and no one can track your logins.
## How do I get a Blockstack ID?
If you install the [Blockstack
Browser](https://github.com/blockstack/blockstack-browser) or use the
[Web-hosted Blockstack Browser](https://browser.blockstack.org), you can
purchase one with Bitcoin.
## Do I need a Blockstack ID to use Blockstack apps?
No, you can use Blockstack applications right away. However, if you want to
*share data with other users*, then you need a Blockstack ID.
## Why do I need a Blockstack ID?
Blockstack IDs are used to discover where you are keeping your
(publicly-readable) application data. For example, if `alice.id` wants to share
a document with `bob.id`, then `bob.id`'s browser uses the Blockstack ID
`alice.id` to look up where `alice.id` stored it.
The technical descriptions of how and why this works are quite long.
Please see the [Blockstack Naming Service](blockstack_naming_service.md)
documentation for a full description.
## What is a Blockstack Subdomain?
This is also a Blockstack ID, and can be used for all the things a Blockstack ID
can be used for. The only difference is that they have the format `foo.bar.baz`
instead of `bar.baz`. For example,
[jude.personal.id](https://core.blockstack.org/v1/users/jude.personal.id) is a
Blockstack ID, and is a subdomain of `personal.id`.
Subdomains are first-class Blockstack IDs---they can be used for all the same
things that an on-chain Blockstack ID can be used for, and they have all of
the same safety properties. They are globally unique, they are strongly owned
by a private key, and they are human-readable.
Subdomains are considerably cheaper than Blockstack IDs, since hundreds of them
can be registered with a single transaction. The [BNS
documentation](blockstack_naming_service.md) describes them in detail.
Subdomains provide a fast, inexpensive way to onboard many users at once.
## Can I get a Blockstack ID without spending Bitcoin?
Blockstack subdomains can be obtained without spending Bitcoin
by asking a subdomain registrar to create one for you.
## Is there a Blockstack name explorer?
Yes! It's at https://explorer.blockstack.org
# Blockstack App Development
## I'm a Web developer. Can I build on Blockstack?
Yes! Blockstack is geared primarily towards Web developers. All of your
existing knowledge is immediately applicable to Blockstack. Anything you can do
in a Web browser, you can do in a Blockstack app.
## I'm a non-Web developer. Can I build on Blockstack?
Yes! Blockstack implements a [RESTful API](https://core.blockstack.org) which
lets you interact with Blockstack from any language and any runtime. In fact,
the reference client
([blockstack.js](https://github.com/blockstack/blockstack.js)) is mainly a
wrapper around these RESTful API calls, so you won't be missing much by using a
language other than Javascript.
## What's the difference between a Web app and a Blockstack app?
Blockstack apps are built like [single-page Web
apps](https://en.wikipedia.org/wiki/Single-page_application)---they are, in
fact, a type of Web application.
Blockstack apps are a subset of Web applications that use Blockstack's
technology to preserve the user's control over their identities and data.
As such, they tend to be simpler
in design and operation, since in many cases they don't have to host anything
besides the application's assets.
## Do I need to learn any new languages or frameworks?
No. Blockstack applications are built using existing Web frameworks and programming
The only new thing you need to learn is either [blockstack.js](https://github.com/blockstack/blockstack.js) or
the [Blockstack RESTful API](https://core.blockstack.org).
## How does my Web app interact with Blockstack?
The [blockstack.js](https://github.com/blockstack/blockstack.js) library gives
any Web application the ability to interact with Blockstack's authentication and
storage services. In addition, we supply a [public RESTful API](https://core.blockstack.org).
## What does `blockstack.js` do?
This is the reference client implementation for Blockstack. You use it in your
Web app to do the following:
* Authenticate users
* Load and store user data
* Read other users' public data
## How do I use `blockstack.js`?
Please see the API documentation [here](https://github.com/blockstack/blockstack.js).
## How can I look up names and profiles?
You can use `blockstack.js`, or you can use the [public Blockstack Core
endpoint](https://core.blockstack.org).
## How can I read my public app data without `blockstack.js`?
The URLs to a user's public app data are in a canonical location in their
profile. For example, here's how you would get public data from the
[Publik](https://publik.ykliao.com) app, stored under the Blockstack ID `ryan.id`.
1. Get the bucket URL
```bash
$ BUCKET_URL="$(curl -sL https://core.blockstack.org/v1/users/ryan.id | jq -r '."ryan.id"["profile"]["apps"]["http://publik.ykliao.com"]')"
$ echo "$BUCKET_URL"
https://gaia.blockstack.org/hub/1FrZTGQ8DM9TMPfGXtXMUvt2NNebLiSzad/
```
2. Get the data
```bash
$ curl -sL "${BUCKET_URL%%/}/statuses.json"
[{"id":0,"text":"Hello, Blockstack!","created_at":1515786983492}]
```
## How do I register Blockstack IDs?
You should use the [Blockstack Browser](https://github.com/blockstack/blockstack-browser).
## How do I register Blockstack Subdomains?
You can deploy and use a [Blockstack Subdomain Registrar](subdomains.md), or
use an existing one.
## Can I programmatically register Blockstack IDs?
Blockstack applications do not currently have
have access to the user's wallet. Users are expected to
register Blockstack IDs themselves.
However, if you feel particularly ambitious, you can do one of the following:
* Set up a `blockstack api` endpoint (see the project [README](../README.md)) and write a
program to automatically register names. Also, see the [API
documentation](https://blockstack.github.io/blockstack-core/#managing-names-register-a-name)
for registering names on this endpoint.
* Write a `node.js` program that uses `blockstack.js` to register
names. This is currently in development.
## Can I programmatically register Blockstack Subdomains?
Yes! Once you deploy your own subdomain registrar, you can have your Web app
send it requests to register subdomains on your Blockstack ID. You can also
create a program that drives subdomain registration on your Blockstack ID.
## Do you have a testnet or sandbox to experiment with Blockstack?
We have an [integration test framework](../integration_tests) that provides a
private Blockstack testnet. It uses `bitcoin -regtest` to create a private
blockchain that you can interact with, without having to spend any Bitcoin or
having to wait for blocks to confirm. Please see the
[README](../integration_tests/README.md) for details.
## Does Blockstack have a smart contract system?
No, not yet. This is because
Blockstack's design philosophy focuses on keeping system complexity at the
"edges" of the network (e.g. clients), instead of the "core" of the network (e.g.
the blockchain), in accordance with the [end-to-end
principle](https://en.wikipedia.org/wiki/End-to-end_principle).
Generally speaking, this can be interpreted as "if you can do X without
a smart contract, you should do X without a smart contract." This organizing
principle applies to a lot of useful decentralized applications.
## Can Blockstack applications interact with Bitcoin? Ethereum? Smart contracts? Other blockchains?
Yes! Since Blockstack applications are built like Web applications, all you need to do is include the
relevant Javascript library into your application.
## Do you have a Blockstack app development tutorial?
Yes! See [here](https://blockstack.org/tutorials).
# Comparisons to Other Systems
## Blockstack vs DNS
Blockstack and DNS both implement naming systems, but in fundamentally
different ways. Blockstack *can be used* for resolving host names to IP
addresses, but this is not its default use-case. The [Blockstack Naming
Service](blockstack_naming_service.md) (BNS) instead behaves
more like a decentralized
[LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) system for
resolving user names to user data.
While DNS and BNS handle different problems, they share some terminology and
serialization formats. However, it is important to recognize that this is the
*only* thing they have in common---BNS has fundamentally different semantics
than DNS:
* **Zone files**: Blockstack stores a DNS zone file for each name. However,
the semantics of a BNS zone file are nothing like the semantics of a DNS zone
file---the only thing they have in common is their format.
A "standard" Blockstack zone files only have `URI` and `TXT` resource records
that point to the user's application data. Moreover, a Blockstack ID has a
*history* of zone files, and historic zone files can alter the way in which a
Blockstack ID gets resolved (DNS has no such concept). It is conceivable that an advanced
user could add `A` and `AAAA` records to their Blockstack ID's zone file,
but these are not honored by any Blockstack software at this time.
* **Subdomains**: Blockstack has the concept of a subdomain, but it is
semantically very different from a DNS subdomain. In Blockstack, a subdomain
is a Blockstack ID whose state and transaction history are anchored to the
blockchain, but stored within an on-chain Blockstack ID's zone file history.
Unlike DNS subdomains, a BNS subdomain has
its own owner and is a first-class BNS name---all subdomains are resolvable,
and only the subdomain's owner can update the subdomain's records. The only thing BNS subdomains and DNS
subdomains have in common is the name format (e.g. `foo.bar.baz` is a subdomain
of `bar.baz` in both DNS and BNS).
More details can be found in the [Blockstack vs
DNS](https://blockstack.org/docs/blockstack-vs-dns) document. A feature
comparison can be found at the end of the [Blockstack Naming
Service](blockstack_naming_service.md) document.
## Blockstack vs Namecoin
Namecoin also implements a decentralized naming service on top of a blockchain,
just like BNS. In fact, early versions of Blockstack were built on Namecoin.
However, [it was discovered](https://www.usenix.org/node/196209) that Namecoin's
merged mining with Bitcoin regularly placed it under the *de facto* control of a single
miner. This prompted a re-architecting of the system to be *portable* across
blockchains, so that if Blockstack's underlying blockchain (currently Bitcoin)
ever became insecure, the system could migrate to a more secure blockchain.
A feature comparison can be found at the end of the [Blockstack Naming
Service](blockstack_naming_service.md) document.
## Blockstack vs ENS
ENS also implements a decentralized naming system on top of a blockchain, but as
a smart contract on Ethereum. Like BNS, ENS is geared towards resolving names
to off-chain state (ENS names resolve to a hash, for example). Moreover, ENS is
geared towards providing programmatic control over names with Turing-complete
on-chain resolvers.
BNS has a fundamentally different relationship with blockchains than ENS.
WHereas ENS tries to use on-chain logic as much as possible, BNS
tries to use the blockchain as little as possible. BNS only uses it to store a
database log for name operations (which are interpreted with an off-chain BNS
node like Blockstack Core). BNS name state and BNS subdomains reside entirely
off-chain in the Atlas network. This has allowed BNS to migrate from blockchain
to blockchain in order to survive individual blockchain failures, and this has
allowed BNS developers to upgrade its consensus rules without having to get the
blockchain's permission (see the [virtualchain
paper](https://blockstack.org/virtualchain_dccl2016.pdf) for details).
A feature comparison can be found at the end of the [Blockstack Naming
Service](blockstack_naming_service.md) document.
## Blockstack vs Ethereum
Blockstack and Ethereum both strive to provide a decentralized application
platform. Blockstack's design philosophy differs from Ethereum's design
philosophy in that Blockstack emphasizes treating the blockchain as a "dumb
ledger" with no special functionality or properties beyond a few bare minimum
requirements. Instead, it strives to do everything off-chain---an application of the [end-to-end principle](https://en.wikipedia.org/wiki/End-to-end_principle).
Most Blockstack applications do *not*
interact with the blockchain, and instead interact with Blockstack
infrastructure through client libraries and RESTful endpoints.
This is evidenced by Blockstack's decision to implement its naming system (BNS), discovery and routing system
(Atlas), and storage system (Gaia) as blockchain-agnostic components that can be
ported from one blockchain to another.
Ethereum takes the opposite approach. Ethereum dapps are expected to interface
directly with on-chain smart contract logic, and are expected to host a
non-trivial amount of state in the blockchain itself. This is necessary for
them, because many Ethereum dapps' business logic is centered around the
mechanics of an ERC20 token.
Blockstack does not implement a smart contract system (yet), but it will soon
implement a [native token](https://blockstack.com/distribution.pdf) that will be
accessible to Blockstack applications.

BIN
_site/core/figures/test-screen.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

3
_site/core/gaia.md

@ -0,0 +1,3 @@
# Gaia Documentation
This document has moved to the [Gaia repository](https://github.com/blockstack/gaia)

148
_site/core/glossary.md

@ -0,0 +1,148 @@
# Glossary
Commonly used terms and jargon in Blockstack
## Account
A field in a profile that links the name to an existing service, like Twitter or OpenBazaar. They are listed under the `accounts` listing in a profile.
Some accounts serve as social proofs, but they can contain any data the user wants.
## Atlas
A peer-to-peer network maintained by Blockstack Core nodes that stores each
name's zone files and immutable data. See [this document](atlas_network.md) for
details.
## Blockstack ID
(Also called a "name").
A human-readable name in Blockstack. It is comprised only of upper and lower-case ASCII characters, numbers, as well as `-`, `_`, and `.`. It must end with a `.`, followed by a namespace ID. It has at least 3 characters, and at most 37 (including the `.` and the namespace ID).
Anyone can register a Blockstack ID, such as through the [Blockstack Browser](https://github.com/blockstack/blockstack-browser)
## Blockstack Core
A server that reads a blockchain with [virtualchain](https://github.com/blockstack/blockstack-virtualchain), filters out transactions that represent name operations, and builds up a database of (name, public key, state value) triples.
## Blockstack Naming Service (BNS)
This is the naming protocol that Blockstack Core implements. See [this
document](blockstack_naming_service.md) for details.
## Consensus Hash
A cryptographic hash that represents a proof-of-computation by a Blockstack Core node. Two Blockstack Core nodes have seen and processed the same name operations up to block `n` if and only if they each calculate the same consensus hash at height `n`.
A Blockstack Core node only accepts a name operation if it has a previously-calculated but recent consensus hash. Blockstack clients obtain a consensus hash from a Blockstack Core node in order to construct a name operation.
## Gaia
This is Blockstack's storage system. Gaia hosts all of your app-specific data.
## Gaia Hub
This is a publicly-routable server that serves as an entry point for Gaia data.
Anyone can stand up and run a Gaia hub by following [these
instructions](https://github.com/blockstack/gaia).
Blockstack provides a [default Gaia hub](https://gaia.blockstack.org).
## Immutable Data
This is the general term for chunks of data whose hash is cryptographically
bound to a blockchain transaction. This includes all data stored in the Atlas
network (such as your Blockstack ID's zone file),
as well as any data whose hash is stored in the Atlas network.
## Mutable Data
This is the general term for data that is (1) signed by your Blockstack ID, and
(2) can be looked up using your Blockstack ID. This includes all your Gaia
data, as well as your profile.
## Name
See Blockstack ID.
## Name Database
The set of (name, public key, name state) triples that the Blockstack Core node generates by reading the blockchain. The name state is usually the hash of a DNS zone file stored in Atlas.
## Name Operation
A specially-crafted transaction in the underlying blockchain that, when processed, will change each Blockstack Core's name database. Examples include `NAME_PREORDER` (preorders a name), `NAME_REGISTRATION` (registers a name), `NAME_UPDATE` (changes a name's zonefile hash), `NAME_TRANSFER` (changes a name's public key), and `NAME_REVOKE` (locks everyone out of a name until it expires).
Name operations are encoded on Bitcoin as `OP_RETURN` outputs that start with `id`, followed by a 1-byte character that identifies the particular operation.
See the [wire format](wire-format.md) document for details.
## Namespace
Analogous to a DNS TLD, it represents a grouping of names. All names under the same namespace have the same pricing and lifetime rules.
Anyone can create a namespace, but doing so is expensive by design. See the
[namespace creation](namespace_creation.md) tutorial for details.
## Preorder
The first of two steps to acquire a name. This operation writes the hash of both the name and the address that will own it.
## Profile
A signed JSON web token that describes a [Person](https://schema.org/Person), which describes the name's owner. You can put anything you want into your profile.
Additionally, profiles hold lists of social verifications and pointers to your Gaia data.
## Register
(1) The act of acquiring a name in Blockstack.
(2) The second of two steps to create a new name entry in the name database. Reveals the name as plaintext to the world. Must match a recent preorder to be accepted.
## Registrar
An online service that lets you sign up for and manage the profiles of Blockstack IDs.
## Resolver
An online service that displays zonefile and profile data for a Blockstack ID. [The Blockstack Explorer](https://explorer.blockstack.org) is a resolver.
## Social proof
A post in an account on an existing Web service like Twitter, Facebook, or GitHub that points back to a Blockstack ID. Used to provide some evidence that the person who owns the Blockstack ID is also the person who owns the Web service account.
Social proofs are listed in your profile.
## Storage Provider
This is any service that can serve your zone file, profile, or data. In all cases, the data is signed by one of your wallet's keys, so you can use any provider without having to worry about it trying to change the data.
Storage providers are accessed through a Gaia hub. Gaia hubs ship with drivers
that allow them to treat storage providers as dumb hard drives, which store
signed encrypted data on the hub's behalf.
Not all storage providers support writes--some of them are read-only.
Supported storage providers today include:
* Amazon S3
* Dropbox
* Your harddrive
* Any HTTP/HTTPS/FTP server (read-only)
* Any public-use Gaia hub
* IPFS
Support is being added for:
* Google Drive
* Microsoft OneDrive
* Box.com
* BitTorrent
If you have a preferred storage provider, and you're a developer, please consider sending us a pull request to add support for it!
## Zone file
A specially-formatted file that stores routing information for a Blockstack ID.
Blockstack clients use your zone file to find out where your preferred Gaia
hub(s) are. Ever Blockstack Core node stores a copy of every zone file for
every Blockstack ID by participating in the Atlas network.

80
_site/core/install-api.md

@ -0,0 +1,80 @@
# Blockstack API
Step-by-step instructions for deploying a Blockstack API node on Debian or
Ubuntu are below.
- **Step 1:** Make sure you have Blockstack Core running locally (see [instructions](https://github.com/blockstack/blockstack-core/blob/master/README.md#quick-start)).
- **Step 2:** Make sure you have [virtualenv installed](http://docs.python-guide.org/en/latest/dev/virtualenvs/).
Then, setup the API:
```
$ sudo apt-get install -y python-pip memcached rng-tools python-dev libmemcached-dev zlib1g-dev libgmp-dev libffi-dev libssl-dev
$ sudo service memcached start
$ sudo pip install virtualenv
$ sudo npm -g install aglio
$ virtualenv api && source api/bin/activate
$ git clone https://github.com/blockstack/blockstack-core.git
$ cd blockstack-core/
$ pip install .
$ pip install -r api/requirements.txt
$ blockstack setup_wallet
$ blockstack api start
$ deactivate
$ ./build_docs.sh public_api
```
### Search Subsystem
If you want to enable the search subsystem in your installation, you can
follow the instructions [here](search.md).
### Nginx Deployment
For a production deployment we recommend using nginx and uwsgi:
- **Step 1:** Install nginx and uWSGI:
```
$ sudo apt-get install -y nginx
$ sudo pip install uwsgi
```
- **Step 2:** Copy [this sample nginx sites file](../api/nginx/config/nginx_sites-available/blockstack_api) to
> /etc/nginx/sites-available/blockstack_api
and edit the paths depending on the uwsgi blockstack_api socket directory (defaults to /tmp/blockstack_api.sock)
You can test your nginx settings:
```
$ sudo nginx -t
```
- **Step 3:** Copy [this sample systemd service file](../api/nginx/config/systemd_system/blockstack_api.service) to
> /etc/systemd/system/blockstack_api.service
and edit the service user and blockstack paths depending on where your blockstack repo is located, and
where your virtualenv is located.
Note: The following sed commands will work if the virtualenv is currently active and your shell is in the repo's root directory.
```
$ sudo sed -i "s/User\=USER/User\=$USER/" /etc/systemd/system/blockstack_api.service
$ sudo sed -i "s#/path/to/blockstack#$PWD#" /etc/systemd/system/blockstack_api.service
$ sudo sed -i "s#/path/to/virtualenv#$VIRTUAL_ENV#" /etc/systemd/system/blockstack_api.service
```
- **Step 4:** Get a security certificate from [Let's Encrypt](https://letsencrypt.org/).
```
$ git clone https://github.com/certbot/certbot.git
$ cd certbot/
$ ./certbot-auto --nginx -d <your_domain>
```
And copy the cert files to the path given in the nginx sites file earlier.
- **Step 5:** Start nginx and the Blockstack API uwsgi server:
```
sudo systemctl restart blockstack_api
sudo systemctl restart nginx
```
If you run into any issues, please [submit a Github issue](https://github.com/blockstack/blockstack-core/issues) and we'll update these
instructions.

3
_site/core/interactive_regtest_macos.md

@ -0,0 +1,3 @@
Documentation for setting up the regtest mode for Blockstack Browser
using core's integration tests in macOS and Linux has
moved [here](../integration_tests).

42
_site/core/memcached.md

@ -0,0 +1,42 @@
Installing Memcached
=======
The Blockstack API optionally uses memcached and pylibmc for scaling read-only
calls. If you want to enable this functionality then you should have memcached
running locally.
### Memcached on Debian & Ubuntu:
```
$ sudo apt-get install -y python-dev libmemcached-dev zlib1g-dev
$ pip install pylibmc
```
### Memcached on macOS:
Easiest way to install memcached on macOS is by using [Homebrew](https://brew.sh/).
After installing Homebrew:
```
$ brew install memcached
$ brew install libmemcached
$ pip install pylibmc --install-option="--with-libmemcached=/usr/local/Cellar/libmemcached/1.0.18_1/"
```
After installing, you can start memcached and check if it's running properly:
```
$ memcached -d
$ echo stats | nc localhost 11211
```
### Memcached on Heroku
To deploy on Heroku:
```bash
$ heroku create
$ heroku addons:add memcachedcloud
$ git push heroku master
```

589
_site/core/namespace_creation.md

@ -0,0 +1,589 @@
# Creating a Namespace
**WARNING**: If you intend to create a namespace, you must read this document
_in its entirety_. You should also _install the test framework_ and experiment
with your namespace's parameters. _FAILURE TO DO SO MAY RESULT IN IRRECOVERABLE
LOSS OF FUNDS._
**Before you begin**: Some basic familiarity with how Bitcoin works is required to
understand this tutorial. This includes:
* knowing the difference between mainnet, testnet, and regtest
* knowing about compressed and uncompressed ECDSA public keys
* knowing about base58-check encoding
* knowing how Bitcoin transactions are structured
* knowing how UTXOs work
## Overview
Creating a namespace is a three-step process. The first
step is to `preorder` the namespace, which broadcasts a salted hash of the
namespace ID. The second step is to `reveal` the namespace, which exposes the
namespace ID and price function to the blockchain. The final step is to `ready`
the namespace, which allows anyone to register names within it.
In between the `reveal` and `ready` steps, the namespace creator will have a
"lock" on the namespace that lasts for about 1 year. During this time period,
the namespace creator can `import` names. The `import` transaction lets the
namespace creator assign the name a zone file and an owner in one step.
## Before Trying This in Production...
Creating namespaces is expensive.
Be sure to test your namespace in our [integration test
framework](https://github.com/blockstack/blockstack-core/tree/master/integration_tests)
first! It will let you simulate any valid namespace configuration
you want at no risk to you.
### Setting up the Test Environment
In this example, we will use the test framework to create a private Bitcoin
blockchain on your computer, and then create a Blockstack namespace on it.
This will let you experiment with different namespace parameters
without spending actual BTC. The test framework uses `bitcoind -regtest`,
so all of the commands you'll run here will work identically on
mainnet.
To install the test framework, please follow these
[instructions](https://github.com/blockstack/blockstack-core/tree/master/integration_tests).
Once you have the test framework installed, you should run the `namespace_check` test in `--interactive-web` mode.
This will create an empty `.test` namespace and leave the test scenario running
once it finishes. You will be able to fund addresses and create new blocks via
your Web browser or via `curl`, as will be explained below. Also, you'll be able to use the
`blockstack` utility to interact with your private blockchain and namespaces.
The test setup command is as follows. This will launch the `namespace_check`
test scenario, and open a web server on port 3001.
```bash
$ blockstack-test-scenario --interactive-web 3001 blockstack_integration_tests.scenarios.namespace_check
```
When the test is ready for us to experiment, you should see the following:
```bash
An empty namespace called 'test' has been created
Feel free to experiment with other namespaces
Available keys with a balance:
* 6e50431b955fe73f079469b24f06480aee44e4519282686433195b3c4b5336ef01
* c244642ce0b4eb68da8e098facfcad889e3063c36a68b7951fb4c085de49df1b01
* f4c3907cb5769c28ff603c145db7fc39d7d26f69f726f8a7f995a40d3897bb5201
* 8f87d1ea26d03259371675ea3bd31231b67c5df0012c205c154764a124f5b8fe01
* bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01
* 2,3,6f432642c087c2d12749284d841b02421259c4e8178f25b91542c026ae6ced6d01,65268e6267b14eb52dc1ccc500dc2624a6e37d0a98280f3275413eacb1d2915d01,cdabc10f1ff3410082448b708c0f860a948197d55fb612cb328d7a5cc07a6c8a01
* 2,3,4c3ab2a0704dfd9fdc319cff2c3629b72ebda1580316c7fddf9fad1baa323e9601,75c9f091aa4f0b1544a59e0fce274fb1ac29d7f7e1cd020b66f941e5d260617b01,d62af1329e541871b244c4a3c69459e8666c40b683ffdcb504aa4adc6a559a7701
* 2,3,4b396393ca030b21bc44a5eba1bb557d04be1bfe974cbebc7a2c82b4bdfba14101,d81d4ef8123852403123d416b0b4fb25bcf9fa80e12aadbc08ffde8c8084a88001,d0482fbe39abd9d9d5c7b21bb5baadb4d50188b684218429f3171da9de206bb201
* 2,3,836dc3ac46fbe2bcd379d36b977969e5b6ef4127e111f2d3e2e7fb6f0ff1612e01,1528cb864588a6a5d77eda548fe81efc44180982e180ecf4c812c6be9788c76a01,9955cfdac199b8451ccd63ec5377a93df852dc97ea01afc47db7f870a402ff0501
```
You can determine that the test framework is live by going to
`http://localhost:3001` in your Web browser. From there, you can generate
blocks in the test framework's `bitcoind` node and you can fund any address in
the test framework.
Finally, you can use the `blockstack-test-env` command to set up your shell
environment variables so `blockstack` will interact with this test (instead of
mainnet). To do so, run the following in your shell:
```bash
$ . $(which blockstack-test-env) namespace_check
|blockstack-test namespace_check| $
```
You can verify that the environment variables by verifying that your `$PS1`
variable includes the name of your test (as shown above), and that some other
`BLOCKSTACK_`-prefixed variables are set:
```bash
|blockstack-test namespace_check| $ env | grep BLOCKSTACK
BLOCKSTACK_OLD_PS1=\u@\h:\w$
BLOCKSTACK_TESTNET=1
BLOCKSTACK_EPOCH_1_END_BLOCK=1
BLOCKSTACK_EPOCH_2_END_BLOCK=2
BLOCKSTACK_TEST=1
BLOCKSTACK_DEBUG=1
BLOCKSTACK_CLIENT_CONFIG=/tmp/blockstack-run-scenario.blockstack_integration_tests.scenarios.namespace_check/client/client.ini
```
## Registering a Namespace
Suppose we're going to create the `hello` namespace. The key
`6e50431b955fe73f079469b24f06480aee44e4519282686433195b3c4b5336ef01` will be the key that
*pays* for the namespace. The key
`c244642ce0b4eb68da8e098facfcad889e3063c36a68b7951fb4c085de49df1b01` will be the key that
*creates* the namespace. The creator key will be used to `import` names and
declare the namespace `ready`. The payment key will be used to both pay for the
namespace and receive name registration and renewal fees for the first year of
the namespace's lifetime.
In this example, we will set these keys as environment variables:
```bash
|blockstack-test namespace_check| $ export PAYMENT_PKEY="6e50431b955fe73f079469b24f06480aee44e4519282686433195b3c4b5336ef01"
|blockstack-test namespace_check| $ export CREATOR_PKEY="c244642ce0b4eb68da8e098facfcad889e3063c36a68b7951fb4c085de49df1b01"
```
#### Multisig Namespace Payment
If you want to use a multisig address to pay for your namespace (and collect
name registration fees), then instead of using
`6e50431b955fe73f079469b24f06480aee44e4519282686433195b3c4b5336ef01`, you should
use a string formatted as `m,n,pk1,pk2,...,pk_n`. `m` is the number of
signatures required, `n` is the number of private keys, and `pk1,pk2,...,pk_n`
are the private keys.
For example, you can use the following as your `PAYMENT_PKEY` to have a 2-of-3
multisig script pay for your namespace and collect name registration fees:
```bash
|blockstack-test namespace_check| $ export PAYMENT_PKEY="2,3,6f432642c087c2d12749284d841b02421259c4e8178f25b91542c026ae6ced6d01,65268e6267b14eb52dc1ccc500dc2624a6e37d0a98280f3275413eacb1d2915d01,cdabc10f1ff3410082448b708c0f860a948197d55fb612cb328d7a5cc07a6c8a01"
```
### Namespace preorder
The command to preorder the namespace would be:
```bash
|blockstack-test namespace_check| $ blockstack namespace_preorder hello "$PAYMENT_PKEY" "$CREATOR_PKEY"
```
You will be given a set of instructions on how to proceed to reveal and
launch the namespace. _READ THEM CAREFULLY_. You will be prompted to
explicitly acknowledge that you understand the main points of the instructions,
and that you understand the risks.
The command outputs some necessary information at the very end of its execution.
In particular, you will need to remember the transaction ID of the namespace
preorder. The command will help you do so.
Here is a sample output:
```bash
|blockstack-test namespace_check| $ blockstack namespace_preorder hello "$PAYMENT_PKEY" "$CREATOR_PKEY"
<...snip...>
Remember this transaction ID: b40dd1375ef63e5a40ee60d790ec6dccd06efcbac99d0cd5f3b07502a4ab05ac
You will need it for `blockstack namespace_reveal`
Wait until b40dd1375ef63e5a40ee60d790ec6dccd06efcbac99d0cd5f3b07502a4ab05ac has six (6) confirmations. Then, you can reveal `hello` with:
$ blockstack namespace_reveal "hello" "6e50431b955fe73f079469b24f06480aee44e4519282686433195b3c4b5336ef01" "c244642ce0b4eb68da8e098facfcad889e3063c36a68b7951fb4c085de49df1b01" "b40dd1375ef63e5a40ee60d790ec6dccd06efcbac99d0cd5f3b07502a4ab05ac"
{
"status": true,
"success": true,
"transaction_hash": "b40dd1375ef63e5a40ee60d790ec6dccd06efcbac99d0cd5f3b07502a4ab05ac"
}
```
If all goes well, you will get back a transaction hash (in this case, `b40dd1375ef63e5a40ee60d790ec6dccd06efcbac99d0cd5f3b07502a4ab05ac`).
To get Blockstack to process it, you will need to mine some blocks in the test framework (by default,
Blockstack will only accept a transaction that has 6 confirmations). To do
this, simply go to `http://localhost:3001` and generate at least 6 blocks. If you
observe the test log, you will see the Blockstack node process and accept it.
Note that when you do this live, you should wait for
at least 10 confirmations before sending the `reveal` transaction, just to be
safe.
### Namespace reveal
The command to reveal a preordered namespace is more complicated, since it
describes the price curve.
This command is **interactive**. The command to invoke it is as follows:
```bash
|blockstack-test namespace_check| $ blockstack namespace_reveal hello "$PAYMENT_PKEY" "$CREATOR_PKEY" "b40dd1375ef63e5a40ee60d790ec6dccd06efcbac99d0cd5f3b07502a4ab05ac"
```
When running the command, you will see the namespace creation wizard prompt you
with the price curve and the current values:
```
Name lifetimes (blocks): infinite
Price coefficient: 4
Price base: 4
Price bucket exponents: [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Non-alpha discount: 2
No-vowel discount: 5
Burn or receive fees? Receive to mr6nrMvvh44sR5MiX929mMXP5hqgaTr6fx
Name price formula:
(UNIT_COST = 10.0 satoshi):
buckets[min(len(name)-1, 15)]
UNIT_COST * coeff * base
cost(name) = -----------------------------------------------------
max(nonalpha_discount, no_vowel_discount)
Name price table:
| length | price | price, nonalpha | price, no vowel | price, both |
--------------------------------------------------------------------------
| 1 | 42949672960 | 8589934592 | 8589934592 | 8589934592 |
| 2 | 10737418240 | 5368709120 | 2147483648 | 2147483648 |
| 3 | 2684354560 | 1342177280 | 536870912 | 536870912 |
| 4 | 671088640 | 335544320 | 134217728 | 134217728 |
| 5 | 167772160 | 83886080 | 33554432 | 33554432 |
| 6 | 41943040 | 20971520 | 8388608 | 8388608 |
| 7 | 10485760 | 5242880 | 2097152 | 2097152 |
| 8 | 2621440 | 1310720 | 524288 | 524288 |
| 9 | 655360 | 327680 | 131072 | 131072 |
| 10 | 163840 | 81920 | 32768 | 32768 |
| 11 | 40960 | 20480 | 8192 | 8192 |
| 12 | 10240 | 5120 | 2048 | 2048 |
| 13 | 2560 | 1280 | 512 | 512 |
| 14 | 640 | 320 | 128 | 128 |
| 15 | 160 | 80 | 32 | 32 |
| 16+ | 40 | 20 | 10 | 10 |
What would you like to do?
(0) Set name lifetime in blocks (positive integer between 1 and 4294967295, or "infinite")
(1) Set price coefficient (positive integer between 1 and 255)
(2) Set base price (positive integer between 1 and 255)
(3) Set price bucket exponents (16 comma-separated integers, each between 1 and 15)
(4) Set non-alphanumeric character discount (positive integer between 1 and 15)
(5) Set no-vowel discount (positive integer between 1 and 15)
(6) Toggle collecting name fees (True: receive fees; False: burn fees)
(7) Show name price formula
(8) Show price table
(9) Done
(1-9)
```
All prices are in the "fundamental unit" of the underlying blockchain (i.e.
satoshis).
As the formula describes, the name's price is a function of:
* a fixed unit cost (`UNIT_COST`)
* a multiplicative constant coefficient (`coeff`)
* a fixed exponential base (`base`)
* a 16-element list of price buckets, indexed by the length of the name (`buckets`)
* a discount for having non-alphnumeric letters (`nonalpha_discount`)
* a discount for having no vowels in the name (`no_vowel_discount`)
You can use options 1 through 8 to play with the pricing function and examine
the name costs in the price table. Enter 9 to send the transaction itself.
Once you're happy, you can issue the namespace-reveal transaction. As with the
namespace-preorder transaction, you will get back a transaction hash, and your transaction will be
unconfirmed. Simply go to `http://localhost:3001` to generate some more blocks
to confirm your namespace-reveal.
Once you have confirmed your namespace-reveal transaction, you can
begin to populate your namespace with some initial names.
**Collecting Name Fees**
Blockstack 0.17 introduced the ability to create a namespace such that for the
first year of its existence (54595 blocks), all name registration and renewal
fees will be sent to the address of the _payment key_. In this example,
this is the address `mr6nrMvvh44sR5MiX929mMXP5hqgaTr6fx`.
The alternative is to
have all namespace fees sent to an unspendable burn address
(`1111111111111111111114oLvT2`). This is the case for the `.id` namespace,
for example.
After the year has passed, all future name registrations and renewal fees
will be sent to the unspendable burn address. This is to disincentivize
namespace squatters.
**Warnings**
* You must issue this command **within 144 blocks** of the namespace-preorder transaction. Otherwise, the preorder will expire and you will need to start over from scratch.
### Importing names
After sending the `reveal` transaction, you can populate your namespace with
some initial names. You can do so with the `name_import` command.
Suppose we want to import the name `example.hello` and assign it to an owner
whose public key address is `ms6Y32bcL5zhA57e8tf7awgVZuPxV8Xg8N`. Suppose also
that you wanted to give `example.hello` an initial zone file stored at
`/var/blockstack/zone_files/example.hello`. To do so, you would issue the
following command:
```bash
|blockstack-test namespace_check| $ blockstack name_import example.hello ms6Y32bcL5zhA57e8tf7awgVZuPxV8Xg8N /var/blockstack/zone_files/example.hello "$CREATOR_PKEY"
```
By default, you **must** use the private key you used to reveal the namespace
to import names (this is `$CREATOR_PKEY` in this example).
As with namespace-preorder and namespace-reveal, the transaction this command
generates will be unconfirmed. Simply go to `http://localhost:3001` to generate
some blocks to confirm it.
You can check the progress of the transaction with `blockstack info`, as follows:
```bash
|blockstack-test namespace_check| $ blockstack info
{
"cli_version": "0.17.0.8",
"consensus_hash": "b10fdd38a20a7e46555ce3a7f68cf95c",
"last_block_processed": 694,
"last_block_seen": 694,
"queues": {
"name_import": [
{
"confirmations": 1,
"name": "example.hello",
"tx_hash": "10f7dcd9d6963ef5d20d010f731d5d2ddb76163a083b9d7a2b9fd4515c7fe58c"
}
]
},
"server_alive": true,
"server_host": "localhost",
"server_port": 16264,
"server_version": "0.17.0.8"
}
```
The `confirmation` field indicates how deep in the blockchain the transaction is
at the time. Generating more blocks will increase its number of confirmations.
When you do this live,
**YOU SHOULD LEAVE YOUR COMPUTER RUNNING UNTIL THE `name_import` QUEUE IS EMPTY**.
Blockstack's background API daemon will monitor the transactions and upload the
name's zone file to the Blockstack Atlas network once it is confirmed.
But to do so, your computer must remain online. If you do not do this, then
the name will not have a zone file and will be unusable in the higher layers of
Blockstack-powered software (including Blockstack applications). However,
if your computer does go offline or reboots, you can recover by
restarting the Blockstack API daemon (with
`blockstack api start`). The daemon itself will pick up where it left off, and
replicate all zone files that have confirmed transactions.
After the zone file is uploaded, the name will be public and resolvable. You can re-import the
same name over and over, and give it a different address and/or zone file. Like
all other names, the Blockstack Atlas network will accept and propagate zone
files for imported names.
The owner of the address `ms6Y32bcL5zhA57e8tf7awgVZuPxV8Xg8N` will **not** be
able to issue any transactions for the name `example.hello` until the namespace
creator has sent the `ready` transaction.
#### Using multiple private keys for NAME_IMPORT
Bitcoin itself imposes limits on how fast you can send transactions from the
same key (limited by a maximum UTXO-chain length). To work around this,
Blockstack lets you import names by using up to 300 private keys. The private
keys you can use are BIP32 unhardened children of the namespace reveal key (i.e.
`$CREATOR_PKEY` in this example).
The first name you import **must** use the namespace reveal private key
(`$CREATOR_PKEY` in this example). However, all future names you import in this
namespace can use one of the 300 BIP32 keys.
To get the list of keys you can use, you can use the `make_import_keys` command:
```bash
|blockstack-test namespace_check| $ blockstack make_import_keys example hello "$CREATOR_PKEY"
aeda50305ada40aaf53f2d8921aa717f1ec71a0a3b9b4c6397b3877f6d45c46501 (n4DVTuLLv5J1Yc17AoRYY1GtxDAuLGAESr)
92ff179901819a1ec7d32997ce3bb0d9a913895d5850cc05146722847128549201 (mib2KNBGR4az8GiUmusBZexVBqb9YB2gm5)
cc5b6a454e2b614bfa18f4deb9a8e179ab985634d63b7fedfaa59573472d209b01 (mxE2iqV4jdpn4K349Gy424TvZp6MPqSXve)
9b0265e0ac8c3c24fe1d79a734b3661ec2b5c0c2619bb6342356572b8235910101 (n4rGz8hkXTscUGWCwZvahrkEh6LHZVQUoa)
e2585af250404b7918cf6c91c6fa67f3401c0d1ae66df2fafa8fa132f4b9350f01 (moGNpEpighqc6FnkqyNVJA9xtfTiStr5YU)
{
"status": true
}
```
(NOTE: in the test environment, you get only 5 keys in order to save time).
You can use any of these keys to import names.
#### Trying it out
Here's an example walkthrough of how to try this out in the test framework:
1. Import the first name, creating a zone file in the process:
```bash
|blockstack-test namespace_check| $ cat > /var/blockstack/zone_files/example.hello <<EOF
> $ORIGIN example.hello
> $TTL 3600
> _file URI 10 1 "file:///home/blockstack-test/example.hello"
> EOF
|blockstack-test namespace_check| $ blockstack name_import example.hello ms6Y32bcL5zhA57e8tf7awgVZuPxV8Xg8N /var/blockstack/zone_files/example.hello "$CREATOR_PKEY"
Import cost breakdown:
{
"name_import_tx_fee": {
"btc": 0.0003342,
"satoshis": 33420
},
"total_estimated_cost": {
"btc": 0.0003342,
"satoshis": 33420
},
"total_tx_fees": 33420
}
Importing name 'example.hello' to be owned by 'ms6Y32bcL5zhA57e8tf7awgVZuPxV8Xg8N' with zone file hash '05c302430f4ed0a24470abf9df7e264d517fd389'
Proceed? (y/N) y
{
"status": true,
"success": true,
"transaction_hash": "bd875f00f63bcb718bb22782c88c3edcbed79663f2f9152deab328c48746f103",
"value_hash": "05c302430f4ed0a24470abf9df7e264d517fd389"
}
```
2. Advance the test framework blockchain, so the indexer knows which import keys to expect:
```bash
# NOTE: you can also do this by going to http://localhost:3001 in your Web browser
|blockstack-test namespace_check| $ curl -X POST http://localhost:3001/nextblock
```
3. Make import keys:
```bash
|blockstack-test namespace_check| $ blocksatck make_import_keys hello "$CREATOR_PKEY"
aeda50305ada40aaf53f2d8921aa717f1ec71a0a3b9b4c6397b3877f6d45c46501 (n4DVTuLLv5J1Yc17AoRYY1GtxDAuLGAESr)
92ff179901819a1ec7d32997ce3bb0d9a913895d5850cc05146722847128549201 (mib2KNBGR4az8GiUmusBZexVBqb9YB2gm5)
cc5b6a454e2b614bfa18f4deb9a8e179ab985634d63b7fedfaa59573472d209b01 (mxE2iqV4jdpn4K349Gy424TvZp6MPqSXve)
9b0265e0ac8c3c24fe1d79a734b3661ec2b5c0c2619bb6342356572b8235910101 (n4rGz8hkXTscUGWCwZvahrkEh6LHZVQUoa)
e2585af250404b7918cf6c91c6fa67f3401c0d1ae66df2fafa8fa132f4b9350f01 (moGNpEpighqc6FnkqyNVJA9xtfTiStr5YU)
{
"status": true
}
```
4. Fill up one of the addresses in the test framework, so we can fund `NAME_IMPORT` transactions with it:
```bash
# NOTE: you can also do this by going to http://localhost:3001 in your Web browser
|blockstack-test namespace_check| $ curl -X POST -F 'addr=n4DVTuLLv5J1Yc17AoRYY1GtxDAuLGAESr' -F 'value=100000000' 'http://localhost:3001/sendfunds'
```
5. Import another name, with the child private key we just funded:
```bash
|blockstack-test namespace_check| $ cat > /tmp/example.hello.zonefile <<EOF
> $ORIGIN example2.hello
> $TTL 3600
> _file URI 10 1 "file:///home/blockstack-test/example2.hello"
> EOF
|blockstack-test namespace_check| $ blockstack name_import example2.hello n3sFkNfBQPWS25G12DqDEqHRPiqHotAkEb /tmp/example.hello.zonefile aeda50305ada40aaf53f2d8921aa717f1ec71a0a3b9b4c6397b3877f6d45c46501
Import cost breakdown:
{
"name_import_tx_fee": {
"btc": 0.0003342,
"satoshis": 33420
},
"total_estimated_cost": {
"btc": 0.0003342,
"satoshis": 33420
},
"total_tx_fees": 33420
}
Importing name 'example2.hello' to be owned by 'n3sFkNfBQPWS25G12DqDEqHRPiqHotAkEb' with zone file hash '0649bc0b457f54c564d054ce20dc3745a0c4f0c0'
Proceed? (y/N) y
{
"status": true,
"success": true,
"transaction_hash": "496a6c2aaccedd98a8403c2e61ff3bdeff221a58bf0e9c362fcae981353f459f",
"value_hash": "0649bc0b457f54c564d054ce20dc3745a0c4f0c0"
}
```
6. Advance the blockchain again:
```bash
# NOTE: you can also do this by going to http://localhost:3001 in your Web browser
|blockstack-test namespace_check| $ curl -X POST http://localhost:3001/nextblock
```
7. See that the names are processing:
```bash
|blockstack-test namespace_check| $ blockstack info
{
"cli_version": "0.17.0.8",
"consensus_hash": "2a055beeaedcaa1365ab2671a0254a03",
"last_block_processed": 711,
"last_block_seen": 711,
"queues": {
"name_import": [
{
"confirmations": 2,
"name": "example.hello",
"tx_hash": "bd875f00f63bcb718bb22782c88c3edcbed79663f2f9152deab328c48746f103",
},
{
"confirmations": 1,
"name": "example2.hello",
"tx_hash": "496a6c2aaccedd98a8403c2e61ff3bdeff221a58bf0e9c362fcae981353f459f"
}
]
},
"server_alive": true,
"server_host": "localhost",
"server_port": 16264,
"server_version": "0.17.0.8"
}
```
8. Confirm all the transactions:
```bash
# NOTE: you can also do this by going to http://localhost:3001 in your Web browser
|blockstack-test namespace_check| $ for i in $(seq 1 10); do curl -X POST http://localhost:3001/nextblock
```
9. Look up name zone files to confirm they were replicated to the test framework's Atlas network:
```bash
|blockstack-test namespace_check| $ blockstack info
{
"cli_version": "0.17.0.8",
"consensus_hash": "ad247c1d5ff239a65db0736951078f17",
"last_block_processed": 721,
"last_block_seen": 721,
"queues": {},
"server_alive": true,
"server_host": "localhost",
"server_port": 16264,
"server_version": "0.17.0.8"
}
|blockstack-test namespace_check| $ blockstack get_name_zonefile example.hello
$ORIGIN example.hello
$TTL 3600
_file URI 10 1 "file:///home/blockstack-test/example.hello"
|blockstack-test namespace_check| $ blockstack get_name_zonefile example2.hello
$ORIGIN example2.hello
$TTL 3600
_file URI 10 1 "file:///home/blockstack-test/example2.hello"
```
Now, these names are imported and once the `NAMESPACE_READY` transaction is
sent, the name owners can proceed to issue name operations.
**Warnings**
* The first private key you use must be the same one you used to *create* the namespace (`$CREATOR_KEY`).
* You may only use the 300 private keys described above to import names.
* You must complete all `NAME_IMPORT` transactions within 52595 blocks of the `NAMESPACE_REVEAL` transaction (about 1 year).
### Launching a Namespace
Once you have pre-populated your namespace with all of the initial names, you
have to make it `ready` so anyone can register a name. If you do not do this
within 1 year of the `reveal` transaction, then your namespace and all of the
names will disappear, and someone else will be able to register it.
To make a namespace `ready`, you use the creator private key as follows:
```bash
|blockstack-test namespace_check| $ blockstack namespace_ready hello "$CREATOR_PKEY"
```
**Warnings**
* You must send the `NAMESPACE_READY` transaction within 52595 blocks (about 1 year) of the `NAMESPACE_REVEAL` transaction.

64
_site/core/openbazaar.md

@ -0,0 +1,64 @@
# Linking your OpenBazaar GUID to your Blockstack ID
If you don't have the Blockstack CLI. Download and install it first. Instructions are [here](https://github.com/blockstack/blockstack-cli/blob/master/README.md). The rest of this tutorial assumes that you've already registered a name using the Blockstack CLI.
## Step 1: Advanced Mode
The first step is to activate "advanced mode" in the CLI. The command to do so is:
```
$ blockstack set_advanced_mode on
```
## Step 2: Add an OpenBazaar Account
The second step is to create an OpenBazaar account for your profile (the [Onename](https://onename.com) app also enabled to link your OpenBazaar GUID). The command to do so is:
```
$ blockstack put_account "<BLOCKSTACK ID>" "openbazaar" "<YOUR OB GUID>" "<URL TO YOUR STORE>"
```
The URL can be any valid URL; it won't be used by OpenBazaar. Here's an example, using the name `testregistration001.id` and the GUID `0123456789abcdef`:
```
$ blockstack put_account "testregistration001.id" "openbazaar" "0123456789abcdef" "https://bazaarbay.org/@testregistration001"
```
The update should be instantaneous. You can verify that your store is present with `list_accounts`:
```
$ blockstack list_accounts "testregistration001.id"
{
"accounts": [
{
"contentUrl": "https://bazaarbay.org/@testregistration001.id",
"identifier": "0123456789abcdef",
"service": "openbazaar"
}
]
}
````
# Troubleshooting
Common problems you might encounter.
## Profile is in legacy format
If you registered your blockstack ID before spring 2016, there's a chance that your profile is still in a legacy format. It will get migrated to the new format automatically if you update your profile on the [Onename](https://onename.com) app. However, you have to do this manually with the CLI.
To do so, the command is:
```
$ blockstack migrate <YOUR BLOCKSTACK ID>
```
It will take a little over an hour to complete, but once finished, you'll be able to manage your accounts with the above commands (and do so with no delays).
## Failed to broadcast update transaction
This can happen during a `migrate` for one of a few reasons:
* You do not have enough balance to pay the transaction fee (which is calculated dynamically).
* Your payment address has unconfirmed transactions.
* You can't connect to a Bitcoin node.
To determine what's going on, you should try the command again by typing `BLOCKSTACK_DEBUG=1 blockstack ...` instead of `blockstack...`.

33
_site/core/resolver.md

@ -0,0 +1,33 @@
# Blockstack Resolver
During 2014-2016, Bockstack resolver was a separate service (like DNS resolvers).
It was merged into the Blockstack API in early 2017.
The following (legacy) API call is still being supported by the Blockstack API:
```
http://localhost:5000/v2/users/fredwilson
```
And you can see a legacy resolver in action at http://resolver.onename.com/v2/users/fredwilson
## Cron Job for Namespaces
**Note: the instructions below need updating.**
Currently, the resolver indexes all valid names in a local file which can be
populated by running
> $ ./refresh_names.sh
On a production deployment, you should add a crond job to periodically run this
script. You can edit your crontab file by:
> $ crontab -e
Here is a sample crontab file that runs the refresh script every two hours:
```
SHELL=/bin/bash
HOME=/home/ubuntu
#This is a comment
0 */2 * * * /home/ubuntu/resolver/resolver/refresh_names.sh
```

184
_site/core/search.md

@ -0,0 +1,184 @@
# Search
The search subsystem for Blockstack Core creates an index for data associated
with registered names in namespaces and makes that data searchable.
The search subsystem is currently meant to index the .id namespace but can
be easily expanded to include other namespaces.
Currently there are two types of indexes to handle search queries:
* Substring search on usernames, full names, twitter_handle (powered by MongoDB)
* Raw Lucene index which handles searching extended data e.g., bio.
Search will currently return upto a max of 20 results (can be less depending on the query)
with data that follows structure of [blockstack IDs](https://github.com/blockstack/blockstack):
In early 2017, the search subsystem was ported over to the new API system, where support for search is provided by the endpoint:
```
http://localhost:5000/search?query=<SEARCH_PATTERN>
```
This document describes how to setup the search subsystem to respond at that endpoint.
# Installation
- **Step 1:** First, make sure you have [virtualenv installed](http://docs.python-guide.org/en/latest/dev/virtualenvs/).
Then, setup the API and search subsystem:
```
$ sudo apt-get install -y mongodb memcached python-dev libmemcached-dev zlib1g-dev nginx
$ sudo pip install uwsgi
$ git clone https://github.com/blockstack/blockstack-core.git --branch api
$ cd blockstack-core/
$ sudo pip install .
$ sudo pip install -r api/requirements.txt
$ sudo mkdir /var/blockstack-search && sudo chown $USER:$USER /var/blockstack-search
```
- **Step 2:** Make sure you have Blockstack Core running locally (see [instructions](https://github.com/blockstack/blockstack-core/blob/master/README.md#quick-start)). We highly
recommend using a local node because the search subsystem issues thousands of calls to
Blockstack Core for re-indexing and remote nodes can slow down performance.
- **Step 3:** Fetch the data for the .id namespace and respective profiles. Note, you may want to redirect stderr to a file, as there is a lot of debug output.
```
$ cd api/
$ python -m search.fetch_data --fetch_namespace
$ python -m search.fetch_data --fetch_profiles
```
- **Step 4:** Create the search index:
```
python -m search.basic_index --refresh
```
- **Step 5:** Enable search API endpoint:
```
$ sed -i 's/SEARCH_API_ENDPOINT_ENABLED \= False/SEARCH_API_ENDPOINT_ENABLED \= True/' config.py
```
# Usage
You can quickly test the search index from the command line:
```
python -m search.substring_search --search_name "Fred Wil"
python -m search.substring_search --search_twitter fredwil
```
You can also use the search API end-point:
> curl -G {machine_ip}:port/search/name -d "query=muneeb"
Sample Response:
```
{
"people": [
{
"profile": {
"website": [
{
"url": "http://muneebali.com",
"@type": "WebSite"
}
],
"name": "Muneeb Ali",
"address": {
"addressLocality": "New York, NY",
"@type": "PostalAddress"
},
"image": [
{
"contentUrl": "https://s3.amazonaws.com/dx3/muneeb",
"@type": "ImageObject",
"name": "cover"
},
{
"contentUrl": "https://s3.amazonaws.com/kd4/muneeb",
"@type": "ImageObject",
"name": "avatar"
}
],
"@type": "Person",
"description": "Co-founder of Blockstack. Interested in distributed systems and blockchains. Previously, PhD at Princeton."
},
"username": "muneeb"
},
{
"profile": {
"message": "This blockchain ID is reserved for Muneeb Ali. If this is you, please email support@onename.com to claim it for free.",
"status": "reserved"
},
"username": "muneebali"
},
{
"profile": {
"cover": {
"url": "https://s3.amazonaws.com/97p/HHE.jpg"
},
"v": "0.2"
},
"username": "muneebali1"
}
]
}
```
## Enabling Elastic Search
### Requirements:
```
sudo apt-get install mongodb
sudo apt-get install memcached libmemcached-dev
sudo apt-get install python2.7-dev
pip install -r requirements.txt
```
### Elastic Search
Elastic Search library is not in github and resides at unix/lib/elastic
the current version we're using is *0.90.2*. Download from:
> wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.2.zip
before installing pylimbmc make sure [memcached](memcached.md) is installed.
Ensure that mongodb and elastic search are running
starting elastic search:
```
$elasticsearch (on mac)
bin/elasticsearch -d (on linux)
```
To test if elastic search is running:
> curl -X GET http://localhost:9200/
returns:
```
{
"ok" : true,
"status" : 200,
"name" : "Angler",
"version" : {
"number" : "0.90.2",
"snapshot_build" : false,
"lucene_version" : "4.3.1"
},
```
Create Index:
> python create_search_index.py --create_index

114
_site/core/setup_core_portal.md

@ -0,0 +1,114 @@
# Install Script
We provide a [script](../images/scripts/ubuntu-17.04.sh) which will
perform all the steps outlined in this doc (except for creating a protocol handler -- see the bottom of the doc). The script creates a virtualenv of
Blockstack Core and installs Browser in a subdirectory. It additionally creates some
scripts for starting Core and Browser together.
However, if you'd like to customize your install, step through it
yourself, or you are on a different distro, continue on with this doc!
# Setting up Blockstack Core API Service
Install required binaries in Ubuntu:
```
sudo apt update && sudo apt-get install -y python-pip python-dev libssl-dev libffi-dev rng-tools curl build-essential
```
If you'd like to use a virtualenv to install Blockstack, you can do that
```
pip install virtualenv
virtualenv --python=python2.7 ~/.blockstack.venv/ && source ~/.blockstack.venv/bin/activate
```
Let's install virtualchain 0.14.3 and blockstack 0.14.3
```
sudo apt install git
pip install git+https://github.com/blockstack/virtualchain.git@rc-0.14.3
pip install git+https://github.com/blockstack/blockstack-core.git@rc-0.14.3
```
Get Blockstack core configured with default settings and choose your Bitcoin wallet password
```
blockstack setup -y --password BITCOIN_WALLET_PASSWORD --debug
```
# Setting up Blockstack Browser Node Application
Install NodeJS through NodeSource PPA
```
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt install -y nodejs
```
Download Blockstack Browser and install its dependencies
```
git clone https://github.com/blockstack/blockstack-browser.git -bv0.11.1
cd blockstack-browser
npm install node-sass
npm install
```
Note that `blockstack-browser` depends on `node-sass` which can sometimes install strangely on Linux, running `npm install node-sass` before trying to install the other dependencies solves that problem.
# Running Blockstack Browser
Now we're ready to run our Core API service and start the Browser node app.
First, start the Core API service.
```
blockstack api start -y --password BITCOIN_WALLET_PASSWORD --debug
```
Start the CORS proxy.
```
npm run dev-proxy &
```
Start the Node Application
```
npm run dev
```
Then you can open `http://localhost:3000/` in your browser to get to the Blockstack Browser.
You can copy your api password to your clipboard with this command:
```
grep api_password ~/.blockstack/client.ini | sed 's/api_password = //g' | xclip -selection clipboard
```
## Setting up a protocol handler
If you'd like your browser to automatically handle links with the `blockstack:` protocol specifier, you will need to register a protocol handler with your desktop environment. In Ubuntu/Gnome, this can be done by creating a file
`~/.local/share/applications/blockstack.desktop`
With the following contents:
```
[Desktop Entry]
Type=Application
Terminal=false
Exec=bash -c 'xdg-open http://localhost:3000/auth?authRequest=$(echo "%u" | sed s,blockstack:////*,,)'
Name=Blockstack-Browser
MimeType=x-scheme-handler/blockstack;
```
Then you need to make this file executable, and register it as a protocol handler.
```
$ chmod +x ~/.local/share/applications/blockstack.desktop
$ xdg-mime default blockstack.desktop x-scheme-handler/blockstack
```
Now, `blockstack:` protocol URLs should get handled by your Blockstack Browser. If you're running Browser in your browser's private mode, you may have to copy and paste the link, as this protocol handler will try to open in a regular browser window.

303
_site/core/subdomains.md

@ -0,0 +1,303 @@
# Subdomain Design and Implementation
Subdomains allow us to provide names to end users cheaply (and quickly).
## Strong subdomain ownership
For those who are new to this concept, it's a model where domains can
permanently, cryptographically delegate subdomains to particular keys,
relinquishing their ability to revoke the names or change the name
resolution details.
These names will be indicated with an `.`, e.g., `foo.bar.id`
## Overall Design
We can do this today with a special indexer & resolver endpoint and
without any changes to the core protocol.
We can do this by having a zone file record for each subdomain *i*
containing the following information:
1. An owner address *addr*
2. A sequence number *N*
3. A zonefile
4. A signature *S* of the above
The signature *S_i* must be verifiable with the address in the
*(N-1)*th entry for subdomain *i*.
## Zonefile Format
For now, the resolver will use an *TXT* record per subdomain to define
this information. The entry name will be `$(subdomain)`.
We'll use the format of [RFC 1464](https://tools.ietf.org/html/rfc1464)
for the TXT entry. We'll have the following strings with identifiers:
1. **parts** : this specifies the number of pieces that the
zonefile has been chopped into. TXT strings can only be 255 bytes,
so we chop up the zonefile.
2. **zf{n}**: part *n* of the zonefile, base64 encoded
3. **owner**: the owner address delegated to operate the subdomain
4. **seqn**: the sequence number
5. **sig**: signature of the above data.
```
$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
aaron TXT "owner=33VvhhSQsYQyCVE2VzG3EHa9gfRCpboqHy" "seqn=0" "parts=1" "zf0=JE9SSUdJTiBhYXJvbgokVFRMIDM2MDAKbWFpbiBVUkkgMSAxICJwdWJrZXk6ZGF0YTowMzAyYWRlNTdlNjNiMzc1NDRmOGQ5Nzk4NjJhNDlkMDBkYmNlMDdmMjkzYmJlYjJhZWNmZTI5OTkxYTg3Mzk4YjgiCg=="
```
The `registrar` entry indicates how to contact the registrar service
for clients of the domain wishing to register or modify their entry.
### Operations per Zonefile
At 4kb zonefile size, we can only fit around 20 updates per zonefile.
## Domain Operator Endpoint
The directory `subdomain_registrar/` contains our code for running a
subdomain registrar. It can be executed by running:
```
$ blockstack-subdomain-registrar start foo.id
```
Here, `foo.id` is the domain for which subdomains will be associated.
### Configuration and Registration Files
Configuration of the subdomain registrar is done through `~/.blockstack_subdomains/config.ini`
The sqlite database which stores the registrations is located alongside the config `~/.blockstack_subdomains/registrar.db`.
You can change the location of the config file (and the database), by setting the environment variable `BLOCKSTACK_SUBDOMAIN_CONFIG`
### Register Subdomain
Subdomain registrations can be submitted to this endpoint using a REST
API.
```
POST /register
```
The schema for registration is:
```
{
'type' : 'object',
'properties' : {
'name' : {
'type': 'string',
'pattern': '([a-z0-9\-_+]{3,36})$'
},
'owner_address' : {
'type': 'string',
'pattern': schemas.OP_ADDRESS_PATTERN
},
'zonefile' : {
'type' : 'string',
'maxLength' : blockstack_constants.RPC_MAX_ZONEFILE_LEN
}
},
'required':[
'name', 'owner_address', 'zonefile'
],
'additionalProperties' : True
}
```
The registrar will:
1. Check if the subdomain `foo` exists already on the domain.
2. Add the subdomain to the queue.
On success, this returns `202` and the message
```
{"status": "true", "message": "Subdomain registration queued."}
```
When the registrar wakes up to prepare a transaction, it packs the queued
registrations together and issues an `UPDATE`.
### Check subdomain registration status
A user can check on the registration status of their name via querying the
registrar.
This is an API call:
```
GET /status/{subdomain}
```
The registrar checks if the subdomain has propagated (i.e., the
registration is completed), in which case the following is returned:
```
{"status": "Subdomain already propagated"}
```
Or, if the subdomain has already been submitted in a transaction:
```
{"status": "Your subdomain was registered in transaction 09a40d6ea362608c68da6e1ebeb3210367abf7aa39ece5fd57fd63d269336399 -- it should propagate on the network once it has 6 confirmations."}
```
If the subdomain still hasn't been submitted yet:
```
{"status": "Subdomain is queued for update and should be announced within the next few blocks."}
```
If an error occurred trying to submit the `UPDATE` transaction, this endpoint will return an error
message in the `"error"` key of a JSON object.
### Updating Entries
The subdomain registrar does not currently support updating subdomain entries.
## Resolver Behavior
When a lookup like `foo.bar.id` hits the resolver, the resolver will need to:
1. Lookup the zonefile history of `bar.id`
2. Fetch all these zonefiles and filter by operations on `foo`
3. Verify that all `foo` operations are correct
4. Return the latest record for foo
5. Do a profile lookup for `foo.bar.id` by fetching the URLs in the entry.
*Note*, this spec does not define a priority order for fetching those URLs.
### Supported Core / Resolver Endpoints
Generally, domain endpoints are not aware of subdomains (only endpoints
aware of subdomains is `/v1/users/<foo.bar.tld>`,
`/v1/names/<foo.bar.tld>`, and `/v1/addresses/bitcoin/<foo.bar.tld>`)
The endpoints which *are* subdomain aware are marked as such in
[api-specs.md], the cli command `blockstack lookup` is subdomain
aware.
This means that search is *not* yet supported.
The lookups work just like normal -- it returns the user's
profile object:
```
$ curl -H "Authorization: bearer blockstack_integration_test_api_password" -H "Origin: http://localhost:3000" http://localhost:16268/v1/users/bar.foo.id -v -s | python -m json.tool
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 16268 (#0)
> GET /v1/users/bar.foo.id HTTP/1.1
> Host: localhost:16268
> User-Agent: curl/7.50.1
> Accept: */*
> Authorization: bearer blockstack_integration_test_api_password
> Origin: http://localhost:3000
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/2.7.12+
< Date: Thu, 03 Aug 2017 14:39:16 GMT
< content-type: application/json
< Access-Control-Allow-Origin: *
<
{ [66 bytes data]
* Closing connection 0
{
"bar": {
"@type": "Person",
"description": "Lorem Ipsum Bazorem"
}
}
```
Name info lookups are also supported (this should enable authenticating logins
with `blockstack.js`, but I will need to double check).
```
$ curl -H "Authorization: bearer XXXX" -H "Origin: http://localhost:3000" http://localhost:6270/v1/names/created_equal.self_evident_truth.id -s | python -m json.tool
{
"address": "1AYddAnfHbw6bPNvnsQFFrEuUdhMhf2XG9",
"blockchain": "bitcoin",
"expire_block": -1,
"last_txid": "0bacfd5a3e0ec68723d5948d6c1a04ad0de1378c872d45fa2276ebbd7be230f7",
"satus": "registered_subdomain",
"zonefile_hash": "48fc1b351ce81cf0a9fd9b4eae7a3f80e93c0451",
"zonefile_txt": "$ORIGIN created_equal\n$TTL 3600\n_https._tcp URI 10 1 \"https://www.cs.princeton.edu/~ablankst/created_equal.json\"\n_file URI 10 1 \"file:///tmp/created_equal.json\"\n"
}
```
### Subdomain Caching
A resolver *caches* a subdomain's state by keeping a database of all
the current subdomain records. This database is automatically updated
when a new zonefile for a particularly domain is seen by the resolver
(this is performed lazily).
### Testing Subdomain Registrar and Resolution
You can run a subdomain registrar and resolver with blockstack-core in
regtest mode as follows:
```bash
IMAGE=$(docker run -dt -p 3000:3000 -p 6270:6270 -p 16269:16269 -p 18332:18332 -e BLOCKSTACK_TEST_CLIENT_RPC_PORT=6270 -e BLOCKSTACK_TEST_CLIENT_BIND=0.0.0.0 -e BLOCKSTACK_TEST_BITCOIND_ALLOWIP=172.17.0.0/16 quay.io/blockstack/integrationtests:master blockstack-test-scenario --interactive 2 blockstack_integration_tests.scenarios.browser_env)
```
Once you see `Test finished; doing checks` in that container's logs, the
registrar has started and is ready to accept requests. (We recommend
following the docker instructions below for running this test in
Docker, as it will fetch the source code for the registrar and set the
correct environment variables for it to run).
Once this environment has started, you can issue a registration request from curl:
```
curl -X POST -H 'Content-Type: application/json' --data '{"zonefile": "$ORIGIN baz\n$TTL 3600\n_file URI 10 1 \"file:///tmp/baz.profile.json\"\n", "name": "baz", "owner_address": "14x2EMRz1gf16UzGbxZh2c6sJg4A8wcHLD"}' http://localhost:3000/register/
```
This registers `baz.foo.id` -- you can check the registrar's status with
```
curl http://localhost:3000/status/baz
```
The API endpoints `/v1/users/<foo.bar.tld>`,
`/v1/names/<foo.bar.tld>`, and `/v1/addresses/bitcoin/<foo.bar.tld>` all work, so if you query the core API, you'll get a response.
For example:
```
curl http://localhost:6270/v1/names/baz.foo.id | python -m json.tool
```
Will return:
```
{
"address": "1Nup2UcbVuVoDZeZCtR4vjSkrvTi8toTqc",
"blockchain": "bitcoin",
"expire_block": -1,
"last_txid": "43bbcbd8793cdc52f1b0bd2713ed136f4f104a683a9fd5c89911a57a8c4b28b6",
"satus": "registered_subdomain",
"zonefile_hash": "e7e3aada18c9ac5189f1c54089e987f58c0fa51e",
"zonefile_txt": "$ORIGIN bar\n$TTL 3600\n_file URI 10 1 \"file:///tmp/baz.profile.json\"\n"
}
```
### Running an interactive testing environment with the Subdomain Registrar service
Follow the [instructions here](../integration_tests/README.md) to download the regtesting Docker image.
Since the subdomain registrar service runs on port 3000, we need to do two things to expose this endpoint to interact with it from the browser:
- Open port 3000 with `-p 3000:3000`
Here's the full command you'd run to start the interactive testing scenario:
```bash
IMAGE=$(docker run -dt -p 3000:3000 -p 6270:6270 -p 16269:16269 -p 18332:18332 -e BLOCKSTACK_TEST_CLIENT_RPC_PORT=6270 -e BLOCKSTACK_TEST_CLIENT_BIND=0.0.0.0 -e BLOCKSTACK_TEST_BITCOIND_ALLOWIP=172.17.0.0/16 quay.io/blockstack/integrationtests:master blockstack-test-scenario --interactive 2 blockstack_integration_tests.scenarios.browser_env)
```

492
_site/core/wire-format.md

@ -0,0 +1,492 @@
This page is for organizations who want to be able to create and send name operation transactions to the blockchain(s) Blockstack supports.
# Bitcoin
This section describes the transaction formats for the Bitcoin blockchain.
## Transaction format
Each Bitcoin transaction for Blockstack contains signatures from two sets of keys: the name owner, and the payer. The owner `scriptSig` and `scriptPubKey` fields are generated from the key(s) that own the given name. The payer `scriptSig` and `scriptPubKey` fields are used to *subsidize* the operation. The owner keys do not pay for any operations; the owner keys only control the minimum amount of BTC required to make the transaction standard. The payer keys only pay for the transaction's fees, and (when required) they pay the name fee.
This construction is meant to allow the payer to be wholly separate from the owner. The principal that owns the name can fund their own transactions, or they can create a signed transaction that carries out the desired operation and request some other principal (e.g. a parent organization) to actually pay for and broadcast the transaction.
The general transaction layout is as follows:
| **Inputs** | **Outputs** |
| ------------------------ | ----------------------- |
| Owner scriptSig (1) | `OP_RETURN <payload>` (2) |
| Payment scriptSig | Owner scriptPubKey (3) |
| Payment scriptSig... (4) |
| ... (4) | ... (5) |
(1) The owner `scriptSig` is *always* the first input.
(2) The `OP_RETURN` script that describes the name operation is *always* the first output.
(3) The owner `scriptPubKey` is *always* the second output.
(4) The payer can use as many payment inputs as (s)he likes.
(5) At most one output will be the "change" `scriptPubKey` for the payer.
Different operations require different outputs.
## Payload Format
Each Blockstack transaction in Bitcoin describes the name operation within an `OP_RETURN` output. It encodes name ownership, name fees, and payments as `scriptPubKey` outputs. The specific operations are described below.
Each `OP_RETURN` payload *always* starts with the two-byte string `id` (called the "magic" bytes in this document), followed by a one-byte `op` that describes the operation.
### NAME_PREORDER
Op: `?`
Description: This transaction commits to the *hash* of a name. It is the first
transaction of two transactions that must be sent to register a name in BNS.
Example: [6730ae09574d5935ffabe3dd63a9341ea54fafae62fde36c27738e9ee9c4e889](https://www.blocktrail.com/BTC/tx/6730ae09574d5935ffabe3dd63a9341ea54fafae62fde36c27738e9ee9c4e889)
`OP_RETURN` wire format:
```
0 2 3 23 39
|-----|--|--------------------------------------------------|--------------|
magic op hash_name(name.ns_id,script_pubkey,register_addr) consensus hash
```
Inputs:
* Payment `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* Payment `scriptPubkey` script for change
* `p2pkh` `scriptPubkey` to the burn address (0x00000000000000000000000000000000000000)
Notes:
* `register_addr` is a base58check-encoded `ripemd160(sha256(pubkey))` (i.e. an address). This address **must not** have been used before in the underlying blockchain.
* `script_pubkey` is either a `p2pkh` or `p2sh` compiled Bitcoin script for the payer's address.
### NAME_REGISTRATION
Op: `:`
Description: This transaction reveals the name whose hash was announced by a
previous `NAME_PREORDER`. It is the second of two transactions that must be
sent to register a name in BNS.
Example: [55b8b42fc3e3d23cbc0f07d38edae6a451dfc512b770fd7903725f9e465b2925](https://www.blocktrail.com/BTC/tx/55b8b42fc3e3d23cbc0f07d38edae6a451dfc512b770fd7903725f9e465b2925)
`OP_RETURN` wire format (2 variations allowed):
Variation 1:
```
0 2 3 39
|----|--|-----------------------------|
magic op name.ns_id (37 bytes)
```
Variation 2:
```
0 2 3 39 59
|----|--|----------------------------------|-------------------|
magic op name.ns_id (37 bytes, 0-padded) value
```
Inputs:
* Payer `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* `scriptPubkey` for the owner's address
* `scriptPubkey` for the payer's change
Notes:
* Variation 1 simply registers the name. Variation 2 will register the name and
set a name value simultaneously. This is used in practice to set a zone file
hash for a name without the extra `NAME_UPDATE` transaction.
* Both variations are supported. Variation 1 was designed for the time when
Bitcoin only supported 40-byte `OP_RETURN` outputs.
### NAME_RENEWAL
Op: `:`
Description: This transaction renews a name in BNS. The name must still be
registered and not expired, and owned by the transaction sender.
Example: [e543211b18e5d29fd3de7c0242cb017115f6a22ad5c6d51cf39e2b87447b7e65](https://www.blocktrail.com/BTC/tx/e543211b18e5d29fd3de7c0242cb017115f6a22ad5c6d51cf39e2b87447b7e65)
`OP_RETURN` wire format (2 variations allowed):
Variation 1:
```
0 2 3 39
|----|--|-----------------------------|
magic op name.ns_id (37 bytes)
```
Variation 2:
```
0 2 3 39 59
|----|--|----------------------------------|-------------------|
magic op name.ns_id (37 bytes, 0-padded) value
```
Inputs:
* Payer `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* `scriptPubkey` for the owner's addess. This can be a different address than
the current name owner (in which case, the name is renewed and transferred).
* `scriptPubkey` for the payer's change
* `scriptPubkey` for the burn address (to pay the name cost)
Notes:
* This transaction is identical to a `NAME_REGISTRATION`, except for the presence of the fourth output that pays for the name cost (to the burn address).
* Variation 1 simply renews the name. Variation 2 will both renew the name and
set a new name value (in practice, the hash of a new zone file).
* Both variations are supported. Variation 1 was designed for the time when
Bitcoin only supported 40-byte `OP_RETURN` outputs.
* This operation can be used to transfer a name to a new address by setting the
second output (the first `scriptPubkey`) to be the `scriptPubkey` of the new
owner key.
### NAME_UPDATE
Op: `+`
Description: This transaction sets the name state for a name to the given
`value`. In practice, this is used to announce new DNS zone file hashes to the [Atlas
network](atlas_network.md).
Example: [e2029990fa75e9fc642f149dad196ac6b64b9c4a6db254f23a580b7508fc34d7](https://www.blocktrail.com/BTC/tx/e2029990fa75e9fc642f149dad196ac6b64b9c4a6db254f23a580b7508fc34d7)
`OP_RETURN` wire format:
```
0 2 3 19 39
|-----|--|-----------------------------------|-----------------------|
magic op hash128(name.ns_id,consensus hash) zone file hash
```
Note that `hash128(name.ns_id, consensus hash)` is the first 16 bytes of a SHA256 hash over the name concatenated to the hexadecimal string of the consensus hash (not the bytes corresponding to that hex string).
See the [Method Glossary](#method-glossary) below.
Example: `hash128("jude.id" + "8d8762c37d82360b84cf4d87f32f7754") == "d1062edb9ec9c85ad1aca6d37f2f5793"`.
Inputs:
* owner `scriptSig`
* payment `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* owner's `scriptPubkey`
* payment `scriptPubkey` change
### NAME_TRANSFER
Op: `>`
Description: This transaction changes the public key hash that owns the name in
BNS.
Example: [7a0a3bb7d39b89c3638abc369c85b5c028d0a55d7804ba1953ff19b0125f3c24](https://www.blocktrail.com/BTC/tx/7a0a3bb7d39b89c3638abc369c85b5c028d0a55d7804ba1953ff19b0125f3c24)
`OP_RETURN` wire format:
```
0 2 3 4 20 36
|-----|--|----|-------------------|---------------|
magic op keep hash128(name.ns_id) consensus hash
data?
```
Inputs:
* Owner `scriptSig`
* Payment `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* new name owner's `scriptPubkey`
* old name owner's `scriptPubkey`
* payment `scriptPubkey` change
Notes:
* The `keep data?` byte controls whether or not the name's 20-byte value is preserved. This value is either `>` to preserve it, or `~` to delete it.
### NAME_REVOKE
Op: `~`
Description: This transaction destroys a registered name. Its name state value
in BNS will be cleared, and no further transactions will be able to affect the
name until it expires (if its namespace allows it to expire at all).
Example: [eb2e84a45cf411e528185a98cd5fb45ed349843a83d39fd4dff2de47adad8c8f](https://www.blocktrail.com/BTC/tx/eb2e84a45cf411e528185a98cd5fb45ed349843a83d39fd4dff2de47adad8c8f)
`OP_RETURN` wire format:
```
0 2 3 39
|----|--|-----------------------------|
magic op name.ns_id (37 bytes)
```
Inputs:
* owner `scriptSig`
* payment `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* owner `scriptPubkey`
* payment `scriptPubkey` change
### ANNOUNCE
Op: `#`
Description: This transaction does not affect any names in BNS, but it allows a
user to send a message to other BNS nodes. In order for the message to be
received, the following must be true:
* The sender must have a BNS name
* The BNS nodes must list the sender's BNS name as being a "trusted message
sender"
* The message must have already been propagated through the [Atlas
network](atlas_network.md). This transaction references it by content hash.
`OP_RETURN` wire format:
```
0 2 3 23
|----|--|-----------------------------|
magic op ripemd160(sha256(message))
```
Inputs:
* The payer `scriptSig`'s
Outputs:
* `OP_RETURN` payload
* change `scriptPubKey`
Notes:
* The payer key should be an owner key for an existing name, since Blockstack users can subscribe to announcements from specific name-owners.
### NAMESPACE_PREORDER
Op: `*`
Description: This transaction announces the *hash* of a new namespace. It is the
first of three transactions that must be sent to create a namespace.
Example: [5f00b8e609821edd6f3369ee4ee86e03ea34b890e242236cdb66ef6c9c6a1b28](https://www.blocktrail.com/BTC/tx/5f00b8e609821edd6f3369ee4ee86e03ea34b890e242236cdb66ef6c9c6a1b28)
`OP_RETURN` wire format:
```
0 2 3 23 39
|-----|---|-----------------------------------------|----------------|
magic op hash_name(ns_id,script_pubkey,reveal_addr) consensus hash
```
Inputs:
* Namespace payer `scriptSig`
Outputs:
* `OP_RETURN` payload
* Namespace payer `scriptPubkey` change address
* `p2pkh` script to the burn address `1111111111111111111114oLvT2`, whose public key hash is 0x00000000000000000000000000000000
Notes:
* The `reveal_addr` field is the address of the namespace revealer public key. The revealer private key will be used to generate `NAME_IMPORT` transactions.
### NAMESPACE_REVEAL
Op: `&`
Description: This transaction reveals the namespace ID and namespace rules
for a previously-anounced namespace hash (sent by a previous `NAMESPACE_PREORDER`).
Example: [ab54b1c1dd5332dc86b24ca2f88b8ca0068485edf0c322416d104c5b84133a32](https://www.blocktrail.com/BTC/tx/ab54b1c1dd5332dc86b24ca2f88b8ca0068485edf0c322416d104c5b84133a32)
`OP_RETURN` wire format:
```
0 2 3 7 8 9 10 11 12 13 14 15 16 17 18 20 39
|-----|---|--------|-----|-----|----|----|----|----|----|-----|-----|-----|--------|----------|-------------------------|
magic op life coeff. base 1-2 3-4 5-6 7-8 9-10 11-12 13-14 15-16 nonalpha version namespace ID
bucket exponents no-vowel
discounts
```
Inputs:
* Namespace payer `scriptSig`s
Outputs:
* `OP_RETURN` payload
* namespace revealer `scriptPubkey`
* namespace payer change `scriptPubkey`
Notes:
* This transaction must be sent within 1 day of the `NAMESPACE_PREORDER`
* The second output (with the namespace revealer) **must** be a `p2pkh` script
* The address of the second output **must** be the `reveal_addr` in the `NAMESPACE_PREORDER`
Pricing:
The rules for a namespace are as follows:
* a name can fall into one of 16 buckets, measured by length. Bucket 16 incorporates all names at least 16 characters long.
* the pricing structure applies a multiplicative penalty for having numeric characters, or punctuation characters.
* the price of a name in a bucket is ((coeff) * (base) ^ (bucket exponent)) / ((numeric discount multiplier) * (punctuation discount multiplier))
Example:
* base = 10
* coeff = 2
* nonalpha discount: 10
* no-vowel discount: 10
* buckets 1, 2: 9
* buckets 3, 4, 5, 6: 8
* buckets 7, 8, 9, 10, 11, 12, 13, 14: 7
* buckets 15, 16+:
With the above example configuration, the following are true:
* The price of "john" would be 2 * 10^8, since "john" falls into bucket 4 and has no punctuation or numerics.
* The price of "john1" would be 2 * 10^6, since "john1" falls into bucket 5 but has a number (and thus receives a 10x discount)
* The price of "john_1" would be 2 * 10^6, since "john_1" falls into bucket 6 but has a number and punctuation (and thus receives a 10x discount)
* The price of "j0hn_1" would be 2 * 10^5, since "j0hn_1" falls into bucket 6 but has a number and punctuation and lacks vowels (and thus receives a 100x discount)
### NAME_IMPORT
Op: `;`
Description: This transaction registers a name and some name state into a
namespace that has been revealed, but not been launched. Only the namespace
creator can import names. See the [namespace creation
tutorial](namespace_creation.md) for details.
Example: [c698ac4b4a61c90b2c93dababde867dea359f971e2efcf415c37c9a4d9c4f312](https://www.blocktrail.com/BTC/tx/c698ac4b4a61c90b2c93dababde867dea359f971e2efcf415c37c9a4d9c4f312)
`OP_RETURN` wire format:
```
0 2 3 39
|----|--|-----------------------------|
magic op name.ns_id (37 bytes)
```
Inputs:
* The namespace reveal `scriptSig` (with the namespace revealer's public key), or one of its first 300 extended public keys
* Any payment inputs
Outputs:
* `OP_RETURN` payload
* recipient `scriptPubKey`
* zone file hash (using the 20-byte hash in a standard `p2pkh` script)
* payment change `scriptPubKey`
Notes:
* These transactions can only be sent between the `NAMESPACE_REVEAL` and `NAMESPACE_READY`.
* The first `NAME_IMPORT` transaction **must** have a `scriptSig` input that matches the `NAMESPACE_REVEAL`'s second output (i.e. the reveal output).
* Any subsequent `NAME_IMPORT` transactions **may** have a `scriptSig` input whose public key is one of the first 300 extended public keys from the `NAMESPACE_REVEAL`'s `scriptSig` public key.
### NAMESPACE_READY
Op: `!`
Description: This transaction launches a namesapce. Only the namespace creator
can send this transaction. Once sent, anyone can register names in the
namespace.
Example: [2bf9a97e3081886f96c4def36d99a677059fafdbd6bdb6d626c0608a1e286032](https://www.blocktrail.com/BTC/tx/2bf9a97e3081886f96c4def36d99a677059fafdbd6bdb6d626c0608a1e286032)
`OP_RETURN` wire format:
```
0 2 3 4 23
|-----|--|--|------------|
magic op . ns_id
```
Inputs:
* Namespace revealer's `scriptSig`s
Outputs:
* `OP_RETURN` payload
* Change output to the namespace revealer's `p2pkh` script
Notes:
* This transaction must be sent within 1 year of the corresponding `NAMESPACE_REVEAL` to be accepted.
## Method Glossary
Some hashing primitives are used to construct the wire-format representation of each name operation. They are enumerated here:
```
B40_REGEX = '^[a-z0-9\-_.+]*$'
def is_b40(s):
return isinstance(s, str) and re.match(B40_REGEX, s) is not None
def b40_to_bin(s):
if not is_b40(s):
raise ValueError('{} must only contain characters in the b40 char set'.format(s))
return unhexlify(charset_to_hex(s, B40_CHARS))
def hexpad(x):
return ('0' * (len(x) % 2)) + x
def charset_to_hex(s, original_charset):
return hexpad(change_charset(s, original_charset, B16_CHARS))
def bin_hash160(s, hex_format=False):
""" s is in hex or binary format
"""
if hex_format and is_hex(s):
s = unhexlify(s)
return hashlib.new('ripemd160', bin_sha256(s)).digest()
def hex_hash160(s, hex_format=False):
""" s is in hex or binary format
"""
if hex_format and is_hex(s):
s = unhexlify(s)
return hexlify(bin_hash160(s))
def hash_name(name, script_pubkey, register_addr=None):
"""
Generate the hash over a name and hex-string script pubkey.
Returns the hex-encoded string RIPEMD160(SHA256(x)), where
x is the byte string composed of the concatenation of the
binary
"""
bin_name = b40_to_bin(name)
name_and_pubkey = bin_name + unhexlify(script_pubkey)
if register_addr is not None:
name_and_pubkey += str(register_addr)
# make hex-encoded hash
return hex_hash160(name_and_pubkey)
def hash128(data):
"""
Hash a string of data by taking its 256-bit sha256 and truncating it to the
first 16 bytes
"""
return hexlify(bin_sha256(data)[0:16])
```

49
_site/feed.xml

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.5.0">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2018-08-27T11:40:45-07:00</updated><id>http://localhost:4000/</id><title type="html">Blockstack</title><subtitle>Docs</subtitle><author><name>Blockstack</name></author><entry><title type="html">Site tags</title><link href="http://localhost:4000/2017/05/25/post63.html" rel="alternate" type="text/html" title="Site tags" /><published>2017-05-25T00:00:00-07:00</published><updated>2017-05-25T00:00:00-07:00</updated><id>http://localhost:4000/2017/05/25/post63</id><content type="html" xml:base="http://localhost:4000/2017/05/25/post63.html">&lt;p&gt;http://localhost:4000/assets/posts/&lt;/p&gt;
&lt;p&gt;/2017/05/25/post63.html&lt;/p&gt;
&lt;p&gt;Musce libero nunc, dignissim quis turpis quis, semper vehicula dolor. Suspendisse tincidunt consequat quam, ac posuere leo dapibus id. Cras fringilla convallis elit, at eleifend mi interam.&lt;/p&gt;
&lt;p&gt;Nulla non sollicitudin. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla. Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit.&lt;/p&gt;
&lt;h2 id=&quot;image-lightbox-example&quot;&gt;Image Lightbox Example&lt;/h2&gt;
&lt;p&gt;Nunc porta malesuada porta. Etiam tristique vestibulum dolor at ultricies. Proin hendrerit sapien sed erat fermentum, at commodo velit consectetur.&lt;/p&gt;
&lt;figure data-uk-lightbox=&quot;animation: slide&quot;&gt;
&lt;!-- &lt;a class=&quot;uk-inline&quot; href=&quot;http://localhost:4000/assets/posts/image1.png&quot; caption=&quot;Image in lightbox&quot;&gt; --&gt;
&lt;a class=&quot;uk-inline&quot; href=&quot;/assets/posts/image1.png&quot; caption=&quot;Image in lightbox&quot;&gt;
&lt;!-- &lt;img src=&quot;http://localhost:4000/assets/posts/image1.png&quot; alt=&quot;Alt for image&quot;&gt; --&gt;
&lt;img src=&quot;/assets/posts/image1.png&quot; alt=&quot;Alt for image&quot; /&gt;
&lt;div class=&quot;uk-position-center&quot;&gt;
&lt;span data-uk-overlay-icon=&quot;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/a&gt;
&lt;figcaption data-uk-grid=&quot;&quot; class=&quot;uk-flex-right&quot;&gt;&lt;span class=&quot;uk-width-auto&quot;&gt;Image in lightbox&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna, et dapibus turpis.&lt;/p&gt;
&lt;h2 id=&quot;example-of-code-block&quot;&gt;Example Of Code Block&lt;/h2&gt;
&lt;p&gt;In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;&lt;/p&gt;
&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;http-equiv=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IE=edge&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width=device-width, initial-scale=1&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/assets/css/main.css&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;shortcut icon&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;image/png&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/assets/img/favicon.png&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/assets/js/main.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;text-and-quote&quot;&gt;Text and Quote&lt;/h2&gt;
&lt;p&gt;Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna turpis.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;&lt;/p&gt;
&lt;p&gt;Etiam in fermentum mi. Sed et tempor felis, eu aliquet nisi. Nam eget ullamcorper arcu. Nunc porttitor nisl a dolor blandit, eget consequat sem maximus. Phasellus lacinia quam porta orci malesuada, vel tincidunt.&lt;/p&gt;</content><author><name>John Black</name></author><summary type="html">Site tags</summary></entry></feed>

50
_site/get-content.sh

@ -0,0 +1,50 @@
#!/bin/bash
# get the content from the downstream repos
# needs jq "brew install jq"
collectionList=$(<collections.json)
for collection in $(echo "$collectionList" | jq -r '.collections[] | @base64'); do
# Get the collection structure
_jq() {
echo ${collection} | base64 --decode | jq -r ${1}
}
theName=$(echo $(_jq '.name'))
theRepo=$(echo $(_jq '.repo'))
echo "Getting the _$theName"
rm -rf _$theName
svn checkout $theRepo/trunk/docs _$theName
#
# sed -i "" "s/THETITLE/${theTitle}/g" ${DIR}/pdfconfigs/config_mydoc_pdf.yml
#
# for code in $(echo $(_jq '.codes') | jq -r '.[]'); do
# theCode=${code}
# sed -i "" "s/${code}/pdf/g" ${DIR}/_data/sidebars/mydoc_sidebar.yml
# done
#
# echo 'Killing all Jekyll instances'
# kill -9 $(ps aux | grep '[j]ekyll' | awk '{print $2}')
# clear
#
# echo "Building PDF-friendly HTML site for Mydoc ...";
# bundle exec jekyll serve --detach --config _config.yml,pdfconfigs/config_mydoc_pdf.yml;
# echo "done";
#
# echo "Building the PDF ...";
# prince --javascript --pdf-keywords=prince-no-fallback --input-list=_site/pdfconfigs/prince-list.txt -o pdf/${theName}_${theVersion}.pdf;
#
#
# ## Reset everything for the next collection
# git checkout -- ${DIR}/collection-list.json
# git checkout -- ${DIR}/pdfconfigs/config_mydoc_pdf.yml
# git checkout -- ${DIR}/_data/sidebars/mydoc_sidebar.yml
done

423
_site/index.html

@ -0,0 +1,423 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Blockstack | Docs</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="Blockstack" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Docs" />
<meta property="og:description" content="Docs" />
<link rel="canonical" href="http://localhost:4000/" />
<meta property="og:url" content="http://localhost:4000/" />
<meta property="og:site_name" content="Blockstack" />
<script type="application/ld+json">
{"name":"Blockstack","description":"Docs","author":{"@type":"Person","name":"Blockstack"},"@type":"WebSite","url":"http://localhost:4000/","headline":"Blockstack","@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section section-hero" data-uk-scrollspy="cls: uk-animation-slide-bottom-medium; repeat: true">
<div class="uk-container uk-container-small">
<!-- <p class="hero-image uk-text-center"><img src="http://localhost:4000/assets/posts/touch-icon.png" alt="Hero"></p> -->
<p class="hero-image uk-text-center"><img src="/assets/posts/touch-icon.png" alt="Hero"></p>
<!-- <h1 class="uk-heading-hero uk-text-center uk-margin-remove-top">What would you like to know?</h1> -->
<p class="subtitle uk-text-lead uk-text-center">Welcome to the documentation on everything Blockstack.</p>
<div class="hero-search">
<!-- Html Elements for Search -->
<div class="uk-position-relative">
<form class="uk-search uk-search-default uk-width-1-1" name="search-hero" onsubmit="return false;">
<span data-uk-search-icon></span>
<input id="hero-search" class="uk-search-input" type="search" placeholder="Search for a term, API, or topic...">
</form>
<ul id="hero-search-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('hero-search'),
resultsContainer: document.getElementById('hero-search-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
</div>
</div>
</div>
<div class="uk-section">
<div class="uk-container">
<h2 class="uk-text-center heading-hero-2" style="padding-top: 25px !important;">Browse by topic or technology category</h2>
<div class="uk-child-width-1-3@m uk-grid-match uk-text-center uk-margin-medium-top" data-uk-grid>
<div>
<div class="uk-card uk-card-body uk-inline uk-border-rounded">
<a class="uk-position-cover" href="/learn/overview.html"></a>
<span data-uk-icon="icon: settings; ratio: 2" class=""></span>
<h3 class="uk-card-title uk-margin">Evaluate Blockstack</h3>
<p>Learn about the technology behind Blockstack. Understand the value it offers and how it provides it.</p>
</div>
</div>
<div>
<div class="uk-card uk-card-body uk-inline uk-border-rounded">
<a class="uk-position-cover" href="/newinternet/privacy.html"></a>
<span data-uk-icon="icon: settings; ratio: 2" class=""></span>
<h3 class="uk-card-title uk-margin">Use the New Internet</h3>
<p>Learn about the New Internet and its applications. Create an identity and learn how to use it.</p>
</div>
</div>
<div>
<div class="uk-card uk-card-body uk-inline uk-border-rounded">
<a class="uk-position-cover" href="/android/tutorial.html"></a>
<span data-uk-icon="icon: settings; ratio: 2" class=""></span>
<h3 class="uk-card-title uk-margin">Build Apps and Earn Money</h3>
<p>Learn how to build an application that earns with Blockstack.</p>
</div>
</div>
<div>
<div class="uk-card uk-card-body uk-inline uk-border-rounded">
<a class="uk-position-cover" href="/naming/overview.html"></a>
<span data-uk-icon="icon: cog; ratio: 2" class=""></span>
<h3 class="uk-card-title uk-margin">Use the Naming Service</h3>
<p>Managing your account, create new users and exporting data</p>
</div>
</div>
<div>
<div class="uk-card uk-card-body uk-inline uk-border-rounded">
<a class="uk-position-cover" href="/auth/overview.html"></a>
<span data-uk-icon="icon: cog; ratio: 2" class=""></span>
<h3 class="uk-card-title uk-margin">Implement Authentication</h3>
<p>Managing your account, creating new users and exporting data</p>
</div>
</div>
<div>
<div class="uk-card uk-card-body uk-inline uk-border-rounded">
<a class="uk-position-cover" href="/gaia/overview.html"></a>
<span data-uk-icon="icon: cog; ratio: 2" class=""></span>
<h3 class="uk-card-title uk-margin">Implement Storage with GAIA</h3>
<p>Backend storage drivers and interactions between developer APIs and the Gaia service.</p>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section uk-text-center">
<div class="uk-container uk-container-small">
<div class="article-content uk-margin-medium-top"><!-- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -->
</div>
</div>
</div>
<div class="uk-section uk-text-center">
<div class="uk-container uk-container-small">
<div data-uk-scrollspy="cls: uk-animation-slide-bottom-medium; repeat: true">
<h3>Didn't find an answer to your question?</h3>
<p class="subtitle uk-text-lead uk-text-center">Get in touch with us and we will be happy to respond!</p>
<a class="uk-button uk-button-primary uk-button-large button-cta" href="/contact/">Contact Us</a>
</div>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>

6
_site/netlify.toml

@ -0,0 +1,6 @@
[Settings]
ID = "2daa9486-d204-4dc7-857a-2bfcded10b91"
[build]
publish: _site

294
_site/news/index.html

@ -0,0 +1,294 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>News | Blockstack</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="News" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Docs" />
<meta property="og:description" content="Docs" />
<link rel="canonical" href="http://localhost:4000/news/" />
<meta property="og:url" content="http://localhost:4000/news/" />
<meta property="og:site_name" content="Blockstack" />
<script type="application/ld+json">
{"description":"Docs","author":{"@type":"Person","name":"Blockstack"},"@type":"WebPage","url":"http://localhost:4000/news/","headline":"News","@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container uk-container-xsmall">
<h1 class="uk-article-title">News</h1>
<div class="uk-card card-post uk-inline uk-border-rounded uk-width-1-1 uk-margin">
<a class="uk-position-cover" href="/2017/05/25/post63.html"></a>
<div class="uk-card-header">
<div class="uk-grid-small uk-flex-middle" uk-grid>
<div class="uk-width-auto">
<img class="avatar avatar-small" alt="Blockstack" width="40" height="40" data-proofer-ignore="true" src="https://avatars1.githubusercontent.com/Blockstack?v=3&s=40" srcset="https://avatars1.githubusercontent.com/Blockstack?v=3&s=40 1x, https://avatars1.githubusercontent.com/Blockstack?v=3&s=80 2x, https://avatars1.githubusercontent.com/Blockstack?v=3&s=120 3x, https://avatars1.githubusercontent.com/Blockstack?v=3&s=160 4x" />
</div>
<div class="uk-width-expand">
<h3 class="uk-card-title uk-margin-remove-bottom">Site tags</h3>
<p class="uk-text-meta uk-margin-remove-top"><time datetime="2017-05-25T00:00:00-07:00">
May 25, 2017
</time></p>
</div>
</div>
</div>
<div class="uk-card-body">
<h2 id="site-tags">Site tags</h2>
</div>
<div class="uk-card-footer">
<span class="uk-button uk-button-text">Read more &rarr;</span>
</div>
</div>
<!-- Pagination links -->
<ul class="uk-pagination uk-margin-medium-top">
</ul>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>

41
_site/package.json

@ -0,0 +1,41 @@
{
"name": "docs",
"version": "1.0.0",
"description": "Docs Jekyll theme.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"copy": "ncp node_modules/uikit/src/scss/ _sass/uikit/ && ncp node_modules/system-font-css/ _sass/system-font-css/",
"lint": "jshint assets/js/custom.js",
"uglify": "uglifyjs node_modules/uikit/dist/js/uikit.js node_modules/uikit/dist/js/uikit-icons.js node_modules/simple-jekyll-search/dest/simple-jekyll-search.js assets/js/custom.js -m -c -o assets/js/main.js",
"concat": "uglifyjs node_modules/uikit/dist/js/uikit.js node_modules/uikit/dist/js/uikit-icons.js node_modules/simple-jekyll-search/dest/simple-jekyll-search.js assets/js/custom.js -b -o assets/js/main.js",
"dev": "npm run lint && npm run concat",
"build": "npm run lint && npm run uglify",
"watch": "watch 'npm run dev' assets/js/",
"postinstall": "npm run copy && npm run concat"
},
"repository": {
"type": "git",
"url": "git+https://github.com/"
},
"author": "moxiegirl",
"license": "MIT",
"bugs": {
"url": "https://github.com/"
},
"homepage": "https://github.com/",
"dependencies": {
"simple-jekyll-search": "^1.5.0",
"system-font-css": "^2.0.1",
"uikit": "^3.0.0-beta.42"
},
"devDependencies": {
"jshint": "^2.9.5",
"ncp": "latest",
"uglify-js": "^3.2.1",
"watch": "^1.0.2"
},
"directories": {
"doc": "docs"
}
}

2
_site/robots.txt

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

3
_site/search.json

@ -0,0 +1,3 @@
[
]

270
_site/thanks/index.html

@ -0,0 +1,270 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Thanks | Blockstack</title>
<meta name="generator" content="Jekyll v3.5.0" />
<meta property="og:title" content="Thanks" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Docs" />
<meta property="og:description" content="Docs" />
<link rel="canonical" href="http://localhost:4000/thanks/" />
<meta property="og:url" content="http://localhost:4000/thanks/" />
<meta property="og:site_name" content="Blockstack" />
<script type="application/ld+json">
{"description":"Docs","author":{"@type":"Person","name":"Blockstack"},"@type":"WebPage","url":"http://localhost:4000/thanks/","headline":"Thanks","@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="http://localhost:4000/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container uk-container-xsmall">
<article class="uk-article">
<h1 class="uk-article-title">Thanks</h1>
<div class="article-content">
<p>Varius tempor. Nulla non sollicitudin tortor. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla.</p>
<p>Ut malesuada varius tempor. Nulla non sollicitudin tortor. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla.</p>
<p>Mesuada varius tempor. Nulla non sollicitudin tortor. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla.</p>
<p>Varius tempor. Nulla non sollicitudin tortor. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla.</p>
</div>
</article>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="http://localhost:4000/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>
Loading…
Cancel
Save