After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 4.8 MiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 613 KiB |
After Width: | Height: | Size: 286 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 227 KiB |
After Width: | Height: | Size: 207 KiB |
After Width: | Height: | Size: 59 KiB |
@ -0,0 +1,503 @@
|
||||
<!doctype html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
|
||||
<title>ActivityPub</title> |
||||
|
||||
<meta name="description" content="Por que você deveria aprender Rust"> |
||||
<meta name="author" content="Julio Biason"> |
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"> |
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> |
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui"> |
||||
|
||||
<link rel="stylesheet" href="reveal.js/css/reveal.css"> |
||||
<link rel="stylesheet" href="reveal.js/css/theme/night.css" id="theme"> |
||||
|
||||
<!-- Code syntax highlighting --> |
||||
<link rel="stylesheet" href="reveal.js/lib/css/zenburn.css"> |
||||
|
||||
<!-- Printing and PDF exports --> |
||||
<script> |
||||
var link = document.createElement( 'link' ); |
||||
link.rel = 'stylesheet'; |
||||
link.type = 'text/css'; |
||||
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css'; |
||||
document.getElementsByTagName( 'head' )[0].appendChild( link ); |
||||
</script> |
||||
|
||||
<!--[if lt IE 9]> |
||||
<script src="lib/js/html5shiv.js"></script> |
||||
<![endif]--> |
||||
|
||||
<style type="text/css" media="screen"> |
||||
.happy { |
||||
color: yellow; |
||||
} |
||||
|
||||
.reveal section img { |
||||
border: none; |
||||
} |
||||
|
||||
.reveal ul.empty { |
||||
list-style: none inside; |
||||
} |
||||
|
||||
.revel ul.empty li { |
||||
display: block; |
||||
} |
||||
|
||||
.cursor { |
||||
background-color: #666; |
||||
color: white; |
||||
} |
||||
|
||||
img { |
||||
max-height: 90%; |
||||
} |
||||
|
||||
td.seen { |
||||
font-style: italic; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.semi-opaque { |
||||
background-color: rgba(0, 0, 0, 0.7); |
||||
} |
||||
|
||||
.white { |
||||
background-color: white !important; |
||||
} |
||||
</style> |
||||
</head> |
||||
|
||||
<body> |
||||
<div class="reveal"> |
||||
<div class="slides"> |
||||
<section> |
||||
<section data-background="_images/activitypub-logo.png" data-header> |
||||
<h2 class="semi-opaque">ActivityPub</h2> |
||||
</section> |
||||
</section> |
||||
|
||||
<section> |
||||
<section> |
||||
<img src="_images/avatar-20170726.png" alt="Me" style="float:left;width:200px;" class="no-border"> |
||||
|
||||
<div> |
||||
<ul class="empty"> |
||||
<li>Júlio Biason</li> |
||||
<li><a href="https://functional.cafe/@juliobiason">https://functional.cafe/@juliobiason</a></li> |
||||
<li><a href="https://t.me/juliobiason">https://t.me/juliobiason</a></li> |
||||
<li>julio.biason@pm.me</li> |
||||
<li><a href="http://presentations.juliobiason.net">http://presentations.juliobiason.net</a></li> |
||||
</ul> |
||||
</div> |
||||
</section> |
||||
</section> |
||||
|
||||
<section> |
||||
<section> |
||||
<img class="stretch" src="_images/internet.jpeg" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Para entender ActivityPub -- e porque ele existe -- |
||||
precisamos dar um passo atrás e entender a internet. |
||||
|
||||
A internet foi criada para ser "anarquica", no |
||||
sentido que não haveria um ponto central; se algum |
||||
ponto da rede fosse destruído por uma bomba nuclear |
||||
(porque assim eram os anos 60), outros pontos |
||||
continuariam funcionando. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<img class="stretch" src="_images/federation.png" title="(do latim: foederatio, de foedus: “liga, tratado, aliança”) ou Estado Federal é um Estado composto por diversas entidades territoriais autônomas dotadas de governo próprio."> |
||||
|
||||
<aside class="notes"> |
||||
De certa forma, as coisas funcionavam de forma |
||||
"federada", cuja definição do dicionário para |
||||
"federação" é: "(do latim: foederatio, de foedus: |
||||
“liga, tratado, aliança”) ou Estado Federal é um |
||||
Estado composto por diversas entidades territoriais |
||||
autônomas dotadas de governo próprio." |
||||
|
||||
(E como eu sou fã de Jornada nas Estrelas, eu |
||||
sempre lembro da "Federação dos Planetas Unidos", |
||||
que tinha o mesmo significado: vários planetas, |
||||
cada um com suas políticas, mas cada um funcionando |
||||
da forma que quisesse.) |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<img class="stretch" src="_images/email.png" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Um dos exemplos mais básicos de federação ainda em |
||||
uso é o email: Existem vários servidores/serviços |
||||
de email por aí, cada um tem suas definições do que |
||||
é spam (ou como um email é definido como "spam"), |
||||
quotas de espaço, aliases -- enfim, uma série de |
||||
políticas -- mas os serviços conversam entre si |
||||
para garantir que todos possam receber emails, |
||||
mesmo estando em serviços (com políticas) |
||||
diferentes. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<img class="stretch" src="_images/xmpp.png" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Outro exemplo de federação é o XMPP, um protocolo |
||||
criado para comunicação instantânea que era |
||||
utilizado pelo Hangouts a muito tempo (hoje não é |
||||
mais, é um protocolo fechado). |
||||
</aside> |
||||
</section> |
||||
</section> |
||||
|
||||
<section> |
||||
<section> |
||||
<img class="stretch" src="_images/socializing.jpeg" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Apesar dos pesares, humanos são seres sociais e, |
||||
apesar dos pesares, a internet é uma forma de |
||||
socialização. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<img class="stretch" src="_images/silo.jpeg" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Infelizmente, a pouco tempo (em termos de tempo |
||||
de vida de internet), o modelo começou a mudar |
||||
para um modelo de "Silos", onde tudo fica no mesmo |
||||
lugar (mesmo que o "mesmo lugar" sejam vários |
||||
computadores em vários lugares). |
||||
|
||||
A ideia de coisas com "políticas diferentes que |
||||
trabalham em forma de aliança" foi esquecida e |
||||
agora boa parte das coisas que nós queremos |
||||
compartilhar acaba ficando sob uma única política. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<img class="stretch" src="_images/all-eggs.jpeg" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Basicamente estamos colocando todos os ovos no |
||||
mesmo sesto. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<img class="stretch" src="_images/all-eggs-broken.jpeg" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
Basta lembrar o que acontece toda vez que algum |
||||
juiz diz que é para bloquear o WhatsApp. |
||||
|
||||
(O resultado é que explodem os cadastros no |
||||
Telegram, que sofre do mesmo problema.) |
||||
</aside> |
||||
</section> |
||||
</section> |
||||
|
||||
<section> |
||||
<section> |
||||
<img class="stretch white" src="_images/ActivityPub-logo.svg" alt=""> |
||||
|
||||
<aside class="notes"> |
||||
E assim como temos o XMPP para conversas |
||||
instantâneas, temos o ActivityPub para ações |
||||
"sociais" -- no sentido de "coisas que fazemos com |
||||
nossas vidas". |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>Mas O Que é ActivityPub</h4> |
||||
|
||||
<ul> |
||||
<li class="fragment">Protocolo certificado pela W3C.</li> |
||||
<li class="fragment">Baseado em HTTP e JSON.</li> |
||||
<li class="fragment">Tem vários conceitos iguais ao email.</li> |
||||
<li class="fragment">Composto de outros protolocos: WebFinger, ActivityStreams, ActivityVocabulary e JSON-LD.</li> |
||||
</ul> |
||||
|
||||
<aside class="notes"> |
||||
1. O protocolo é certificado (e padronizado) pela |
||||
W3C, o que deixa o protocolo aberto para |
||||
qualquer um implementar a sua própria versão (e |
||||
existem várias implementações, que eu vou falar |
||||
mais pra frente). |
||||
2. Apesar d'eu ter comentado o email, que usa um |
||||
protocolo específico, ActivityPub usa HTTP e JSON. |
||||
3. E apesar de ser HTTP e JSON, ainda aproveita |
||||
alguns conceitos do email -- e sim, eu estou |
||||
andando em circulos, mas peraí. |
||||
4. ActivityPub não é apenas um protocolo, mas é um |
||||
protocolo construido sobre outros protocolos, |
||||
como WebFinger para descoberta de informações de |
||||
usuários, ActivityStreams que descreve o formato |
||||
das atividades, ActivityVocabulary que inidica |
||||
quais ações existentes e os tipos de objetos |
||||
existentes e JSON-LD que define os formato dos |
||||
objetos em JSON. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>O Que é ActivityPub</h4> |
||||
<h3>Activity Vocabulary</h3> |
||||
|
||||
<ul> |
||||
<li class="fragment">Actors <span class="fragment">(Person, Bot, Service)</span></li> |
||||
<li class="fragment">Notes</li> |
||||
<li class="fragment">Images</li> |
||||
<li class="fragment">Links</li> |
||||
<li class="fragment">...</li> |
||||
</ul> |
||||
|
||||
<aside class="notes"> |
||||
Existem atores que aplicam as ações (person, bot, |
||||
company/service), e as atividades tem coisas como o |
||||
compartilhamento de notas (texto), imagens, links e |
||||
outras coisas. Praticamente tudo que possa ser |
||||
pensando em compartilhar. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<h3>WebFinger</h3> |
||||
|
||||
<pre><code class="hljs json" data-trim> |
||||
{"@context": "https://www.w3.org/ns/activitystreams", |
||||
"type": "Person", |
||||
"id": "https://social.example/alyssa/", |
||||
"name": "Alyssa P. Hacker", |
||||
"preferredUsername": "alyssa", |
||||
"summary": "Lisp enthusiast hailing from MIT", |
||||
"inbox": "https://social.example/alyssa/inbox/", |
||||
"outbox": "https://social.example/alyssa/outbox/", |
||||
"followers": "https://social.example/alyssa/followers/", |
||||
"following": "https://social.example/alyssa/following/", |
||||
"liked": "https://social.example/alyssa/liked/"} |
||||
</code></pre> |
||||
|
||||
<aside class="notes"> |
||||
Essa é a estrutura de um ator. Existem algumas |
||||
opções importantes/interessantes aqui. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<pre><code class="hljs json" data-trim data-line-numbers="7"> |
||||
{"@context": "https://www.w3.org/ns/activitystreams", |
||||
"type": "Person", |
||||
"id": "https://social.example/alyssa/", |
||||
"name": "Alyssa P. Hacker", |
||||
"preferredUsername": "alyssa", |
||||
"summary": "Lisp enthusiast hailing from MIT", |
||||
"inbox": "https://social.example/alyssa/inbox/", |
||||
"outbox": "https://social.example/alyssa/outbox/", |
||||
"followers": "https://social.example/alyssa/followers/", |
||||
"following": "https://social.example/alyssa/following/", |
||||
"liked": "https://social.example/alyssa/liked/"} |
||||
</code></pre> |
||||
|
||||
<aside class="notes"> |
||||
Essa informação sobre o ator (que eu estou |
||||
mostrando do originador da mensagem) tem alguns |
||||
valores que são importantes. |
||||
|
||||
Por exemplo, the "inbox" tem as mensagens que |
||||
chegaram para esse usuário. |
||||
|
||||
Obviamente, não necessáriamente qualquer um pode |
||||
acessar o inbox, mas a informação pertence ao ator. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<pre><code class="hljs json" data-trim data-line-numbers="8"> |
||||
{"@context": "https://www.w3.org/ns/activitystreams", |
||||
"type": "Person", |
||||
"id": "https://social.example/alyssa/", |
||||
"name": "Alyssa P. Hacker", |
||||
"preferredUsername": "alyssa", |
||||
"summary": "Lisp enthusiast hailing from MIT", |
||||
"inbox": "https://social.example/alyssa/inbox/", |
||||
"outbox": "https://social.example/alyssa/outbox/", |
||||
"followers": "https://social.example/alyssa/followers/", |
||||
"following": "https://social.example/alyssa/following/", |
||||
"liked": "https://social.example/alyssa/liked/"} |
||||
</code></pre> |
||||
|
||||
<aside class="notes"> |
||||
Assim como o "inbox", existe o "outbox" que é tudo |
||||
que o ator enviou. Basicamente, essa é a lista de |
||||
todas as atividades do usuário específico. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<h3>Activity Stream</h3> |
||||
|
||||
<pre><code class="hljs json" data-trim> |
||||
{"@context": "https://www.w3.org/ns/activitystreams", |
||||
"type": "Create", |
||||
"id": "https://social.example/alyssa/posts/a29a6843", |
||||
"to": ["https://chatty.example/ben/"], |
||||
"actor": "https://social.example/alyssa/", |
||||
"object": {"type": "Note", |
||||
"id": "https://social.example/alyssa/posts/49e2d03d", |
||||
"attributedTo": "https://social.example/alyssa/", |
||||
"to": ["https://chatty.example/ben/"], |
||||
"content": "Did you finish reading that book?"}} |
||||
</code></pre> |
||||
|
||||
<aside class="notes"> |
||||
E uma atividade -- por exemplo, nosso ator acima |
||||
enviando um texto para outro ator. |
||||
</aside> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<img class="white stretch" src="_images/ActivityPub-tutorial-image.png" alt=""> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<h3>Client to Server Activities</h3> |
||||
|
||||
<p class="fragment"> |
||||
create, update, delete, follow, add, remove, like, |
||||
block, undo |
||||
</p> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<h3>Server to Server Activity</h3> |
||||
|
||||
<p class="fragment"> |
||||
create, update, delete, follow, accept (follow), |
||||
reject (to follow), add, remove, like, announce |
||||
(reposting/boosting), undo |
||||
</p> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>ActivityPub</h4> |
||||
<h3>Public</h3> |
||||
|
||||
<p class="fragment">https://www.w3.org/ns/activitystreams#Public</p> |
||||
</section> |
||||
</section> |
||||
|
||||
<section> |
||||
<section> |
||||
<h4>Suporte ao ActivityPub</h4> |
||||
|
||||
<ul> |
||||
<li class="fragment">ForgeFed (Código, Github)</li> |
||||
<li class="fragment">PixelFed (Fotos, Instagram)</li> |
||||
<li class="fragment">PeerTube (Videos, YouTube)</li> |
||||
<li class="fragment">HubZilla/Plume/WordPress ActivityPub Plugin (Blogging, WordPress)</li> |
||||
<li class="fragment">DistBin (Snippets, Pastebin/Gist)</li> |
||||
<li class="fragment">Diaspora (Social, Facebook)</li> |
||||
<li class="fragment">Microblog/Honk/Plemora/Mastodon (Micro-blogging, Twitter)</li> |
||||
</ul> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>Suporte ao ActivityPub</h4> |
||||
<h3>Mastodon</h3> |
||||
|
||||
<ul> |
||||
<li class="fragment">2.629 instâncias</li> |
||||
<li class="fragment">10.877.412 de contas criadas</li> |
||||
<li class="fragment">157.437 usuários ativos (última semana de novembro)</li> |
||||
<li class="fragment">1.562.887.737.129.765 toots</li> |
||||
</ul> |
||||
</section> |
||||
|
||||
<section> |
||||
<h4>Suporte ao ActivityPub</h4> |
||||
|
||||
<p> |
||||
<a href="https://fediverse.party">Fediverse</a> |
||||
</p> |
||||
</section> |
||||
</section> |
||||
|
||||
<section> |
||||
<section> |
||||
<h4>Informações Técnicas</h4> |
||||
|
||||
<ul> |
||||
<li><a href="https://www.w3.org/TR/activitypub/">ActivityPub, W3C Recommendation 23 January 2018</a></li> |
||||
<li><a href="https://nextcloud.com/blog/activitypub-the-new-standard-for-decentralized-networks/">NextCloud: ActivityPub: the new standard for decentralized networks</a></li> |
||||
<li><a href="https://hacks.mozilla.org/2018/11/decentralizing-social-interactions-with-activitypub/">Mozilla Hacks: Decentralizing Social Interactions with ActivityPub</a></li> |
||||
<li><a href="https://activitypub.rocks/">ActivityPub Rocks!</a></li> |
||||
<li><a href="https://flak.tedunangst.com/post/ActivityPub-as-it-has-been-understood">Honk: ActivityPub as it has been understood</a></li> |
||||
</ul> |
||||
</section> |
||||
</section> |
||||
|
||||
<section data-background='_images/thats-all-folks.jpg'> |
||||
<div class="semi-opaque"> |
||||
<ul class="empty"> |
||||
<li><a href="https://functional.cafe/@juliobiason">https://functional.cafe/@juliobiason</a></li> |
||||
<li><a href="https://t.me/juliobiason">https://t.me/juliobiason</a></li> |
||||
<li>julio.biason@pm.me</li> |
||||
<li><a href="http://presentations.juliobiason.net">http://presentations.juliobiason.net</a></li> |
||||
</ul> |
||||
</div> |
||||
</section> |
||||
</div> |
||||
</div> |
||||
|
||||
<script src="reveal.js/lib/js/head.min.js"></script> |
||||
<script src="reveal.js/js/reveal.js"></script> |
||||
|
||||
<script> |
||||
// Full list of configuration options available at: |
||||
// https://github.com/hakimel/reveal.js#configuration |
||||
Reveal.initialize({ |
||||
controls: true, |
||||
progress: true, |
||||
history: true, |
||||
center: true, |
||||
// showNotes: true, |
||||
|
||||
transition: 'slide', // none/fade/slide/convex/concave/zoom |
||||
|
||||
// Optional reveal.js plugins |
||||
dependencies: [ |
||||
{ src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } }, |
||||
{ src: 'reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, |
||||
{ src: 'reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, |
||||
{ src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, |
||||
{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true }, |
||||
{ src: 'reveal.js/plugin/notes/notes.js', async: true } |
||||
] |
||||
}); |
||||
</script> |
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,62 @@
|
||||
* { |
||||
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif; |
||||
font-size: 1em; |
||||
font-style: normal; |
||||
} |
||||
|
||||
body { |
||||
max-width: 50rem; |
||||
padding: 20px 10px; |
||||
background: #000; |
||||
color: #ccc; |
||||
line-height: 1rem; |
||||
margin: 0 auto; |
||||
} |
||||
|
||||
h1 { |
||||
display: block; |
||||
position: relative; |
||||
padding: 20px 0 10px; |
||||
margin 0; |
||||
overflow: hidden; |
||||
float: none; |
||||
line-height: 1.3rem; |
||||
} |
||||
|
||||
h1:after { |
||||
content: "===================================================================================================="; |
||||
position: absolute; |
||||
bottom: -7px; |
||||
left: 0; |
||||
} |
||||
|
||||
h2 { |
||||
position: relative; |
||||
margin-top: 1rem; |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
h2:before { |
||||
content: "## "; |
||||
display: inline; |
||||
} |
||||
|
||||
a, a:visited { |
||||
color: #ccc; |
||||
cursor: pointer; |
||||
border-bottom: 1px solid #ff2e88; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
a:after { |
||||
content: " " url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20class='i-external'%20viewBox='0%200%2032%2032'%20width='14'%20height='14'%20fill='none'%20stroke='%23ff9800'%20stroke-linecap='round'%20stroke-linejoin='round'%20stroke-width='9.38%'%3E%3Cpath%20d='M14%209%20L3%209%203%2029%2023%2029%2023%2018%20M18%204%20L28%204%2028%2014%20M28%204%20L14%2018'/%3E%3C/svg%3E"); |
||||
} |
||||
|
||||
div.muted { |
||||
color: rgba(255,255,255,0.5); |
||||
} |
||||
|
||||
div.hide { |
||||
display: none; |
||||
} |
||||
|
@ -0,0 +1 @@
|
||||
[{"image": "_images/tdd-kentbeck-book.jpg", "changed": "2019-02-13 10:10:13", "presentation": "unit-in-unittests-2.html", "title": "\"Unit\" em \"Unit Tests\""}, {"image": "_images/vim.png", "changed": "2019-02-13 10:10:13", "presentation": "gramatica-vim.html", "title": "A Gram\u00e1tica do VIM"}, {"image": "_images/ajax-sosp-cors-csrf.png", "changed": "2019-02-13 10:10:13", "presentation": "ajax-sosp-cors-csrf.html", "title": "AJAX / SOSP / CORS / CSRF"}, {"image": "_images/activitypub-logo.png", "changed": "2019-12-05 12:43:37", "presentation": "activitypub.html", "title": "ActivityPub"}, {"image": "_images/cargo-cult.jpg", "changed": "2019-02-15 09:45:46", "presentation": "cargo-cult.html", "title": "Cargo Cult"}, {"image": "_images/django-allauth.png", "changed": "2019-02-13 10:10:13", "presentation": "django-full.html", "title": "Django"}, {"image": "_images/django-allauth.png", "changed": "2019-02-13 10:10:13", "presentation": "django.html", "title": "Entendendo Django"}, {"image": "_images/django-rest.png", "changed": "2019-02-13 10:10:13", "presentation": "django-rest.html", "title": "Entendendo Django REST Framework"}, {"image": "_images/tdd-kentbeck-book.jpg", "changed": "2019-11-14 11:27:47", "presentation": "filosofando-testes.html", "title": "Filosofando sobre Testes"}, {"image": "_images/flask.png", "changed": "2019-02-13 10:10:13", "presentation": "flask-40mins.html", "title": "Flask em 40 Minutos ou Menos"}, {"image": "_images/streamprocessing-flink.png", "changed": "2019-09-12 14:52:26", "presentation": "flink.html", "title": "Flink"}, {"image": "_images/python.jpg", "changed": "2019-11-14 11:27:47", "presentation": "fugindo-com-python-2.html", "title": "Fugindo para as Colinas Com Python"}, {"image": "_images/Sketch27014711.png", "changed": "2019-02-13 10:10:13", "presentation": "gitsvn.html", "title": "GIT + GIT-SVN"}, {"image": "_images/git-workflow-gitflow.png", "changed": "2019-02-13 10:10:13", "presentation": "gitflow.html", "title": "GIT Flow"}, {"image": "_images/rust.png", "changed": "2019-02-15 09:45:46", "presentation": "rust-legal.html", "title": "O Que Rust Tem de Legal"}, {"image": "_images/tchelinux.png", "changed": "2019-10-16 11:02:29", "presentation": "tchelinux.html", "title": "O Que \u00c9 o Tchelinux?"}, {"image": "_images/osi_keyhole_300X300_90ppi_0.png", "changed": "2019-11-14 11:27:47", "presentation": "porque-como-opensource.html", "title": "Por que e Como Participar de Projetos Open Source"}, {"image": "_images/rust-ferris.png", "changed": "2019-11-14 11:27:47", "presentation": "porque-rust.html", "title": "Porque Voc\u00ea Deveria Aprender Rust"}, {"image": "_images/poa.jpg", "changed": "2019-02-13 10:10:13", "presentation": "pypoa.html", "title": "PyPoa 2014"}, {"image": "_images/snake-six.jpg", "changed": "2019-02-13 10:10:13", "presentation": "python23six.html", "title": "Python 2 + 3 = Six"}, {"image": "_images/python.jpg", "changed": "2019-02-13 10:10:13", "presentation": "python36.html", "title": "Python 3.6"}, {"image": "_images/Seascapeshd.png", "changed": "2019-02-13 10:10:13", "presentation": "rest.html", "title": "ReST"}, {"image": "_images/rustlatam.png", "changed": "2019-04-16 18:16:30", "presentation": "rustlatam-2019.html", "title": "Rust Latam 2019"}, {"image": "_images/rust-ferris.png", "changed": "2019-07-03 09:56:18", "presentation": "quick-rust.html", "title": "R\u00e1pida Introdu\u00e7\u00e3o ao Rust"}, {"image": "_images/Eau_Rouge_1997.jpg", "changed": "2019-02-13 10:10:13", "presentation": "spa.html", "title": "SPA"}, {"image": "_images/streamprocessing.jpg", "changed": "2019-11-14 11:27:47", "presentation": "intro-stream-processing.html", "title": "Uma N\u00e3o-Gentil Introdu\u00e7\u00e3o ao Stream Processing"}] |
@ -0,0 +1,670 @@
|
||||
:root { |
||||
--accent: rgb(35,176,255); |
||||
--accent-alpha-70: rgba(35,176,255,.7); |
||||
--accent-alpha-20: rgba(35,176,255,.2); |
||||
--background: #1D212C; |
||||
--color: white; |
||||
--border-color: rgba(255, 255, 255, .1) |
||||
} |
||||
|
||||
|
||||
.button-container { |
||||
display:table; |
||||
margin-left:auto; |
||||
margin-right:auto |
||||
} |
||||
button, |
||||
.button, |
||||
a.button { |
||||
position:relative; |
||||
display:flex; |
||||
align-items:center; |
||||
justify-content:center; |
||||
padding:8px 18px; |
||||
margin-bottom:5px; |
||||
text-align:center; |
||||
border-radius:8px; |
||||
border:1px solid transparent; |
||||
appearance:none; |
||||
cursor:pointer; |
||||
outline:none |
||||
} |
||||
button.outline, |
||||
.button.outline, |
||||
a.button.outline { |
||||
background:transparent; |
||||
box-shadow:none; |
||||
padding:8px 18px |
||||
} |
||||
button.outline :hover, |
||||
.button.outline :hover, |
||||
a.button.outline :hover { |
||||
transform:none; |
||||
box-shadow:none |
||||
} |
||||
button.primary, |
||||
.button.primary, |
||||
a.button.primary { |
||||
box-shadow:0 4px 6px rgba(50,50,93,0.11),0 1px 3px rgba(0,0,0,0.08) |
||||
} |
||||
button.primary:hover, |
||||
.button.primary:hover, |
||||
a.button.primary:hover { |
||||
box-shadow:0 2px 6px rgba(50,50,93,0.21),0 1px 3px rgba(0,0,0,0.08) |
||||
} |
||||
button.link, |
||||
.button.link, |
||||
a.button.link { |
||||
background:none; |
||||
font-size:1rem |
||||
} |
||||
button.small, |
||||
.button.small, |
||||
a.button.small { |
||||
font-size:.8rem |
||||
} |
||||
button.wide, |
||||
.button.wide, |
||||
a.button.wide { |
||||
min-width:200px; |
||||
padding:14px 24px |
||||
} |
||||
a.read-more, |
||||
a.read-more:hover, |
||||
a.read-more:active { |
||||
display:inline-flex; |
||||
background:none; |
||||
box-shadow:none; |
||||
padding:0; |
||||
max-width:100% |
||||
} |
||||
.code-toolbar { |
||||
margin-bottom:20px |
||||
} |
||||
.code-toolbar .toolbar-item a { |
||||
position:relative; |
||||
display:inline-flex; |
||||
align-items:center; |
||||
justify-content:center; |
||||
padding:3px 8px; |
||||
margin-bottom:5px; |
||||
text-align:center; |
||||
font-size:13px; |
||||
font-weight:500; |
||||
border-radius:8px; |
||||
border:1px solid transparent; |
||||
appearance:none; |
||||
cursor:pointer; |
||||
outline:none |
||||
} |
||||
.header { |
||||
display:flex; |
||||
flex-direction:column; |
||||
position:relative; |
||||
} |
||||
.header__inner { |
||||
display:flex; |
||||
align-items:center; |
||||
justify-content:space-between |
||||
} |
||||
.header__logo { |
||||
display:flex; |
||||
flex:1 |
||||
} |
||||
.header__logo:after { |
||||
content:''; |
||||
background:repeating-linear-gradient(90deg, var(--accent), var(--accent) 2px, transparent 0, transparent 16px); |
||||
display:block; |
||||
width:100%; |
||||
right:10px |
||||
} |
||||
.header__logo a { |
||||
flex:0 0 auto; |
||||
max-width:100% |
||||
} |
||||
.header .menu { |
||||
margin:20px 0 0 |
||||
} |
||||
.header .menu__inner { |
||||
display:flex; |
||||
flex-wrap:wrap; |
||||
list-style:none; |
||||
margin:0; |
||||
padding:0 |
||||
} |
||||
.header .menu__inner li.active { |
||||
color:var(--accent-alpha-70) |
||||
} |
||||
.header .menu__inner li:not(:last-of-type) { |
||||
margin-right:20px; |
||||
margin-bottom:10px; |
||||
flex:0 0 auto |
||||
} |
||||
.header .menu__sub-inner { |
||||
position:relative; |
||||
list-style:none; |
||||
padding:0; |
||||
margin:0 |
||||
} |
||||
.header .menu__sub-inner:not(:only-child) { |
||||
margin-left:20px |
||||
} |
||||
.header .menu__sub-inner-more { |
||||
position:absolute; |
||||
background:var(--background); |
||||
box-shadow:var(--shadow); |
||||
color:white; |
||||
border:2px solid; |
||||
margin:0; |
||||
padding:10px; |
||||
list-style:none; |
||||
z-index:99; |
||||
top:35px; |
||||
left:0 |
||||
} |
||||
.header .menu__sub-inner-more-trigger { |
||||
color:var(--accent); |
||||
user-select:none; |
||||
cursor:pointer |
||||
} |
||||
.header .menu__sub-inner-more li { |
||||
margin:0; |
||||
padding:5px; |
||||
white-space:nowrap |
||||
} |
||||
.logo { |
||||
display:flex; |
||||
align-items:center; |
||||
text-decoration:none; |
||||
background:var(--accent); |
||||
color:black; |
||||
padding:5px 10px |
||||
} |
||||
html { |
||||
box-sizing:border-box |
||||
} |
||||
*, |
||||
*:before, |
||||
*:after { |
||||
box-sizing:inherit |
||||
} |
||||
body { |
||||
margin:0; |
||||
padding:0; |
||||
font-family:Hack, DejaVu Sans Mono, Monaco, Consolas, Ubuntu Mono, monospace; |
||||
font-size:1rem; |
||||
line-height:1.54; |
||||
background-color:var(--background); |
||||
color:var(--color); |
||||
text-rendering:optimizeLegibility; |
||||
-webkit-font-smoothing:antialiased; |
||||
-webkit-overflow-scrolling:touch; |
||||
-webkit-text-size-adjust:100% |
||||
} |
||||
@media (max-width: 683px) { |
||||
body { |
||||
font-size:1rem |
||||
} |
||||
} |
||||
h1, |
||||
h2, |
||||
h3, |
||||
h4, |
||||
h5, |
||||
h6 { |
||||
display:flex; |
||||
align-items:center; |
||||
font-weight:bold; |
||||
line-height:1.3 |
||||
} |
||||
h1 { |
||||
font-size:1.4rem |
||||
} |
||||
h2 { |
||||
font-size:1.3rem |
||||
} |
||||
h3 { |
||||
font-size:1.2rem |
||||
} |
||||
h4, |
||||
h5, |
||||
h6 { |
||||
font-size:1.15rem |
||||
} |
||||
a { |
||||
color:inherit |
||||
} |
||||
img { |
||||
display:block; |
||||
max-width:100% |
||||
} |
||||
img.left { |
||||
margin-right:auto |
||||
} |
||||
img.center { |
||||
margin-left:auto; |
||||
margin-right:auto |
||||
} |
||||
img.right { |
||||
margin-left:auto |
||||
} |
||||
p { |
||||
margin-bottom:20px |
||||
} |
||||
figure { |
||||
display:table; |
||||
max-width:100%; |
||||
margin:25px 0 |
||||
} |
||||
figure.left img { |
||||
margin-right:auto |
||||
} |
||||
figure.center img { |
||||
margin-left:auto; |
||||
margin-right:auto |
||||
} |
||||
figure.right img { |
||||
margin-left:auto |
||||
} |
||||
figure figcaption { |
||||
font-size:14px; |
||||
padding:5px 10px; |
||||
margin-top:5px; |
||||
background:var(--accent); |
||||
color:var(--background) |
||||
} |
||||
figure figcaption.left { |
||||
text-align:left |
||||
} |
||||
figure figcaption.center { |
||||
text-align:center |
||||
} |
||||
figure figcaption.right { |
||||
text-align:right |
||||
} |
||||
code { |
||||
font-family:Hack, DejaVu Sans Mono, Monaco, Consolas, Ubuntu Mono, monospace; |
||||
font-feature-settings:normal; |
||||
background:var(--accent-alpha-20); |
||||
padding:1px 6px; |
||||
margin:0 2px; |
||||
font-size:.95rem |
||||
} |
||||
pre { |
||||
font-family:Hack, DejaVu Sans Mono, Monaco, Consolas, Ubuntu Mono, monospace; |
||||
padding:20px; |
||||
font-size:.95rem; |
||||
overflow:auto; |
||||
border-top:1px solid rgba(255,255,255,0.1); |
||||
border-bottom:1px solid rgba(255,255,255,0.1) |
||||
} |
||||
@media (max-width: 683px) { |
||||
pre { |
||||
white-space:pre-wrap; |
||||
word-wrap:break-word |
||||
} |
||||
} |
||||
blockquote { |
||||
margin:8px 50px; |
||||
padding:8px |
||||
} |
||||
@media (max-width: 683px) { |
||||
blockquote { |
||||
padding-right:0 |
||||
} |
||||
} |
||||
blockquote:before { |
||||
content:'”'; |
||||
font-family:Georgia, serif; |
||||
font-size:3.875rem; |
||||
position:absolute; |
||||
left:-40px; |
||||
top:-20px |
||||
} |
||||
blockquote p:first-of-type { |
||||
margin-top:0 |
||||
} |
||||
blockquote p:last-of-type { |
||||
margin-bottom:0 |
||||
} |
||||
blockquote p { |
||||
position:relative |
||||
} |
||||
blockquote p:before { |
||||
content:'>'; |
||||
display:block; |
||||
position:absolute; |
||||
left:-25px; |
||||
color:var(--accent) |
||||
} |
||||
table { |
||||
table-layout:fixed; |
||||
border-collapse:collapse; |
||||
width:100%; |
||||
margin:40px 0 |
||||
} |
||||
table, |
||||
th, |
||||
td { |
||||
border:1px dashed var(--accent); |
||||
padding:10px |
||||
} |
||||
th { |
||||
color:var(--accent) |
||||
} |
||||
ul, |
||||
ol { |
||||
margin-left:30px; |
||||
padding:0 |
||||
} |
||||
ul li, |
||||
ol li { |
||||
position:relative |
||||
} |
||||
@media (max-width: 683px) { |
||||
ul, |
||||
ol { |
||||
margin-left:20px |
||||
} |
||||
} |
||||
ul ul, |
||||
ul ol, |
||||
ol ul, |
||||
ol ol { |
||||
margin-top:20px |
||||
} |
||||
ol ol { |
||||
list-style-type:lower-alpha |
||||
} |
||||
.container { |
||||
display:flex; |
||||
flex-direction:column; |
||||
padding:40px; |
||||
max-width:864px; |
||||
min-height:100vh; |
||||
margin:0 auto |
||||
} |
||||
@media (max-width: 683px) { |
||||
.container { |
||||
padding:20px |
||||
} |
||||
} |
||||
.content { |
||||
display:flex |
||||
} |
||||
hr { |
||||
width:100%; |
||||
border:none; |
||||
background:var(--border-color); |
||||
height:1px |
||||
} |
||||
.hidden { |
||||
display:none |
||||
} |
||||
.posts { |
||||
/* margin:0 auto */ |
||||
} |
||||
.post { |
||||
width:100%; |
||||
text-align:left; |
||||
margin:8px auto; |
||||
padding:20px 0 |
||||
} |
||||
@media (max-width: 899px) { |
||||
.post { |
||||
max-width:660px |
||||
} |
||||
} |
||||
.post .post-meta, |
||||
.post .post-meta-inline { |
||||
font-size:1rem; |
||||
margin-bottom:10px; |
||||
color:var(--accent-alpha-70) |
||||
} |
||||
.post-meta-inline { |
||||
display:inline |
||||
} |
||||
.post-title { |
||||
position:relative; |
||||
color:var(--accent); |
||||
margin:0 0 8px; |
||||
border-bottom:var(--border); |
||||
font-weight:normal |
||||
} |
||||
.post-title a { |
||||
text-decoration:none |
||||
} |
||||
.post .post-tags, |
||||
.post .post-tags-inline { |
||||
margin-bottom:20px; |
||||
font-size:1rem; |
||||
opacity:.5 |
||||
} |
||||
.post-tags { |
||||
display:block |
||||
} |
||||
.post-tags-inline { |
||||
display:inline |
||||
} |
||||
@media (max-width: 683px) { |
||||
.post-tags-inline { |
||||
display:block |
||||
} |
||||
} |
||||
.post-content { |
||||
margin-top:8px |
||||
} |
||||
.post-cover { |
||||
border:20px solid var(--accent); |
||||
background:transparent; |
||||
margin:40px 0; |
||||
padding:20px |
||||
} |
||||
@media (max-width: 683px) { |
||||
.post-cover { |
||||
padding:10px; |
||||
border-width:10px |
||||
} |
||||
} |
||||
.post ul { |
||||
list-style:none |
||||
} |
||||
.post ul li:before { |
||||
content:'►'; |
||||
position:absolute; |
||||
left:-20px; |
||||
color:var(--accent) |
||||
} |
||||
.post--regulation h1 { |
||||
justify-content:center |
||||
} |
||||
.post--regulation h2 { |
||||
justify-content:center; |
||||
margin-bottom:10px |
||||
} |
||||
.post--regulation h2+h2 { |
||||
margin-top:-10px; |
||||
margin-bottom:20px |
||||
} |
||||
.post-list .post-date { |
||||
color:var(--accent-alpha-70); |
||||
text-decoration:none |
||||
} |
||||
.post-list a { |
||||
text-decoration:none |
||||
} |
||||
.post-list .post-list-title { |
||||
text-decoration:underline |
||||
} |
||||
.post-list .post-tag { |
||||
text-decoration:underline |
||||
} |
||||
.pagination { |
||||
margin-top:50px |
||||
} |
||||
.pagination__title { |
||||
display:flex; |
||||
text-align:center; |
||||
position:relative; |
||||
margin:100px 0 20px |
||||
} |
||||
.pagination__title-h { |
||||
text-align:center; |
||||
margin:0 auto; |
||||
padding:5px 10px; |
||||
background:var(--background); |
||||
font-size:.8rem; |
||||
text-transform:uppercase; |
||||
letter-spacing:.1em; |
||||
z-index:1 |
||||
} |
||||
.pagination__title hr { |
||||
position:absolute; |
||||
left:0; |
||||
right:0; |
||||
width:100%; |
||||
margin-top:15px; |
||||
z-index:0 |
||||
} |
||||
.pagination__buttons { |
||||
display:flex; |
||||
align-items:center; |
||||
justify-content:center |
||||
} |
||||
@media (max-width: 683px) { |
||||
.pagination__buttons { |
||||
flex-direction:column |
||||
} |
||||
} |
||||
.button { |
||||
position:relative; |
||||
display:inline-flex; |
||||
align-items:center; |
||||
justify-content:center; |
||||
font-size:1rem; |
||||
border-radius:8px; |
||||
max-width:40%; |
||||
padding:0; |
||||
cursor:pointer; |
||||
appearance:none |
||||
} |
||||
@media (max-width: 683px) { |
||||
.button { |
||||
max-width:80% |
||||
} |
||||
} |
||||
.button+.button { |
||||
margin-left:10px |
||||
} |
||||
.button a { |
||||
display:flex; |
||||
padding:8px 16px; |
||||
text-overflow:ellipsis; |
||||
white-space:nowrap; |
||||
overflow:hidden |
||||
} |
||||
.button__text { |
||||
text-overflow:ellipsis; |
||||
white-space:nowrap; |
||||
overflow:hidden |
||||
} |
||||
.footer { |
||||
padding:40px 0; |
||||
flex-grow:0; |
||||
opacity:.5 |
||||
} |
||||
.footer__inner { |
||||
display:flex; |
||||
align-items:center; |
||||
justify-content:space-between; |
||||
margin:0; |
||||
width:760px; |
||||
max-width:100% |
||||
} |
||||
@media (max-width: 899px) { |
||||
.footer__inner { |
||||
flex-direction:column |
||||
} |
||||
} |
||||
.footer a { |
||||
color:inherit |
||||
} |
||||
.footer .copyright { |
||||
display:flex; |
||||
flex-direction:row; |
||||
align-items:center; |
||||
font-size:1rem; |
||||
color:var(--light-color-secondary) |
||||
} |
||||
.footer .copyright--user { |
||||
margin:auto; |
||||
text-align:center |
||||
} |
||||
.footer .copyright>*:first-child:not(:only-child) { |
||||
margin-right:10px |
||||
} |
||||
@media (max-width: 899px) { |
||||
.footer .copyright>*:first-child:not(:only-child) { |
||||
border:none; |
||||
padding:0; |
||||
margin:0 |
||||
} |
||||
} |
||||
@media (max-width: 899px) { |
||||
.footer .copyright { |
||||
flex-direction:column; |
||||
margin-top:10px |
||||
} |
||||
} |
||||
@media (max-width: 899px) { |
||||
.footer .copyright-theme-sep { |
||||
display:none |
||||
} |
||||
} |
||||
@media (max-width: 899px) { |
||||
.footer .copyright-theme { |
||||
font-size:0.75rem |
||||
} |
||||
} |
||||
.footnote-definition { |
||||
margin-bottom:8px |
||||
} |
||||
.footnote-definition p { |
||||
display:inline |
||||
} |
||||
|
||||
/*! |
||||
* Hack typeface https://github.com/source-foundry/Hack |
||||
* License: https://github.com/source-foundry/Hack/blob/master/LICENSE.md |
||||
*/@font-face { |
||||
font-family:'Hack'; |
||||
src:url("fonts/hack-regular.woff2?sha=3114f1256") format("woff2"), |
||||
url("fonts/hack-regular.woff?sha=3114f1256") format("woff"); |
||||
font-weight:400; |
||||
font-style:normal |
||||
} |
||||
@font-face { |
||||
font-family:'Hack'; |
||||
src:url("fonts/hack-bold.woff2?sha=3114f1256") format("woff2"), |
||||
url("fonts/hack-bold.woff?sha=3114f1256") format("woff"); |
||||
font-weight:700; |
||||
font-style:normal |
||||
} |
||||
@font-face { |
||||
font-family:'Hack'; |
||||
src:url("fonts/hack-italic.woff2?sha=3114f1256") format("woff2"), |
||||
url("fonts/hack-italic.woff?sha=3114f1256") format("woff"); |
||||
font-weight:400; |
||||
font-style:italic |
||||
} |
||||
@font-face { |
||||
font-family:'Hack'; |
||||
src:url("fonts/hack-bolditalic.woff2?sha=3114f1256") format("woff2"), |
||||
url("fonts/hack-bolditalic.woff?sha=3114f1256") format("woff"); |
||||
font-weight:700; |
||||
font-style:italic |
||||
} |
||||
|
||||
.hide { |
||||
display: none; |
||||
} |