├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── admin ├── hardware-inventory.md └── take.md ├── build.sh ├── general ├── extra-resources.md ├── laptop-setup-instructions.md ├── module-template.md ├── post-workshop-survey.md ├── pre-workshop-survey.md └── welcome-email.md ├── install-dependencies.sh ├── module-1 ├── README.md ├── handouts │ ├── 2-peer-to-peer-file-sharing-on-a-mesh.md │ ├── 2-sistema-p2p-en-red-mallada_es.md │ ├── 3-community-local-impact.md │ ├── 3-design-access.md │ ├── 3-mission-ownership.md │ ├── 3-profit-sustainability.md │ ├── 3-teaching-learning.md │ └── peer-to-peer-applications.svg ├── presentation.html └── slide-images │ ├── home-internet.svg │ ├── mesh-topology.svg │ └── peer-to-peer-applications.svg ├── module-2 ├── README.md ├── handouts │ ├── 2-your-node-in-a-mesh-network.md │ └── 3-cards-of-tlds.md ├── presentation.html └── slide-images │ ├── peer-to-peer-applications.svg │ └── three-node-mesh-network.svg ├── module-3 ├── README.md ├── handouts │ ├── 2-configuration-cards.md │ └── 2-mesh-your-node-wirelessly.md ├── presentation.html └── slide-images │ ├── antenna.svg │ ├── power-supply.svg │ ├── radio.svg │ ├── single-board-computer.svg │ └── storage.svg ├── module-4 ├── README.md ├── handouts │ └── ft-york.pdf └── presentation.html ├── module-5 ├── README.md ├── handouts │ └── 2-bandwidth-testing-with-a-video-stream.md └── presentation.html ├── module-6 ├── README.md ├── presentation.html └── slide-images │ ├── decoding-lora.jpg │ ├── sl-testnode0-bb.png │ ├── smart-home.svg │ ├── steamlink-setup.svg │ └── wireless-tech.svg ├── package.sh ├── pdf.css ├── site ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── _includes │ ├── contents.html │ ├── footer.html │ ├── navigation.html │ └── videowrapper.html ├── _layouts │ ├── default.html │ ├── home.html │ └── page.html ├── contents.html ├── css │ ├── main.css │ ├── mofo-bootstrap.css │ └── syntax.css └── img │ ├── cc-logo.svg │ ├── favicon.png │ ├── footer-icon-conduct.svg │ ├── footer-icon-email.svg │ ├── footer-icon-github.svg │ ├── footer-icon-help.svg │ ├── footer-icon-irc.svg │ ├── footer-icon-terms.svg │ ├── footer-icon-twitter.svg │ └── hero.png ├── slide-files ├── fonts │ ├── jost │ │ ├── LICENSE.md │ │ ├── jost-100-hairline.woff2 │ │ ├── jost-100-hairlineitalic.woff2 │ │ ├── jost-200-thin.woff2 │ │ ├── jost-200-thinitalic.woff2 │ │ ├── jost-300-light.woff2 │ │ ├── jost-300-lightitalic.woff2 │ │ ├── jost-400-book.woff2 │ │ ├── jost-400-bookitalic.woff2 │ │ ├── jost-500-medium.woff2 │ │ ├── jost-500-mediumitalic.woff2 │ │ ├── jost-600-semi.woff2 │ │ ├── jost-600-semiitalic.woff2 │ │ ├── jost-700-bold.woff2 │ │ ├── jost-700-bolditalic.woff2 │ │ ├── jost-800-heavy.woff2 │ │ ├── jost-800-heavyitalic.woff2 │ │ ├── jost-900-black.woff2 │ │ ├── jost-900-blackitalic.woff2 │ │ └── jost.css │ ├── ubuntu-mono │ │ ├── LICENSE.txt │ │ ├── UbuntuMono-Bold.woff2 │ │ ├── UbuntuMono-BoldItalic.woff2 │ │ ├── UbuntuMono-Italic.woff2 │ │ ├── UbuntuMono-Regular.woff2 │ │ └── ubuntu-mono.css │ └── zilla-slab │ │ ├── LICENSE.txt │ │ ├── ZillaSlab-Bold.woff2 │ │ ├── ZillaSlab-BoldItalic.woff2 │ │ ├── ZillaSlab-Italic.woff2 │ │ ├── ZillaSlab-Light.woff2 │ │ ├── ZillaSlab-LightItalic.woff2 │ │ ├── ZillaSlab-Medium.woff2 │ │ ├── ZillaSlab-MediumItalic.woff2 │ │ ├── ZillaSlab-Regular.woff2 │ │ ├── ZillaSlab-SemiBold.woff2 │ │ ├── ZillaSlab-SemiBoldItalic.woff2 │ │ └── zilla-slab.css ├── polyfills.js ├── remark.html ├── remark.js ├── remark.less └── slide.css └── wip-pdf.css /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated asset directory 2 | output 3 | publish 4 | 5 | # GitBook 6 | _book 7 | book.pdf 8 | book.epub 9 | book.mobi 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | install: "./install-dependencies.sh" 2 | 3 | script: "./build.sh" 4 | 5 | before_deploy: "./package.sh $TRAVIS_TAG" 6 | 7 | deploy: 8 | - provider: releases 9 | api_key: 10 | secure: VnXRjvEsJKZJ0mto3ZMOFccE8QzuRvqyxm6juM05g3Z9GuC1E3wuQI+3N0qSinkxUpzbjfSWhBSeApN7cKPKYJTBehDA6euQyTTY12LbZliSNkwmS2YBfPjJqll4/kCLMzYvaQwVbPijhIUYOCUI/6x28OGJUSohdH3RplJ68LGsIzbTkZ/j17u6iKDIqzmazngTMriWaNC5eKGTSYLXbTibJxJtYOTi8OcsvuAd5KGQpU06MJFxB5ARCK1WATwHIeLWsIKux670vJkH2duYRxexirRcL5C42PwqqihalW4JC7nEilC2IMq2MUGlTeO2ph8UEKZ4O/w0BZTOvb1SJ2YJlfF1lm1Hu/LiEw1pDzkWA1DcneyvAezCjJ9cEjqT2nRPqBY3e/OSjpH7pFMr0o8xaX0N3MRzvZ7Lu/7Ds/DMZeavqE+UVLLvb3BKqboJYwl3T0tN452zUkGpiP+MNW+ZECKbd5FGF9kpSLfGG4rT7FFtVAvPkqzwKuX+1QCFOXemrrtfcL6H7uDIJzlzz7qxccIo5rGfeb/XXNeAVc0+L3S9DNHN+L6u0T5kOMiwO6sLabjBrqhiA6yowSMlSV1oKWDeXkzYZBC+05bA/cRpC6W+49+I1zBze9qe4YMZ1ztDtlV/E5LfbfisrWSjQQRhyvA7FxVsXLw/Q5st17Q= 11 | file: 12 | - "publish/workshop-materials-$TRAVIS_TAG.tar.gz" 13 | - "publish/workshop-materials-$TRAVIS_TAG.zip" 14 | skip_cleanup: true 15 | on: 16 | repo: tomeshnet/p2p-internet-workshop 17 | tags: true 18 | - provider: pages 19 | github-token: 20 | secure: VnXRjvEsJKZJ0mto3ZMOFccE8QzuRvqyxm6juM05g3Z9GuC1E3wuQI+3N0qSinkxUpzbjfSWhBSeApN7cKPKYJTBehDA6euQyTTY12LbZliSNkwmS2YBfPjJqll4/kCLMzYvaQwVbPijhIUYOCUI/6x28OGJUSohdH3RplJ68LGsIzbTkZ/j17u6iKDIqzmazngTMriWaNC5eKGTSYLXbTibJxJtYOTi8OcsvuAd5KGQpU06MJFxB5ARCK1WATwHIeLWsIKux670vJkH2duYRxexirRcL5C42PwqqihalW4JC7nEilC2IMq2MUGlTeO2ph8UEKZ4O/w0BZTOvb1SJ2YJlfF1lm1Hu/LiEw1pDzkWA1DcneyvAezCjJ9cEjqT2nRPqBY3e/OSjpH7pFMr0o8xaX0N3MRzvZ7Lu/7Ds/DMZeavqE+UVLLvb3BKqboJYwl3T0tN452zUkGpiP+MNW+ZECKbd5FGF9kpSLfGG4rT7FFtVAvPkqzwKuX+1QCFOXemrrtfcL6H7uDIJzlzz7qxccIo5rGfeb/XXNeAVc0+L3S9DNHN+L6u0T5kOMiwO6sLabjBrqhiA6yowSMlSV1oKWDeXkzYZBC+05bA/cRpC6W+49+I1zBze9qe4YMZ1ztDtlV/E5LfbfisrWSjQQRhyvA7FxVsXLw/Q5st17Q= 21 | local-dir: site/_site 22 | target-branch: gh-pages 23 | keep-history: false 24 | skip-cleanup: true 25 | on: 26 | repo: tomeshnet/p2p-internet-workshop 27 | tags: true 28 | -------------------------------------------------------------------------------- /admin/hardware-inventory.md: -------------------------------------------------------------------------------- 1 | # Hardware Inventory 2 | 3 | ## Current inventory 4 | 5 | | Item | Units | Status | 6 | |:-----|:------|:-------| 7 | | Raspberry Pi 3B+ with power | 6 | With @darkdrgn2k | 8 | | Toplinkst TOP-S5 | 35 | With @darkdrgn2k | 9 | | Samsung Evo Select 32 GB | 20 | With @darkdrgn2k | 10 | | LoRa hardware | 0 | Not ordered | 11 | 12 | ## Hardware allocation 13 | 14 | | Item | Units | Shipping costs (CAD) | Delivered by | For | 15 | |:--|:--|:--|:--|:--| 16 | | TOP-S5 | 3 | 20.09 | @darkdrgn2k | Florida Polytechnic | 17 | | TOP-S5 | 2 | 0.00 | @benhylau | NYU Abu Dhabi | 18 | | TOP-S5 | 3 | 0.00 | @benhylau | Amber Initiative Foundation | 19 | | TOP-S5 | 1 | 0.00 | @benhylau | @makeworld-the-better-one | 20 | | TOP-S5 | 1 | 0.00 | @benhylau | @benhylau | 21 | | TOP-S5 | 5 | 0.00 | @benhylau | People's Open | 22 | 23 | See [collaboration groups](https://github.com/tomeshnet/p2p-internet-workshop/issues/68). 24 | 25 | ## Purchased items 26 | 27 | | Item | Units | Cost (CAD) | Total (CAD) | Status | Note | 28 | |:--|--:|--:|--:|:--|:--| 29 | | [Raspberry Pi 3B+ with power](https://www.ebay.ca/itm/232708265037) | 6 | 80.29 | 481.74 (352.70 USD) | Received | Prices have gone up on Amazon, @benhylau bought from a slightly better option on ebay | 30 | | [Toplinkst TOP-S5](https://toplinkst-wifi.en.made-in-china.com/product/NyaQzvYEsGWL/China-Top-S5-802-11A-B-G-N-300Mbps-Rt5572-Dual-Band-USB-Wireless-Module-with-Ce-FCC-for-STB.html) + accessories (pigtails, antennas, [USB header](https://www.ebay.ca/itm/10PCS-USB-Male-to-2-54mm-DIP-Adapter-Converter-Board-4-Pin-PCB-DIY-Power-Supply/132646223066)) | 50 | 13.74 | 631.11 (470 USD) + 12.73 (9.48 USD) + 42.98 (customs) | Received | Price changes and shipping costs, @benhylau revised to 50 units | 31 | | [Samsung Evo Select 32 GB](https://www.amazon.com/gp/product/B06XWN9Q99/) | 20 | 11.23 | 224.51 (166.99 USD) | Received | Evo Select cards should be just like Evo Plus cards, but distributed by Samsung/Amazon officially. There were concerns over fake SD cards from third-party sources. Max allowed per order is 20 so @benhylau revised quantity | 32 | | ~~[LoRa hardware](https://www.aliexpress.com/item/LoRa-ESP32-ESP-32-0-96-Inch-Blue-OLED-Display-Bluetooth-WIFI-CP2102-LoRa-Kit-32/32856663861.html)~~ | ~~20~~ | ~~13.26~~ | ~~265.12~~ | ~~Paid~~ | Vendor shipped me the wrong item, pending refund | 33 | 34 | ## Planned purchases 35 | 36 | | Item | Units | Cost (CAD) | Total (CAD) | Use | 37 | |:--|--:|--:|--:|:--| 38 | | [Raspberry Pi 3B+ with power](https://www.amazon.ca/CanaKit-Raspberry-Premium-Clear-Supply/dp/B07BD51R39/ref=sr_1_3?ie=UTF8&qid=1537269850&sr=8-3&keywords=CanaKit) | 6 | 70 | 420 | Shared resource for local facilitators | 39 | | [Toplinkst TOP-S5](https://toplinkst-wifi.en.made-in-china.com/product/NyaQzvYEsGWL/China-Top-S5-802-11A-B-G-N-300Mbps-Rt5572-Dual-Band-USB-Wireless-Module-with-Ce-FCC-for-STB.html) + accessories (pigtails, antennas, [USB header](https://www.ebay.ca/itm/10PCS-USB-Male-to-2-54mm-DIP-Adapter-Converter-Board-4-Pin-PCB-DIY-Power-Supply/132646223066)) | 60 | 11 | 660 | Shared resource and give/sell to collaborators | 40 | | [Samsung Evo Plus 32 GB](https://es.aliexpress.com/store/product/Original-SAMSUNG-Micro-SD-card-Memory-Card-EVO-EVO-Plus-32GB-Class10-TF-Card-C10-80MB/2882215_32801860844.html?spm=a219c.search0204.3.312.597e7641Ma9jyX&ws_ab_test=searchweb0_0,searchweb201602_4_10065_10068_10547_10059_10884_10548_10887_10696_100031_309_10084_10083_10103_451_452_10618_10307_10820_10303_525,searchweb201603_55,ppcSwitch_5_ppcChannel&algo_expid=89b40dad-d8cd-4036-85a4-c48516992182-44&algo_pvid=89b40dad-d8cd-4036-85a4-c48516992182&priceBeautifyAB=0) | 24 | 11 | 264 | Shared resource and pre-image SDs to give/sell to collaborators if needed | 41 | | [LoRa hardware](https://www.aliexpress.com/item/LoRa-ESP32-ESP-32-0-96-Inch-Blue-OLED-Display-Bluetooth-WIFI-CP2102-LoRa-Kit-32/32856663861.html) | 20 | 15 | 300 | Shared resource and give/sell to collaborators who run Module 6 | 42 | 43 | See [budget and planning](https://github.com/tomeshnet/p2p-internet-workshop/issues/56). 44 | -------------------------------------------------------------------------------- /admin/take.md: -------------------------------------------------------------------------------- 1 | # Take Tracking 2 | 3 | This sheet tracks distribution of grant funding relating to the development and facilitation of this workshop. You can find out more about the "take" funds distribution process [here](https://github.com/benhylau/ssbc-grants-scuttlemesh/blob/master/README.md#funds-distribution), the basic pattern: 4 | 5 | > Once your Take Request gets two +1's from other collaborators on the list, @benhylau will send you the requested amount and merge your Pull Request. 6 | 7 | ## Secure Scuttlebutt Consortium 2018 (for ScuttleMesh) 8 | 9 | Amount: ETH 7.253 10 | See: https://github.com/benhylau/ssbc-grants-scuttlemesh 11 | Take: https://github.com/benhylau/ssbc-grants-scuttlemesh/blob/master/take.md 12 | 13 | ## IPFS Research 2018 14 | 15 | Amount: USD 5,000 (CAD 2,251.27 of which is for salaries) 16 | See: https://github.com/tomeshnet/p2p-internet-workshop/issues/55 17 | 18 | | GitHub Handle | Dec 15 | Dec 29 | 19 | |:-------------:|:------:|:------:| 20 | | @benhylau | C 1000| | 21 | | @darkdrgn2k | C 100| | 22 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Delete generated assets 4 | rm -rf output 5 | mkdir output 6 | 7 | # Set CSS styles source 8 | css="pdf.css" 9 | echo "Using CSS styles from $css" 10 | 11 | # Define starting directory 12 | base_dir="$(pwd)" 13 | 14 | # Create folder for general assets 15 | mkdir output/general 16 | 17 | # Generate general assets 18 | for doc in general/*.md; do 19 | 20 | # Generate assets as .pdf 21 | if [ -f $doc ]; then 22 | out="output/general/$(echo "$doc" | sed 's|/|-|g' | sed 's|.md|.pdf|')" 23 | echo "Generating document from $doc to $out" 24 | markdown-pdf "$doc" --out "$out" --cwd general --css-path "$css" 25 | fi 26 | done 27 | 28 | # Copy technical files used by Remark 29 | cp -r "slide-files" "output/" 30 | 31 | # Go through each module 32 | for mod in module-*; do 33 | # Create folder for module 34 | mkdir "output/$mod" 35 | 36 | # Generate lesson plan .pdf 37 | doc="$mod/README.md" 38 | if [ -f $doc ]; then 39 | out="output/$mod/$mod.pdf" 40 | echo "Generating lesson plan from $doc to $out" 41 | markdown-pdf "$doc" --out "$out" --cwd "$mod" --css-path "$css" 42 | fi 43 | 44 | # Generate handouts as .pdf 45 | mkdir "output/$mod/handouts" 46 | for doc in $mod/handouts/*.md; do 47 | if [ -f $doc ]; then 48 | out="output/$mod/handouts/$(echo "$doc" | sed 's|/|-|g' | sed 's|.md|.pdf|')" 49 | echo "Generating handouts from $doc to $out" 50 | markdown-pdf "$doc" --out "$out" --cwd "$mod/handouts" --css-path "$css" 51 | fi 52 | done 53 | 54 | # Copy Remark presentation and generate .pdf copy with DeckTape 55 | doc="presentation.html" 56 | cd $mod 57 | if [ -f $doc ]; then 58 | # Generate .pdf 59 | out="../output/$mod/handouts/$mod-presentation.pdf" 60 | echo "Generating presentation from $mod/$doc to $out" 61 | decktape remark "$doc" "$out" --chrome-arg=--allow-file-access-from-files 62 | 63 | # Copy Remark presentation 64 | cp -r "slide-images" "../output/$mod/" 65 | cp "$doc" "../output/$mod/" 66 | fi 67 | cd $base_dir 68 | 69 | done 70 | -------------------------------------------------------------------------------- /general/extra-resources.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | Resources including existing curriculum, workshop materials and lesson planning. 4 | 5 | ## Learning Development & Course Design 6 | 7 | - [Software Carpentry Learning Objectives](http://carpentries.github.io/instructor-training/14-lesson-study/) 8 | - [Verbs to Assess Learning Outcomes](https://www.clinton.edu/curriculumcommittee/listofmeasurableverbs.cxml) 9 | - [Blooms (Digital) Taxonomy](http://teachonline.asu.edu/2016/05/integrating-technology-blooms-taxonomy/) 10 | 11 | ## Curriculum 12 | 13 | - [networks.land](http://networks.land) 14 | - [Commotion Wireless](https://commotionwireless.net) 15 | - [Metamesh YouTube channel (Video)](https://www.youtube.com/channel/UCGEnntxbGKMU9J9GIZ1LQUQ) 16 | - [Detroit Community Technology Project](http://detroitcommunitytech.org/learning-materials) 17 | - [Community Technology Facilitation](http://communitytechnology.github.io/docs/facilitation/discussion-formats/) 18 | -------------------------------------------------------------------------------- /general/laptop-setup-instructions.md: -------------------------------------------------------------------------------- 1 | # Laptop Setup Instructions 2 | 3 | To participate in the workshop, you will need access to the software described below. You will also need an up-to-date web browser. 4 | 5 | ## SSH Client 6 | 7 | You will need access to an SSH client to use during the workshop to perform tasks. Please familiarize yourself with where to find it in your operating system (instructions below). 8 | 9 | ### Windows 10 | 11 | Windows does not come with an SSH client. You will need to download one to use during the workshop. A popular one is called PuTTY. To get PuTTY, follow these steps: 12 | 13 | 1. Download [PuTTY](https://www.putty.org). 14 | 15 | 2. Place the downloaded file on your desktop for easy access. 16 | 17 | ### macOS 18 | 19 | On macOS there is a built-in SSH client you can access from your Terminal. You can find the Terminal by opening your Applications folder, then opening the Utilities folder. The Terminal application will be amongst the icons there. You may want to add this to your dock. 20 | 21 | ### Linux 22 | 23 | On Linux there is a built-in SSH client you can access from your Terminal. Linux has many ways to access the Terminal. If your distribution has a search function (like UBUNTU) look for one of these keywords: terminal, xterm, uxterm. 24 | 25 | ## Text Editor 26 | 27 | A text editor may be a helpful tool when you are working with SSH. Any editor you can write text on will do. Some examples are below: 28 | 29 | ### Windows 30 | 31 | - NotePad (pre-installed) 32 | - [Notepad++](http://notepad-plus-plus.org) 33 | - [Sublime Text](http://www.sublimetext.com) 34 | 35 | ### macOS 36 | 37 | - TextEdit (pre-installed) 38 | - [Text Wrangler](http://www.barebones.com/products/textwrangler/) 39 | - [Sublime Text](http://www.sublimetext.com) 40 | 41 | ### Linux 42 | 43 | - [Gedit](https://wiki.gnome.org/Apps/Gedit) 44 | - [Kate](http://kate-editor.org) 45 | - [Sublime Text](http://www.sublimetext.com) 46 | -------------------------------------------------------------------------------- /general/module-template.md: -------------------------------------------------------------------------------- 1 | # Module Template 2 | 3 | Total length: 1.5 hour 4 | Planned: 1.25 hour 5 | 6 | | **Section** | **Length** | 7 | |----------------------------------------------------|------------| 8 | | **1: Topic introduction** | 15 min | 9 | | **2: Hands-on and material exploration** | 40 min | 10 | | **3: Discussion and reflection activity** | 20 min | 11 | | **4: Wrap-up and week ahead** | 5 min | 12 | 13 | ## 1: Topic introduction 14 | 15 | - Break up dense material into class discussion or more engaging material 16 | 17 | ## 2: Hands-on and material exploration 18 | 19 | - Mostly peer-to-peer style facilitation with multiple helpers 20 | 21 | ### Objectives 22 | 23 | - Learning objectives of the activity 24 | 25 | ### Materials 26 | 27 | - Materials required for the activity 28 | 29 | ### Format 30 | 31 | - Format (_Individuals_, _Pairs_, _Groups_, or _Class_) of the activity 32 | 33 | ### Activity 34 | 35 | - Rundown of the activity 36 | 37 | ## 3: Discussion and reflection activity 38 | 39 | - Interactive (class discussions and questions) 40 | 41 | ## 4: Wrap-up and week ahead 42 | 43 | - Video + article(s) during the week for flip classroom during class -------------------------------------------------------------------------------- /general/post-workshop-survey.md: -------------------------------------------------------------------------------- 1 | # Building the Peer-to-Peer Internet 2 | ## Post-Workshop Survey 3 | 4 | 1. Did you attend Building the Peer-to-Peer Internet? _(Yes, No) *_ 5 | 6 | 1. Please give us some feedback about the workshops overall. _(Yes, No)_ 7 | 8 | - The amount of information covered was reasonable for allotted time 9 | - The overall atmosphere was welcoming 10 | - I learned skills that I will be able to use in my day to day life 11 | - The event was worth my time 12 | 13 | 1. How likely are you to recommend the workshop series to a friend or colleague? _(0 – 10)_ 14 | 15 | 1. How much of the information presented in the workshops was new to you? _(None of the information, Some of the information, About half of the information, Most of the information, All of the information)_ 16 | 17 | 1. How organized was the event? _(Extremely organized, Very organized, Somewhat organized, Not so organized, Not at all organized)_ 18 | 19 | 1. How did you perceive the pace of workshops overall? _(Too slow, Slightly slow, Just right, Slightly fast, Too fast)_ 20 | 21 | 1. Tell us about your previous experience with the following topics: 22 | 23 | - Unix shell 24 | - Networking 25 | - Decentralized services 26 | - Mesh networks 27 | - Microcontrollers and single-board computers (e.g. Raspberry Pi or Arduino) 28 | 29 | 1. Tell us about changes in your knowledge on these topics: 30 | 31 | - Unix shell 32 | - Networking 33 | - Decentralized services 34 | - Mesh networks 35 | - Microcontrollers and single-board computers (e.g. Raspberry Pi or Arduino) 36 | 37 | 1. What did you like or dislike about the event? 38 | 39 | ``` 40 | 41 | 42 | 43 | ``` 44 | 45 | 1. Final thoughts? Anything we could do to improve? 46 | 47 | ``` 48 | 49 | 50 | 51 | ``` 52 | -------------------------------------------------------------------------------- /general/pre-workshop-survey.md: -------------------------------------------------------------------------------- 1 | # Building the Peer-to-Peer Internet 2 | ## Pre-Workshop Survey 3 | 4 | 1. I consent to this survey _(Yes) *_ 5 | 6 | 1. Are you age 18 or above? We should not collect if under 18. _(Yes, No) *_ 7 | 8 | 1. In a few words, what is your most important reason for attending this workshop? 9 | 10 | ``` 11 | 12 | 13 | 14 | ``` 15 | 16 | 1. Below are some reasons we think people will come to Toronto Mesh workshops. Some of these reasons may overlap with the reasons you suggested above. How important were these reasons to you? _(Not at all important, Slightly important, Important, Very important, N/A)_ 17 | 18 | - Improve your knowledge of networking and the internet 19 | - Join an active project or group of enthusiasts 20 | - Experiment with new software and tools related to your interests 21 | - Network with other workshop attendees 22 | - Learn new or update existing skills 23 | 24 | 1. Besides the course content, what importance did the following factors have on your choice to attend the workshop? _(Not at all important, Slightly important, Important, Very important, N/A)_ 25 | 26 | - Attending an in-person/live workshop 27 | - Location and timing of workshop 28 | - Learning with friends/colleagues 29 | - Other (please specify) 30 | 31 | 1. How did you hear about Toronto Mesh / Building the Peer-to-Peer Internet workshop? _(Select all that apply)_ 32 | 33 | - Friend/colleague 34 | - Conference/meeting/seminar 35 | - Library website or flyer 36 | - Journal or publication 37 | - Our website 38 | - Social Media (Twitter, Facebook, etc.) 39 | - Other (please specify) 40 | 41 | 1. If you experienced any strong concerns about attending this workshop, can you let us know what they were? Are there ways we can address them? 42 | 43 | ``` 44 | 45 | 46 | 47 | ``` 48 | 49 | 1. Tell us about your experience with the following topics: _Current knowledge (Little or no knowledge, Some knowledge, Extensive knowledge), Perception about this topic (Very intimidating, Slightly intimidating, Neither intimidating nor unintimidating, Not very intimidating, Not at all intimidating, No opinion)_ 50 | 51 | - Unix shell 52 | - Networking 53 | - Decentralized services 54 | - Mesh networks 55 | - Microcontrollers and single-board computers (e.g. Raspberry Pi or Arduino) 56 | 57 | 1. How would you rate your motivation to learn about these topics? _(Not at all motivated, Slightly motivated, Motivated, Very motivated, Not relevant or not sure what this is)_ 58 | 59 | - Unix shell 60 | - Networking 61 | - Decentralized services 62 | - Mesh networks 63 | - Microcontrollers and single-board computers (e.g. Raspberry Pi or Arduino) 64 | 65 | 1. How would you describe your ability to do the following tasks? _(Yes, No, Maybe)_ 66 | 67 | - Use terminal or command line to list files in a directory 68 | - Log in or 'ssh into' a server 69 | - Log in to router admin panel (i.e. to change network password) 70 | - Update software or firmware on a router 71 | -------------------------------------------------------------------------------- /general/welcome-email.md: -------------------------------------------------------------------------------- 1 | # Welcome Email 2 | 3 | Hello, 4 | 5 | We are excited for the first Building the Peer-to-Peer Internet workshop, and we hope you are too! The workshops run on Tuesdays, April 10 to May 15 from 6:30-8:00 p.m. at the Fort York library. Here are a few notes to get you ready for the first session. 6 | 7 | 1. Please complete the pre-workshop survey [ link to survey ]. We use this to set the pace of the workshop and, together with a post-workshop survey, to assess how it went in order to improve for future sessions. 8 | 2. Make sure you have administrator privileges on your laptop. 9 | 3. We will be using an SSH client and Text Editor software. You likely already have it installed on your computer. Set up instructions can be found at https://github.com/tomeshnet/p2p-internet-workshop/blob/master/SETUP.md 10 | 11 | If you have any trouble, send us an email at hello@tomesh.net or come a little early Tuesday April 10 before the class. 12 | 13 | If you are no longer able to attend, please let us know at hello@tomesh.net so that we can offer your seat to someone on the waitlist. 14 | 15 | Links that will be used in the workshop: 16 | - Workshop information https://tomesh.net/peer-to-peer-internet/ 17 | - Lesson materials https://github.com/tomeshnet/p2p-internet-workshop/ 18 | - Shared notepad https://pad.riseup.net/p/peer-to-peer-internet 19 | 20 | You may also want to check out these resources about the Unix Shell: 21 | - Software Carpentry's Introducing the Shell https://swcarpentry.github.io/shell-novice/01-intro/ 22 | - and, Navigating Files and Directories https://swcarpentry.github.io/shell-novice/02-filedir/ 23 | 24 | Getting to the workshop: https://www.torontopubliclibrary.ca/fortyork/ 25 | 26 | We are committed to making sure that the workshop is accessible to everyone. Please tell us if there is anything we should know in advance in order to make the workshop accessible for you. 27 | 28 | Looking forward to seeing you soon! 29 | 30 | Best, 31 | 32 | Toronto Mesh 33 | -------------------------------------------------------------------------------- /install-dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # For rendering course materials to .pdf 4 | npm install -g markdown-pdf 5 | 6 | # For converting Remark presentations to .pdf 7 | npm install -g decktape 8 | 9 | # For generating course website with Jekyll 10 | gem install bundler 11 | -------------------------------------------------------------------------------- /module-1/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "What is mesh?" 4 | module: "1" 5 | contents: 6 | - _articles/module-1/presentation.md 7 | - _articles/module-1/pdf-assets.md 8 | following: _articles/module-1/presentation.md 9 | --- 10 | 11 | # Module 1: What is mesh? 12 | 13 | | **Section** | **Length** | 14 | |------------------------------------------------------------------------------------|------------| 15 | | [**1: Topic introduction**](#1-topic-introduction) | 15 min | 16 | | [**2: Hands-on and material exploration**](#2-hands-on-and-material-exploration) | 40 min | 17 | | [**3: Discussion and reflection activity**](#3-discussion-and-reflection-activity) | 20 min | 18 | | [**4: Wrap-up and week ahead**](#4-wrap-up-and-week-ahead) | 5 min | 19 | | **Workshop length** | 1:30 min | 20 | 21 | ## 1: Topic introduction 22 | 23 | - Introduce yourself, why you are interested in this workshop 24 | - Discuss familiar topics like net neutrality, internet service providers, and internet censorship 25 | - Explain how a mesh topology differs from ISP internet 26 | - Discuss social, political, and technical reasons for a mesh 27 | - Succinct high-level slides on many pieces that will be explored in more detail in upcoming modules: 28 | - Two minutes on historic Toronto networks 29 | - Two minutes on community mesh networks in North America and other parts of the world 30 | - General landscape of technologies like flashing routers with OpenWrt to install mesh routing software 31 | - Set realistic expectations of the state of mesh technology: 32 | - One minute on low-cost computing and hardware capabilities 33 | - One minute on WiFi and directional radios 34 | - State of peer-to-peer applications and how that differs from familiar applications 35 | 36 | ## 2: Hands-on and material exploration 37 | 38 | Trying out peer-to-peer applications running over a decentralized infrastructure. 39 | 40 | ### Objectives 41 | 42 | - Experience local peer-to-peer applications that are relatable to those we are familiar with from the Internet (e.g. Facebook, Dropbox, Whatsapp, Twitter, Spotify) 43 | - "Run your own app" on pre-configured nodes and contrast "serverless" applications on a distributed physical network vs. traditional centralized edge services via ISP networks 44 | - Run [IPFS](https://ipfs.io) on Raspberry Pi 3s and exchange content on an ad-hoc peer-to-peer social network 45 | 46 | ### Materials 47 | 48 | A _Raspberry Pi 3 Kit_ for each student that includes: 49 | 50 | - Raspberry Pi 3 and power supply 51 | - USB WiFi radio that is [ad-hoc or 802.11s-capable](https://github.com/phillymesh/802.11s-adapters) 52 | - SD card with [mesh-workshop](https://github.com/benhylau/mesh-workshop) pre-configured to mesh wirelessly with cjdns and [IPFS docker](https://github.com/vanmesh/p2p-apps-dockers) 53 | - Worksheet printout for each student 54 | 55 | ### Format 56 | 57 | - Groups of 2 58 | 59 | ### Activity 60 | 61 | - Explain distributed web content on a mesh network 62 | - Assign one Raspberry Pi to each student, but keep students in groups of 2 so they can help each other through the worksheet 63 | - Boot all the Raspberry Pi nodes and see that they all wirelessly mesh with one another 64 | - Connect student laptop to each Raspberry Pi's Host AP and initiate a SSH session to `root@.local` (the pre-configured address of the Host AP interface) 65 | - Follow worksheet and share content with each other using IPFS 66 | - Discuss how the systems we just built relate to the content mesh network presented earlier 67 | - Recognize this is a low-level interaction with minimal user interface, but we can build high-level applications based on this content-distributed topology that resemble familiar centralized applications 68 | - Transition to next activity to investigate a centralized application 69 | 70 | ## 3: Discussion and reflection activity 71 | 72 | Reflect on the role of technology in society and power, based on [Explore Community Technology: Investigate Technology](https://communitytechnology.github.io/docs/intro-ct/investigate-tech/). 73 | 74 | Put a list of popular mobile/web applications on the board (e.g. Facebook, Dropbox, Whatsapp, Twitter, Spotify) and pick the one most used by the audience (e.g. put your hand up if you use this daily). Divide the class into five groups, they spend 10 min to dissect this application (questions sourced from _Investigate Technology_ linked above): 75 | 76 | 1. Mission & Ownership 77 | - What is the goal or mission of the technology? 78 | - Who owns the technology? 79 | - Who makes decisions about it? 80 | - How are decisions made? 81 | 82 | 1. Design & Access 83 | - Who designs the technology or system? 84 | - Who is it designed for? 85 | - Who can use the technology? 86 | - Who is left out? 87 | 88 | 1. Community & Local Impact 89 | - Who is strengthened? 90 | - Are local relationships strengthened or weakened? 91 | - Is anyone negatively impacted? 92 | - Is the content made by people in your community? 93 | - Is the content for people in your community? 94 | - How is the local media ecosystem strengthened or weakened? 95 | 96 | 1. Profit & Sustainability 97 | - Who profits from the technology? 98 | - Are the profits or results shared? 99 | - Where does the money go? 100 | - Does that technology generate jobs in your community? 101 | 102 | 1. Teaching & Learning 103 | - How are skills and knowledge shared about the technology? 104 | - Who installs it? 105 | - Who repairs it? 106 | 107 | In the next 10 min, have each group present their findings. As a class, discuss how these answers may differ if the technology is created and maintained by its community of users. 108 | 109 | ## 4: Wrap-up and week ahead 110 | 111 | - Recap that we have: 112 | - Presented the general state of peer-to-peer networks and services 113 | - Experimented with a distributed peer-to-peer application run over off-internet mesh network infrastructure 114 | - Touched upon community models for creating and managing technologies 115 | - Emphasize how distributed systems are less susceptible to some risks that come with centrally governed platforms but also present challenges 116 | - Extrapolate a world where all our day-to-day technologies are run off devices in people's homes 117 | - Next session we will dive into networking on GNU/Linux and explore the layers between the application we used today and the cable or WiFi radio connecting these nodes 118 | 119 | ### Homework 120 | 121 | - [Routing and the Postal System](https://www.youtube.com/watch?v=n7NBgJAhzZ0) from the [Metamesh YouTube channel](https://www.youtube.com/channel/UCGEnntxbGKMU9J9GIZ1LQUQ) 122 | - Compares IP routing to postal delivery system 123 | - Explains acronyms like IP, DHCP, and NAT 124 | - Explains how addresses are distributed and routing in hierarchical ISP networks 125 | - Provides background for future discussions about self-addressing of IPv6 and mesh based "flat" routing 126 | -------------------------------------------------------------------------------- /module-1/handouts/2-peer-to-peer-file-sharing-on-a-mesh.md: -------------------------------------------------------------------------------- 1 | Peer-to-peer file sharing on a mesh 2 | =================================== 3 | 4 | ## Connecting to your Raspberry Pi 5 | 6 | 1. Verify that the Raspberry Pi has its WiFi adapter(s) properly connected and the SD card is in place. Power on the device and wait for a solid green light with a flashing red light. 7 | 8 | 1. Connect your computer's WiFi Client to the Raspberry Pi's WiFi Access Point: 9 | 10 | - SSID: `` 11 | - Password: `password` 12 | 13 | 1. Once your computer is connected to the WiFi Access Point, you can access the Raspberry Pi via a Secure Shell (SSH): 14 | 15 | - Host: `.local` (or `10.0.0.1`) 16 | - Username: `root` 17 | - Password: `root` 18 | 19 | On **macOS or Linux** using **Terminal**, enter `ssh root@example.local` followed by the password `root`. 20 | 21 | On **Windows** using the **PuTTY** graphical interface, enter the `Host` and select `SSH` then click `Open` to initiate an SSH session. Enter the `Username` and `Password` when prompted. 22 | 23 | 1. Find a Raspberry Pi near you and try to ping it to verify that the mesh network interface is working, replacing `example` and `example2` with the `hostname` of your node and the nearby node, respectively: 24 | 25 | **root@example:~#** `ping example2.local` 26 | 27 | Hit `Ctrl + C` to stop the ping. 28 | 29 | You are now a mesh node operator running commands from your pet Raspberry Pi, which is connected to the rest of the mesh network we just formed in this room! For the rest of this activity, we will continue to use `example` to represent your node, and `example2` to represent another node near you. Be sure to replace these with the name of your own pet Raspberry Pi and that of its friend. 30 | 31 | ## Running the InterPlanetary File System (IPFS) 32 | 33 | 1. Start IPFS in the background: 34 | 35 | **root@example:~#** `docker load --input ~/docker/tomeshnet-ipfs-0.1.tar` 36 | **root@example:~#** `docker run --name ipfs --network host --detach tomeshnet/ipfs:0.1` 37 | 38 | With these two commands, we have used a tool called `docker` (which we will not go into detail for now) to load all the files required to run IPFS, then told the Raspberry Pi to run IPFS in the background. You won't see much visual output, but next we will start interacting with this application. 39 | 40 | 1. Initiate an interactive session and write a message to the peer-to-peer filesystem: 41 | 42 | **root@example:~#** `docker exec -it ipfs sh` 43 | **/ #** `echo "Hello World" | ipfs add` 44 | 45 | With the first command, we navigated to an interactive shell with access to the running IPFS application, and the second command added the text `Hello World` to the peer-to-peer filesystem. 46 | 47 | 1. Copy the content address from the `ipfs add` output, which is uniquely derived from your `Hello World` text. To read the content back, use `ipfs cat` followed by pasting the content address you copied: 48 | 49 | **/ #** `ipfs cat QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u` 50 | 51 | 1. Next, you can go to your browser and access the IPFS content you just added! You can use a URL formatted like this to access IPFS content from the browser of your computer: 52 | 53 | `http://.local:8080/ipfs/` 54 | 55 | For example: 56 | 57 | `http://example.local:8080/ipfs/QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u` 58 | 59 | Then you should see `Hello World` in your browser window. This works because each node is running an ipfs-to-http gateway that can be accessed from clients connected to the Access Point of the Raspberry Pi. 60 | 61 | 1. Try to echo other text and read it back in the shell and display it in your browser 62 | 63 | You can actually add any type of file, such as photos and videos, to IPFS, and regardless of the file size you can address (and verify!) them with a short content address like this. So far we have created and fetched content from the IPFS running on our pet Raspberry Pi, but we have not shared any file across the mesh network. Let's do that! 64 | 65 | ## Forming an IPFS content network 66 | 67 | 1. In order to form a network, you need two nodes to know about each other. So let's start with finding your identity in the network and sharing it with another node: 68 | 69 | **/ #** `ipfs id` 70 | 71 | You will see a bunch of lines as output. Note the address that starts with `/ip6/fc` and looks something like this: 72 | 73 | `/ip6/fcb0:3f14:ebc8:1f7b:a1ce:bd44:a410:5049/tcp/4001/ipfs/QmXLWSa1AbLJfivfT9dQJdvs6AsdMkjZjjBMv5SVtimVBq` 74 | 75 | The `/ip6/fc00::/8` is your mesh node's unique IPv6 address (we will cover IPv6 addresses in the next workshop), and the part after `/ipfs/` is your IPFS node ID. You can think of the IPv6 as the street address to your Raspberry Pi, where one will find a live IPFS node, and the IPFS node ID uniquely identifies that IPFS node among all IPFS nodes in the world. Copy this line to a note pad and we will paste it into another node. With these two pieces of information it can both find and identify your IPFS node. 76 | 77 | 1. Type `exit` once to leave the IPFS session for now. Find a nearby node, ask the operator for permission to access their pet Raspberry Pi via SSH and confirm that they already have IPFS running. Now from the session of your Raspberry Pi, initiate an SSH session to the nearby node: 78 | 79 | **root@example:~#** `ssh example2.local` 80 | 81 | 1. Yes we are in two levels of SSH sessions, but that's ok :) Now we initiate an interactive session to IPFS on `example2`, then add your address to tell it about your node: 82 | 83 | **root@example2:~#** `docker exec -it ipfs sh` 84 | **/ #** `ipfs bootstrap add /ip6/fcb0:3f14:ebc8:1f7b:a1ce:bd44:a410:5049/tcp/4001/ipfs/QmXLWSa1AbLJfivfT9dQJdvs6AsdMkjZjjBMv5SVtimVBq` 85 | 86 | Now your nodes are peered to form an IPFS network, which means `example` can access any content in the network accessible to `example2`, and vice versa. It doesn't take many peerings to connect all the nodes in this room. 87 | 88 | 1. Now let's add some content on `example2`, then type `exit` twice to return to `example`, and try to read that text back on `example` and from your browser. It may take a while after you first establish peering, but eventually the content will become available across the network. 89 | 90 | To recap, we started the IPFS application and ipfs-to-http gateway in a docker container running on a Raspberry Pi, then peered two nodes to create an IPFS content-addressing network. Each mesh node is now also an IPFS node that publishes and fetches content within our local mesh network. 91 | 92 | ![Peer-to-peer applications](peer-to-peer-applications.svg) 93 | 94 | Can you identify where the pet Raspberry Pi system you just built fit in the above diagram of a mesh network? 95 | -------------------------------------------------------------------------------- /module-1/handouts/2-sistema-p2p-en-red-mallada_es.md: -------------------------------------------------------------------------------- 1 | Cómo Compartir ficheros p2p sobre una red mesh 2 | =================================== 3 | 4 | Notas de traducción. Los siguientes conceptos no se han traducido para facilitar futuros textos que podrían estar en inglés sobre conceptos muy relevantes: 5 | 6 | - host: la máquina / el equipo 7 | - hostname: nombre de la máquina / el equipo 8 | - mesh: malla, referencia normalmente a red mallada, con las propiedades similares a una malla: redundante (varios caminos) 9 | - gateway: portal; suele ser un intermediario entre dos sistemas, en este caso hace intermediación entre sistema HTTP y IPFS 10 | - file system: sistema de ficheros, supongo que conocerás los famosos FAT32, NTFS. La abreviación FS para filesystem suele aparecer. 11 | - p2p: peer-to-peer, relación entre pares, relación horizontal. Lo contrario es la relación cliente-servidor, relación maestro esclavo. 12 | 13 | ## Conectando a tu Raspberry Pi 14 | 15 | 1. Verifica que la Raspberry Pi tiene correctamente conectado tanto el adaptador(es) wifi como la tarjeta SD. Enciende el dispositivo y espera hasta que aparezca una luz verde constante con una luz roja intermitente. 16 | 17 | 1. Conecta el cliente WiFi de tu ordenador al punto de acceso wifi de la Raspberry Pi: 18 | 19 | - SSID: `` 20 | - Contraseña: `password` 21 | 22 | 1. Una vez conectado al punto de acceso wifi, puedes acceder al Raspberry Pi por SSH: 23 | 24 | - Host: `.local` (or `10.0.0.1`) 25 | - Usuario: `root` 26 | - Contraseña: `root` 27 | 28 | En **macOS o Linux** desde el **Terminal**, pon `ssh root@ejemplo.local` y escribe la contraseña de `root`. 29 | 30 | En **Windows** usando la interfaz gráfica de **PuTTY**, pon el `Host`, elige `SSH` y dale al botón `Open` para abrir una sesión SSH. Pon `Usuario` y `Contraseña` cuando te lo pida. 31 | 32 | 1. Encuentra una Raspberry Pi cerca de ti e intenta hacer un ping para verificar que la interfaz de red mesh está funcionando. Remplaza `ejemplo` y `ejemplo2` con el `hostname` de tu nodo y el nodo más cercano, respectivamente: 33 | 34 | **root@ejemplo:~#** `ping ejemplo2.local` 35 | 36 | Teclea `Ctrl + C` para detener el comando ping. 37 | 38 | Ahora eres un operador de nodo mesh usando los comandos de tu propia Raspberry Pi, que está conectada al resto de la red mesh que hemos creado en esta sala! Para el resto de la actividad continuaremos usando `ejemplo` para representar tu nodo, y `ejemplo2` para representar tu nodo más cercano. Asegúrate de remplazar estos con el nombre de tu propia Raspberry Pi y la de tu vecino. 39 | 40 | ## Arrancar el InterPlanetary File System (IPFS) 41 | 42 | 1. Arranca IPFS en segundo plano: 43 | 44 | **root@ejemplo:~#** `docker load --input ~/docker/tomeshnet-ipfs-0.1.tar` 45 | **root@ejemplo:~#** `docker run --name ipfs --network host --detach tomeshnet/ipfs:0.1` 46 | 47 | Con estos dos comandos, estamos utilizando una herramienta que se llama `docker` (que por ahora no vamos a explicar en detalle) que cargar todos los ficheros necesarios para ejecutar IPFS en segundo plano. No verás casi salida visual, pero empezaremos a interactuar con esta aplicación. 48 | 49 | 1. Inicia una sesión interactiva y escribe un mensaje en el sistema de ficheros p2p: 50 | 51 | **root@ejemplo:~#** `docker exec -it ipfs sh` 52 | **/ #** `echo "Hello World" | ipfs add` 53 | 54 | Con el primer comando, se navega a un intérprete de comandos interactivo con acceso a la aplicación IPFS, y con el segundo comando se añade el texto `Hello World` al sistema de ficheros P2P. 55 | 56 | 1. Copia la dirección del contenido resultante de haber escrito `ipfs add` antes, que ha surgido de una derivación inequívoca del texto anterior `Hello World`. Para leer nuevamente el contenido, usa `ipfs cat` seguido de la dirección del contenido que hayas copiado: 57 | 58 | **/ #** `ipfs cat QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u` 59 | 60 | 1. Ahora puedes acceder al contenido IPFS que acabas de añadir! Puedes usar una URL con el siguiente formato para así poder acceder al contenido desde el navegador web de tu ordenador: 61 | 62 | `http://.local:8080/ipfs/` 63 | 64 | Por ejemplo: 65 | 66 | `http://ejemplo.local:8080/ipfs/QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u` 67 | 68 | Después debes ver `Hello World` en la ventana de tu navegador web. Esto funciona porque cada nodo corre un ipfs-to-http gateway y que puede ser accedido desde el cliente conectado al punto de acceso del Raspberry Pi. 69 | 70 | 1. Intenta enviar otro texto y leerlo tanto desde el intérprete como desde el navegador web. 71 | 72 | En realidad puedes añadir cualquier tipo de fichero a IPFS, como fotos o vídeos, e independientemente del tamaño del fichero puedes darle una dirección (y verificarlo!) con una dirección URL corta como esta. Hasta ahora hemos creado y accedido al contenido de tu Raspberry Pi, pero no hemos compartir contenido en la red mesh. Vamos a ello! 73 | 74 | ## Crear red de contenido IPFS 75 | 76 | 1. Para poder formar una red se necesitan dos nodos que se conozcan entre sí. Entonces empezaremos por encontrar tu identidad en la red y compartirla con otro nodo: 77 | 78 | **/ #** `ipfs id` 79 | 80 | Verás varias lineas de salida. Anota la dirección que empieza con `/ip6/fc` y que es similar a esta: 81 | 82 | `/ip6/fcb0:3f14:ebc8:1f7b:a1ce:bd44:a410:5049/tcp/4001/ipfs/QmXLWSa1AbLJfivfT9dQJdvs6AsdMkjZjjBMv5SVtimVBq` 83 | 84 | La `/ip6/fc00::/8` es la dirección única de IPv6 de tu nodo de la mesh (explicaremos los direcciones IPv6 en el siguiente taller) y la parte de después de `/ipfs/` es el ID de tu nodo de IPFS. Puedes pensar en IPv6 como la dirección postal de tu Raspberry Pi, donde también se encuentra un nodo de IPFS funcionando, y el ID del nodo IPFS identifica inequívocamente este nodo IPFS del resto de nodos IPFS en el mundo. Copia esta línea en un bloc de notas y pégala en otro nodo. Con estos datos podemos encontrar e identificar tu nodo de IPFS. 85 | 86 | 1. Escribe `exit` una vez para salir de la sesión IPFS por ahora. Encuentra un nodo cerca de ti, pide permiso al operador de su mascota-RaspberryPi para acceder a su nodo via SSH y confirma así que ya tienen el IPFS en marcha. Ahora desde la sesión de tu Raspberry Pi, inicia una sesión SSH hacia el nodo vecino: 87 | 88 | **root@ejemplo:~#** `ssh ejemplo2.local` 89 | 90 | 1. Sí, estamos en dos capas de SSH, pero está bien :) Ahora iniciaremos una sesión interactiva de IPFS en `ejemplo2`, después añade tu dirección para informarle de tu nodo: 91 | 92 | **root@ejemplo2:~#** `docker exec -it ipfs sh` 93 | **/ #** `ipfs bootstrap add /ip6/fcb0:3f14:ebc8:1f7b:a1ce:bd44:a410:5049/tcp/4001/ipfs/QmXLWSa1AbLJfivfT9dQJdvs6AsdMkjZjjBMv5SVtimVBq` 94 | 95 | Ahora los nodos están emparejados para formar una red IPFS, que significa que `ejemplo` puede acceder a todo el contenido en la red accesible a `ejemplo2`, y viceversa. No van a hacer falta muchos más emparejamientos para acabar conectando todos los nodos de esta sala. 96 | 97 | 1. Ahora vamos a añadir algo de contenido sobre `ejemplo2`, y después escribimos `exit` dos veces para poder volver a `ejemplo`, y vamos a tratar de leer el texto desde tu navegador web. Este proceso puede tardar un rato desde que hayas establecido el emparejamiento por primera vez, pero eventualmente el contenido estará accesible por toda la red. 98 | 99 | En resumen, se ejecuta la aplicación IPFS y el portal *ipfs-to-http gateway* en un contenedor de docker que está en una Raspberry Pi, luego se empareja con dos nodos para crear una red de contenido accesible con IPFS. Cada nodo de la mesh también es un nodo IPFS que publica y obtiene contenido dentro de nuestra red mesh local. 100 | 101 | ![Peer-to-peer applications](peer-to-peer-applications.svg) 102 | 103 | Puedes identificar dónde está la mascota-RaspberryPi que acabas de construir en el diagrama de arriba? 104 | -------------------------------------------------------------------------------- /module-1/handouts/3-community-local-impact.md: -------------------------------------------------------------------------------- 1 | Community & Local Impact 2 | ======================== 3 | 4 | **Application:** `________________` 5 | 6 | Who is strengthened? 7 | 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | ``` 15 | 16 | Are local relationships strengthened or weakened? 17 | 18 | ``` 19 | 20 | 21 | 22 | 23 | 24 | ``` 25 | 26 | Is anyone negatively impacted? 27 | 28 | ``` 29 | 30 | 31 | 32 | 33 | 34 | ``` 35 | 36 | Is the content made by people in your community? 37 | 38 | ``` 39 | 40 | 41 | 42 | 43 | 44 | ``` 45 | 46 | Is the content for people in your community? 47 | 48 | ``` 49 | 50 | 51 | 52 | 53 | 54 | ``` 55 | 56 | How is the local media ecosystem strengthened or weakened? 57 | 58 | ``` 59 | 60 | 61 | 62 | 63 | 64 | ``` 65 | -------------------------------------------------------------------------------- /module-1/handouts/3-design-access.md: -------------------------------------------------------------------------------- 1 | Design & Access 2 | =============== 3 | 4 | **Application:** `________________` 5 | 6 | Who designs the technology or system? 7 | 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ``` 18 | 19 | Who is it designed for? 20 | 21 | ``` 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ``` 31 | 32 | Who can use the technology? 33 | 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ``` 44 | 45 | Who is left out? 46 | 47 | ``` 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /module-1/handouts/3-mission-ownership.md: -------------------------------------------------------------------------------- 1 | Mission & Ownership 2 | =================== 3 | 4 | **Application:** `________________` 5 | 6 | What is the goal or mission of the technology? 7 | 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ``` 18 | 19 | Who owns the technology? 20 | 21 | ``` 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ``` 31 | 32 | Who makes decisions about it? 33 | 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ``` 44 | 45 | How are decisions made? 46 | 47 | ``` 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /module-1/handouts/3-profit-sustainability.md: -------------------------------------------------------------------------------- 1 | Profit & Sustainability 2 | ======================= 3 | 4 | **Application:** `________________` 5 | 6 | Who profits from the technology? 7 | 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ``` 18 | 19 | Are the profits or results shared? 20 | 21 | ``` 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ``` 31 | 32 | Where does the money go? 33 | 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ``` 44 | 45 | Does that technology generate jobs in your community? 46 | 47 | ``` 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /module-1/handouts/3-teaching-learning.md: -------------------------------------------------------------------------------- 1 | Teaching & Learning 2 | =================== 3 | 4 | **Application:** `________________` 5 | 6 | How are skills and knowledge shared about the technology? 7 | 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ``` 18 | 19 | Who installs it? 20 | 21 | ``` 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ``` 31 | 32 | Who repairs it? 33 | 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ``` 44 | 45 | -------------------------------------------------------------------------------- /module-1/handouts/peer-to-peer-applications.svg: -------------------------------------------------------------------------------- 1 | Illustrations -------------------------------------------------------------------------------- /module-1/presentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Module One 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 148 | 149 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /module-1/slide-images/home-internet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | workshop-illustrations 11 | 12 | 16 | 17 | 24 | 27 | 29 | 31 | 33 | 35 | 37 | 39 | 40 | 47 | 49 | 51 | 53 | 54 | 56 | 59 | 61 | 63 | 66 | 70 | 73 | 76 | 78 | 80 | 83 | 85 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /module-2/handouts/2-your-node-in-a-mesh-network.md: -------------------------------------------------------------------------------- 1 | Your node in a mesh network 2 | =========================== 3 | 4 | ## Connecting to your Raspberry Pi 5 | 6 | 1. Verify that the Raspberry Pi has the SD card in place. Power on the device and wait for a solid green light with a flashing red light. 7 | 8 | 1. Connect your computer's WiFi Client to the Raspberry Pi's WiFi Access Point: 9 | 10 | - SSID: `` 11 | - Password: `password` 12 | 13 | 1. Once your computer is connected to the WiFi Access Point, you can access the Raspberry Pi via a Secure Shell (SSH): 14 | 15 | - Host: `.local` (or `10.0.0.1`) 16 | - Username: `root` 17 | - Password: `root` 18 | 19 | On **macOS or Linux** using **Terminal**, enter `ssh root@example.local` followed by the password `root`. 20 | 21 | On **Windows** using the **PuTTY** graphical interface, enter the `Host` and select `SSH` then click `Open` to initiate an SSH session. Enter the `Username` and `Password` when prompted. 22 | 23 | You are now connected to and able to run commands from your Raspberry Pi, but unlike last week, your Raspberry Pi is currently not connected to all the other ones in the room. Find a partner and we will manually get the two Raspberry Pis to talk over an ethernet cable. For the rest of this activity, we will use `example` to represent one node, and `example2` to represent the other. 24 | 25 | ## Making a wired ethernet link 26 | 27 | 1. The Raspberry Pi has one single ethernet port for wired networking. In the operating system, it is represented by `eth0`. Look at the `eth0` ethernet interface using: 28 | 29 | **root@example:~#** `networkctl status eth0` 30 | 31 | You should see `State: no-carrier (configuring)`. This is because the ethernet port is not connected to anything. We need to build a road between the two Raspberry Pis. 32 | 33 | 1. Connect the two nodes with an ethernet cable, then run the same command again. You will find that the state has changed to `State: degraded (configuring)`. Even though we have a road (i.e. ethernet cable), there is no street addresses (i.e. IP addresses) or road signs for directions (i.e. routes). 34 | 35 | 1. We will now assign IP addresses to the `eth0` interface on the two nodes. It is important that they have different addresses for the same reason two houses should not have the same street address. Let us assign `192.168.0.1` to `example`, and `192.168.0.2` to `example2`: 36 | 37 | **root@example:~#** `ip addr add 192.168.0.1/24 dev eth0` 38 | 39 | **root@example2:~#** `ip addr add 192.168.0.2/24 dev eth0` 40 | 41 | We are assigning the IP address `192.168.0.1` to the ethernet interface of `example`, and the `/24` tells the device to route all IP traffic to and from `192.168.0.X` addresses through the `eth0` interface with that IP address. On `example2`, the command does the same thing except the traffic is routed through its `eth0` interface with IP address `192.168.0.2`. 42 | 43 | 1. Check the status of `eth0` again and you should find that its state has changed to `State: routable (configuring)` and its newly assigned IP address will also be printed. 44 | 45 | 1. Check the route to ensure the road signs are properly registered: 46 | 47 | **root@example:~#** `ip route` 48 | 49 | One of the lines in the output should look like `192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.1`, which means IP traffic to and from `192.168.0.X` addresses will be routed through the `eth0` network interface with the IP address `192.168.0.1`. There are other network interfaces on your Raspberry Pi, such as the one wirelessly connecting your computer. You can see them all by running: 50 | 51 | **root@example:~#** `networkctl status` 52 | 53 | 1. Now let's try to ping each other over this new pathway you just built! 54 | 55 | **root@example:~#** `ping 192.168.0.2` 56 | 57 | Or, using mDNS: 58 | 59 | **root@example:~#** `ping example2.local` 60 | 61 | Hit `Ctrl + C` to stop the ping. 62 | 63 | We have confirmed the two Raspberry Pis can reach each other. Let's try to send human-readable messages over that wire. 64 | 65 | ## Communicating over the wire 66 | 67 | 1. We will use the tool netcat to send plaintext messages to one another. On `example`, start listening on port 80: 68 | 69 | **root@example:~#** `nc -l -p 80` 70 | 71 | Then, connect to it from `example2` and start typing messages: 72 | 73 | **root@example2:~#** `nc example.local 80` 74 | **root@example2:~#** `Hello can you hear me?` 75 | 76 | Hit `Ctrl + C` to stop netcat. 77 | 78 | 1. Instead of writing each other in human-readable plaintext, we can send other messages over the wire, such as a language your web browser understands, called the Hypertext Transfer Protocol (HTTP). On `example`, we will run a minimal webserver that can respond to HTTP messages. Look at the script `start-webserver.sh` and run it: 79 | 80 | **root@example:~#** `cat ~/scripts/start-webserver.sh` 81 | **root@example:~#** `sh ~/scripts/start-webserver.sh` 82 | 83 | From `example2`, send a HTTP request to it: 84 | 85 | **root@example2:~#** `curl example.local` 86 | 87 | Observe the response from the webserver. When you are ready to move on, hit `Ctrl + C` to stop the server. 88 | 89 | Our applications talk in many protocols, such as HTTP and SSH (how you are connected to the Raspberry Pi), but they all run on top of IP infrastructure. This means when we build a mesh network, we just need to ensure it talks the Internet Protocol, as we have just done, and all applications will run on the mesh network without modifications. Now we know our Netflix and YouTube will (theoretically) work seamlessly over a mesh network, let's try to extend our two-node IP network to include one more node :) 90 | -------------------------------------------------------------------------------- /module-2/handouts/3-cards-of-tlds.md: -------------------------------------------------------------------------------- 1 | # `vb.ly` 2 | 3 | Violet Blue's "sex-positive URL shortener" vb.ly was deleted by the .ly domain registry in 2010 allegedly for not adhering to regulations for the TLD related to "text referring to adult content and offensive imagery." Basically, pornography is illegal under Libyan law (which is not to say Sharia law, these are different) and although vb.ly was operating outside of Libya, it was still expected to adhere to Libyan law. Later that same year, access to less than four-letter .ly domains became restricted to Libyan residents. 4 | 5 | **Scenario: Contentious Use of Your TLD** 6 | 7 | This is a scenario in which someone outside of a player's country uses their TLD in a way that doesn't necessarily reflect the country's political or cultural experiences, and the player has to decide whether to allow that use of their TLD or intervene, potentially damaging their TLD's reputation and position on the political stage or damaging their reputation in their country as a political leader. 8 | 9 | --- 10 | 11 | # `.ly` 12 | 13 | Libya's two governments, as well as other splinter groups, are competing over the ability to communicate officially via the internet, and in places it comes down simply to who holds the login details: "the government domains are distributed between the two parties and it depends on who has the password which allows them to change the details of the domain. 14 | 15 | **Scenario: Political Unrest** 16 | 17 | While similar to the government collapse scenario, this more typically refers to chaos within a government more like a revolution or coup than confluence of several factions dissolving the nation. Players can choose a few scenarios to resolve or not resolve their conflict. 18 | 19 | --- 20 | 21 | # `.tv` 22 | 23 | The domain is currently operated by dotTV, a Verisign company; the Tuvalu government owns twenty percent of the company. In 1999, Tuvalu negotiated a contract leasing its Internet domain name ".tv" to a company formed by idealab for $50 million in royalties over a 12-year period. The Tuvalu government receives a quarterly payment of US$1 million for use of the top-level domain. With the first $1 million payment the government received, Tuvalu was finally able to afford the $100,000 it cost to join the United Nations. Lou Kerner joined .tv as its CEO in January 2000, and the company began selling .tv domain names in April 2000. Verisign acquired .tv in December 2001. 24 | 25 | **Scenario: Middleman Offer** 26 | 27 | In this scenario, a ccTLD hands over maintenance and management of their TLD to a third-party operator. They can choose to do this for lots of reasons, though the most common reason is that the country itself lacks the IT infrastructure to actually run a domain registry and needs assistance promoting the TLD. However, this choice comes with caveats–technically the players only receive a percentage of profits from the TLD. 28 | 29 | --- 30 | 31 | # `.yu` 32 | 33 | Computer Scientists at the Jožef Stefan Institute in Slovenia, then part of the Socialist Federal Republic of Yugoslavia, registered the .yu domain in 1987. 34 | 35 | When SFR Yugoslavia dissolved during the Yugoslav Wars beginning in 1991, the republic broke up into several smaller countries. Slovenia and Croatia quickly registered their own TLDs (.si and .hr, respectively, registered in 1993) but through a weird game of governance hot-potato the new Slovenian government now controlled the .yu TLD. and IANA facilitated the transfer fo the TLD from Slovenian hands to the Federal Republic of Yugoslavia via an association at the University of Belgrade. 36 | 37 | In 2003, the FR Yugoslavia became Serbia and Montenegro, and the .cs ccTLD was registered for the newly named country. However, it didn't really end up going into use. .yu ended up lingering for a while, basically being the only ccTLD that wasn't based on an ISO code. In a way, it kind of didn't make a huge difference since the Serbia and Montenegro split apart in 2006, which led to the creation of the .rs and .me TLDs. In 2007, ICANN handed control of .yu to the Serbian National Register of Internet Domain Names, with the intent of slowly phasing the TLD out and letting the domain expire, which it ultimately did in 2010. 38 | 39 | **Scenario: Government Collapse!** 40 | 41 | This is a scenario in which political unrest within your country leads to your country being divided into multiple independent states, leading your current TLD being retired and new rules being established. 42 | 43 | --- 44 | 45 | # `.io` 46 | 47 | .io is one of the fastest-growing top-level domains on the internet, a particular favourite among start-ups and technology companies. It refers to the British Indian Ocean Territory, a remote but strategically-important scattering of islands in the middle of the Indian Ocean, also known as the Chagos Archipelago. It consists of seven atolls and over 1,000 tiny islands. 48 | 49 | All Chagossians were driven off the island starting around 1967, when Mauritius was declared independent from the British government and the islands were annexed from Mauritius, and they have not and probably will not ever be allowed to go home. The archipelago's largest island is currently home to a U.S. military base, which has played a pretty cool role in propagating the war on terror. 50 | 51 | All this to say, when ccTLDs were being registered Chagossians weren't exactly prepared for it, which is where Paul Kane and the Internet Computer Bureau come in. Kane registered the TLD way back in 1997, and is just now reaping the benefits of the .io TLD. The ICB also manages 2 other British territory TLDs, .ac (Ascenion Islands) and .sh (St. Helena). Kane has previously stated with regard to the TLDs that "Each of the overseas territories has an account and the funds are deposited there because obviously the territories have expenses that they incur and it's offsetting that." Whether that's actually true or whether the account Kane describes actually goes to a representative of the Chagossian people is entirely unclear. 52 | 53 | **Scenario: Middleman Offer** 54 | 55 | A few ccTLDs are managed by middlemen not necessarily by choice or in the service of financial gain or support. Some countries' TLDs were registered early in the TLD creation process, and representatives from that country weren't necessarily able to actually engage in the process. 56 | 57 | --- 58 | 59 | # `.cat` 60 | 61 | Created in 2005 after extensive lobbying, payment, and the pursuit of letters of support from the Spanish and French governments, this TLD is dedicated to the promotion of Catalonian culture and identity. While it has the potential to be an incredibly lucrative TLD given all the domain hacks that can be applied to it, the requirement that .cat sites promote the Catalonian language in some respect has somewhat limited its expansion. 62 | 63 | **Scenario: Endorsement Letters** 64 | 65 | For a non-recognized nation-state or cultural entity to receive a TLD, they have to do a bunch of things. One of those things is submit letters of support from government and cultural bodies, as well as businesses and individuals with a connection to the region or entity seeking a domain. 66 | 67 | --- 68 | 69 | # `.sucks` 70 | 71 | The Canadian company Momentous acquired the .sucks TLD in 2014 after a private auction between the company and fellow gTLD purveyor Donuts. It's been mired by concerns over defamation and intellectual property for reasons that are probably pretty self-evident (also, Saudi Arabia's Communications and Information Technology Commission filed an objection to the TLD because of the possibility it might be used for pornographic sites, shruggie). 72 | 73 | Momentous, through their subsidiary Vox Populi, in some ways is kind of just running an extortion scheme through this TLD. During the "sunrise" registration period for the TLD they set up a "Trademark Clearinghouse" as a mechanism for allowing corporations to register a .sucks domains in advance–at the price of about $2500 a domain. (Stories about this TLD like to note how Taylor Swift has already acquired taylorswift.sucks, which like, of course she has.) 74 | 75 | **Scenario: Contentious Use of Your TLD** 76 | 77 | Similar to the ccTLD scenario, but generally the politics have less to do with cultural identities and more to do with money and power. 78 | -------------------------------------------------------------------------------- /module-2/slide-images/three-node-mesh-network.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | workshop-illustrations 11 | 15 | 16 | 19 | 23 | 24 | 27 | 29 | 31 | 34 | 36 | 38 | 41 | 43 | 44 | 46 | 49 | 50 | 53 | 56 | 59 | 61 | 63 | 65 | 68 | 70 | 72 | 75 | 77 | 78 | -------------------------------------------------------------------------------- /module-3/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Building nodes (hardware)" 4 | module: "3" 5 | contents: 6 | - _articles/module-3/presentation.md 7 | - _articles/module-3/pdf-assets.md 8 | following: _articles/module-3/presentation.md 9 | --- 10 | 11 | # Module 3: Building nodes (hardware) 12 | 13 | | **Section** | **Length** | 14 | |------------------------------------------------------------------------------------|------------| 15 | | [**1: Topic introduction**](#1-topic-introduction) | 15 min | 16 | | [**2: Hands-on and material exploration**](#2-hands-on-and-material-exploration) | 40 min | 17 | | [**3: Discussion and reflection activity**](#3-discussion-and-reflection-activity) | 20 min | 18 | | [**4: Wrap-up and week ahead**](#4-wrap-up-and-week-ahead) | 5 min | 19 | | **Workshop length** | 1:30 min | 20 | 21 | ## 1: Topic introduction 22 | 23 | - Break apart the mesh node into its base modules and brief overview of each module's role: 24 | - Single board computer 25 | - Storage (SD card) and software (OS) 26 | - Power supply 27 | - Radio (onboard and external) 28 | - Antennas 29 | - Review Homework from Module 2 (radio waves) 30 | - Introduce WiFi concepts as they relate to configuring the radio (frequencies, bands, bandwidth (40 MHz vs 20 MHz), SSID, etc) 31 | - Touch upon licensed and unlicensed frequencies (900Mhz, 2.4Ghz, 5Ghz), how they change from jurisdiction to jurisdiction, and the CRTC as the governing body in Canada. 32 | 33 | ## 2: Hands-on and material exploration 34 | 35 | Group activity to wirelessly mesh with other groups by configuring Raspberry Pis. 36 | 37 | ### Objectives 38 | 39 | - Learn to establish wireless links between nodes and manipulate the nodes' radio properties 40 | - Understand the role that frequency, bands, bandwidth and SSIDs play in a wireless mesh 41 | - Allow opportunity for students to tinker with the radios and create a mesh 42 | - Discover first hand real-world problems with growing the mesh 43 | 44 | ### Materials 45 | 46 | - A Raspberry Pi 3 for each member labeled with the SSID for the node 47 | - SD cards with pre-flashed images with all required software 48 | - Laptops that can establish a SSH session to each Raspberry Pi (each running a Host AP with unique SSID) 49 | - USB WiFi radio that is [ad-hoc or 802.11s-capable](https://github.com/phillymesh/802.11s-adapters) for each Raspberry Pi 3 50 | 51 | ### Format 52 | 53 | - Pairs to start, then work toward establishing a class-wide mesh 54 | 55 | ### Activity 56 | 57 | - As a class review the purpose of each command in a sample starter script: 58 | ``` 59 | ip link set dev wlanX down 60 | iw wlanX set type mp 61 | ip link set dev wlanX up 62 | iw dev wlanX mesh join MY_MESH_NAME freq 2412 63 | ip addr add 192.168.0.Y/24 dev wlanX 64 | ``` 65 | - Break into groups of two 66 | - Each group needs a pair of Raspberry Pis 67 | - Each group will connect to their Raspberry Pi's Host AP and initiate a SSH session 68 | - Use ifconfig to identify which wlan interface is which (Hint: look for 10.0.0.1) 69 | - Use ifconfig and iw to create a mesh between the nodes with this sample starter script 70 | - Use `iw wlanX station dump` to see if connections are established 71 | - Use `iperf3 -s` on one node and `iperf3 -c 192.168.0.Y` on another node to test the speed across the link 72 | - Once the nodes are properly meshed, have groups seek out another group that has finished 73 | - Work together to integrate all 4 nodes into one mesh 74 | - Encourage group to continue to merge meshes until all the groups are meshed into one 75 | - End the group stage by discussing 76 | - Did you seek help with another group to mesh your first two nodes? 77 | - What where the barriers of connecting to another group? 78 | - How did you come to a consensus of mesh method, frequency, SSID, ip address schema? Build upon discussion in Module 2 79 | - Was it easier or harder to connect as the mesh got bigger? 80 | - Did we manage to mesh the whole class? Why, Why not? 81 | - Parallel the experience with the real world 82 | - Mesh locals working together 83 | - Coming to a consensus working in larger groups 84 | 85 | ## 3: Discussion and reflection activity 86 | 87 | Q & A discussion around the different hardware we employ to build a network. 88 | 89 | * Discuss alternative components that could be used in a node for different applications and environments 90 | * SBC (Orange Pi Zero, Rock64, ExpressoBin, Raspberry Pi, etc.) 91 | * Price point 92 | * Processing power 93 | * Power consumption 94 | * Features (10/100 Ethernet, mPci-e, USB ports, etc.) 95 | * Power Supply (wall wart, POE, battery, solar panel, lamp post) 96 | * Storage and OS (OpenWrt/Lede, LibreMesh) 97 | * Radios 98 | * 2.4 Ghz vs 5 Ghz 99 | * Ubiquiti proprietary protocols meshed over Ethernet 100 | 101 | ## 4: Wrap-up and week ahead 102 | 103 | - Next session we will discuss important factors to consider for deployment and use a mapping activity of the nearby area for planning 104 | 105 | ### Homework 106 | 107 | - Watch Meta Mesh [quick tour of a mesh networking installation](https://www.youtube.com/watch?v=aLusYsScrv0): [https://www.youtube.com/watch?v=aLusYsScrv0](https://www.youtube.com/watch?v=aLusYsScrv0) (4:03) 108 | - Optionally read "[Wireless Networking in the Developing World, Chapter 10: Deployment Planning](http://wndw.net/pdf/wndw3-en/ch10-deployment-planning.pdf)": [http://wndw.net/pdf/wndw3-en/ch10-deployment-planning.pdf](http://wndw.net/pdf/wndw3-en/ch10-deployment-planning.pdf) 109 | - Optionally watch 110 | - SmartrekTech [How to install a Smartrek wireless mesh network for sugar making purposes](https://www.youtube.com/watch?v=eKkVEeVNhm8 ): [https://www.youtube.com/watch?v=eKkVEeVNhm8](https://www.youtube.com/watch?v=eKkVEeVNhm8) (4:31) 111 | - [Rural Next Generation Broadband Project](https://www.youtube.com/watch?v=QM7MUWDcNxk): [https://www.youtube.com/watch?v=QM7MUWDcNxk](https://www.youtube.com/watch?v=QM7MUWDcNxk) (6:12) 112 | -------------------------------------------------------------------------------- /module-3/handouts/2-configuration-cards.md: -------------------------------------------------------------------------------- 1 | ``` 2 | ip link set dev wlanX down 3 | iw wlanX set type mp 4 | ip link set dev wlanX up 5 | iw dev wlanX mesh join MY_MESH_NAME freq 2412 6 | ip addr add 192.168.0.Y/24 dev wlanX 7 | ``` 8 | 9 | --- 10 | 11 | ``` 12 | ip link set dev wlanX down 13 | iw wlanX set type mp 14 | ip link set dev wlanX up 15 | iw dev wlanX mesh join MY_MESH_NAME freq 5240 16 | ip addr add 192.168.0.Y/24 dev wlanX 17 | ``` 18 | 19 | --- 20 | 21 | ``` 22 | ip link set dev wlanX down 23 | iw wlanX set type mp 24 | ip link set dev wlanX up 25 | iw dev wlanX mesh join MY_MESH_NAME freq 2437 26 | ip addr add 192.168.0.Y/24 dev wlanX 27 | ``` 28 | 29 | --- 30 | 31 | ``` 32 | ip link set dev wlanX down 33 | iw wlanX set type ibss 34 | ip link set dev wlanX up 35 | iw dev wlanX ibss join MY_MESH_NAME 2437 36 | ip addr add 192.168.0.Y/24 dev wlanX 37 | ``` 38 | 39 | --- 40 | 41 | ``` 42 | ip link set dev wlanX down 43 | iw wlanX set type ibss 44 | ip link set dev wlanX up 45 | iw dev wlanX ibss join MY_MESH_NAME 5745 46 | ip addr add 192.168.0.Y/24 dev wlanX 47 | ``` 48 | 49 | --- 50 | 51 | ``` 52 | ip link set dev wlanX down 53 | iw wlanX set type ibss 54 | ip link set dev wlanX up 55 | iw dev wlanX ibss join MY_MESH_NAME 5180 56 | ip addr add 192.168.0.Y/24 dev wlanX 57 | ``` 58 | -------------------------------------------------------------------------------- /module-3/handouts/2-mesh-your-node-wirelessly.md: -------------------------------------------------------------------------------- 1 | Mesh your node wirelessly 2 | =========================== 3 | 4 | ## Connecting to your Raspberry Pi 5 | 6 | 1. Verify that the Raspberry Pi has the SD card in place. Power on the device and wait for a solid green light with a flashing red light. 7 | 8 | 1. Connect your computer's WiFi Client to the Raspberry Pi's WiFi Access Point: 9 | 10 | - SSID: `` 11 | - Password: `password` 12 | 13 | 1. Once your computer is connected to the WiFi Access Point, you can access the Raspberry Pi via a Secure Shell (SSH): 14 | 15 | - Host: `.local` (or `10.0.0.1`) 16 | - Username: `root` 17 | - Password: `root` 18 | 19 | On **macOS or Linux** using **Terminal**, enter `ssh root@example.local` followed by the password `root`. 20 | 21 | On **Windows** using the **PuTTY** graphical interface, enter the `Host` and select `SSH` then click `Open` to initiate an SSH session. Enter the `Username` and `Password` when prompted. 22 | 23 | You are now connected to and able to run commands from your Raspberry Pi. The Raspberry Pis are currently not connected to all the other ones in the room. Find a partner and we will manually get the two Raspberry Pis to talk over a wireless mesh with a series of commands provided. For the rest of this activity, we will use `example` to represent your node. 24 | 25 | ## Finding your mesh interface 26 | 27 | 1. The Raspberry Pi may prepare network interfaces out of order. To make sure we do not accidentally change the settings on the interface running the Access Point (and disconnect us from the Pi) we will first confirm the interface names: 28 | 29 | **root@example:~#** `iw dev` 30 | 31 | You should see one of the interfaces with `type: AP`. This is the Access Point that your computer uses to connect to the node wirelessly. 32 | 33 | 1. Make note of the interface that is _not_ your `AP`. It will most likely be `wlan1`. 34 | 35 | ## Creating your mesh network 36 | 37 | 1. Partner up with someone at the table to form a new mesh group. 38 | 39 | 1. Decide on a name for your newly formed mesh. Keep it simple and a single word. Don't spend too much time on this. 40 | 41 | 1. Use the commands provided to create a mesh network between the two nodes, with the following substitutions: 42 | 43 | * Make sure you use the correct `wlanX` network interface that you noted above. 44 | * Replace `MY_MESH_NAME` with the mesh name you decided on. 45 | * Assign each node a different IP address. For example, `192.168.0.1` for the first and `192.168.0.2` for the second. 46 | 47 | ## Testing your mesh network 48 | 49 | 1. Use `ping` to ping the other connected node and see if it responds. 50 | 51 | 1. You can check to see what nodes are connected by doing a station dump: 52 | 53 | **root@example:~#** `iw wlanX station dump` 54 | 55 | ## Growing your mesh network 56 | 57 | 1. Now that you have successfully created your small mesh network, find another group in your proximity. 58 | 59 | 1. Expand your mesh to include the new group. 60 | 61 | 1. Now repeat it with another group. 62 | -------------------------------------------------------------------------------- /module-3/presentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Module Three 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 263 | 264 | 281 | 282 | 283 | -------------------------------------------------------------------------------- /module-3/slide-images/antenna.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | Antenna1 10 | 11 | 12 | 13 | 16 | 19 | 21 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /module-3/slide-images/power-supply.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | Power Supply1 10 | 11 | 12 | 13 | 16 | 18 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /module-3/slide-images/radio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | Radio1 11 | 12 | 13 | 14 | 15 | 17 | 19 | 22 | 23 | 24 | 26 | 31 | 34 | 38 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /module-3/slide-images/single-board-computer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | Single Board Computer1 10 | 11 | 12 | 13 | 15 | 17 | 19 | 21 | 23 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /module-3/slide-images/storage.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | Storage1 10 | 11 | 12 | 13 | 20 | 24 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /module-4/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Planning a network" 4 | module: "4" 5 | contents: 6 | - _articles/module-4/presentation.md 7 | - _articles/module-4/pdf-assets.md 8 | following: _articles/module-4/presentation.md 9 | --- 10 | 11 | # Module 4: Planning a network 12 | 13 | | **Section** | **Length** | 14 | |------------------------------------------------------------------------------------------------------|------------| 15 | | [**1: Topic - Network Deployment Planning**](#1-topic---network-deployment-planning) | 15 min | 16 | | [**2: Hands-on - Mapping the Fort York Micro Mesh**](#2-hands-on---mapping-the-fort-york-micro-mesh) | 40 min | 17 | | [**3: Discussion and reflection activity**](#3-discussion-and-reflection-activity) | 20 min | 18 | | [**4: Wrap-up and week ahead**](#4-wrap-up-and-week-ahead) | 5 min | 19 | | **Workshop length** | 1:30 min | 20 | 21 | ## 1: Topic - Network Deployment Planning 22 | 23 | ### Objectives 24 | 25 | - List features of a wifi or mesh deployment 26 | - Explain and summarize important factors to consider for deployment 27 | 28 | ### Materials 29 | 30 | - Class Presentation 31 | - Class Shared Notes (i.e., using Riseup Pad or something similar) 32 | 33 | ### Activity 34 | 35 | - Presentation on Deployment (8 min) 36 | - Planning Considerations Activity (8 min) 37 | 1. Split into groups/pairs 38 | 1. Assign each group a case from [WNDW](http://wndw.net/caseStudies.html) (5 exist) 39 | 1. Ask the groups to read through the cases, identify aspects to keep in mind when planning and present a summary to the group of what they anticipate 40 | 1. Collect responses on in class shared notes and discuss 41 | 42 | ## 2: Hands-on - Mapping the Fort York Micro Mesh 43 | 44 | ### Objectives 45 | 46 | - Sketch out and prototype an imagined Fort York Micro Mesh 47 | 48 | ### Materials 49 | 50 | - Printed map (previous class confirm location. Ask if people live nearby, < 10min walk) and would be up for using their home) 51 | - Google Earth 52 | - Hardware examples 53 | 54 | ### Activity 55 | 56 | - Introduce Group Mapping Exercise 57 | - Based on [Commotion Construction Kit](https://commotionwireless.net/docs/cck/): "[Every Network Tells a Story](https://commotionwireless.net/docs/cck/planning/design-your-network-every-network-tells-story/)" 58 | - Describe Routers and Rules 59 | - Group Mapping 60 | - Discussion, Show & Tell 61 | 62 | ## 3: Discussion and reflection activity 63 | 64 | - Ask group to review planning considerations in light of the mapping activity 65 | - Have someone as note-taker update the original list 66 | - Review the 3 other planning activities in the [Commotion Construction Kit](https://commotionwireless.net/docs/cck/): 67 | - [Survey your Neighbors](https://commotionwireless.net/docs/cck/planning/survey-your-neighbors/) 68 | - [Identify Neighbourhood Skills](https://commotionwireless.net/docs/cck/planning/identify-neighborhood-skills/) 69 | - [Inventory your Neighbourhood](https://commotionwireless.net/docs/cck/planning/inventory-the-neighborhood/) 70 | - With remaining time, jointly brainstorm an Outreach Strategy for Toronto Mesh, starting in their neighbourhood 71 | - Have someone as note-taker add to class shared notes 72 | 73 | ## 4: Wrap-up and week ahead 74 | 75 | - Next session we will talk about Net Neutrality and _why_ and _how_ to "keep the pulse of a network" 76 | 77 | ### Homework 78 | 79 | - Watch [Net Neutrality - 6 Minute Explanation](https://www.youtube.com/watch?v=zASHI9qdB0U) by drawntoknowledge _(NOTE: This video incorrectly labeled ISPs as Tier 1 providers, however this does not impact the video's message)_ 80 | - Watch selection of ["The Internet We Want" Panel starting @ 27:00](https://youtu.be/PtO4rPPBWjY?t=27m00s) 81 | - Optional: Read "[A plan to rescue the Web from the Internet](https://staltz.com/a-plan-to-rescue-the-web-from-the-internet.html)" by Andrew Staltz 82 | -------------------------------------------------------------------------------- /module-4/handouts/ft-york.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/module-4/handouts/ft-york.pdf -------------------------------------------------------------------------------- /module-4/presentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Module Four 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 114 | 115 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /module-5/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Measuring networks" 4 | module: "5" 5 | contents: 6 | - _articles/module-5/presentation.md 7 | - _articles/module-5/pdf-assets.md 8 | following: _articles/module-5/presentation.md 9 | --- 10 | 11 | # Module 5: Measuring networks 12 | 13 | | **Section** | **Length** | 14 | |------------------------------------------------------------------------------------|------------| 15 | | [**1: Topic introduction**](#1-topic-introduction) | 15 min | 16 | | [**2: Hands-on and material exploration**](#2-hands-on-and-material-exploration) | 40 min | 17 | | [**3: Discussion and reflection activity**](#3-discussion-and-reflection-activity) | 20 min | 18 | | [**4: Wrap-up and week ahead**](#4-wrap-up-and-week-ahead) | 5 min | 19 | | **Workshop length** | 1:30 min | 20 | 21 | ## 1: Topic introduction 22 | 23 | - Review of homework on Net Neutrality: 24 | - Did you know about Net Neutrality? 25 | - Did you think it was a good thing? 26 | - Did you think about the negative aspects of it being put into law? 27 | - Are there reasons for traffic shaping or blocking connections 28 | - Why are large tel-cos interested in treating different internet traffic differently 29 | - How may this affect peer-to-peer applications? 30 | - How may a community mesh network affect this? 31 | - Network is a limited resource that is determined by the infrastructure 32 | - Discuss the need for keeping a pulse of the network 33 | - What attributes are important to monitor 34 | - How are these attributes measured? 35 | - Identify units and what they mean 36 | - Where have we seen it in our daily lives? 37 | 38 | ## 2: Hands-on and material exploration 39 | 40 | Monitor flow of network traffic using different tools as we do every day digital things. 41 | 42 | ### Objectives 43 | 44 | Learn how these metrics affect us in our day to day lives, and in contrast how the same metrics affect others. 45 | 46 | ### Materials 47 | 48 | - Your cellphone 49 | - Some sort of public WiFi or internet connection 50 | - A Raspberry Pi 3 for each participant labeled with the SSID for the node 51 | - SD cards with pre-flashed images with all required software 52 | - Laptops that can establish a SSH session to each Raspberry Pi (each running a Host AP with unique SSID) 53 | - USB WiFi radio that is [ad-hoc or 802.11s-capable](https://github.com/phillymesh/802.11s-adapters) for each Raspberry Pi 3 54 | 55 | ### Format 56 | 57 | Groups (or pairs) to start, class discussion then back to groups again 58 | 59 | ### Activity 60 | 61 | As the whole class: 62 | 63 | a. Review your cell phone usage: 64 | - Identify your apps' data usage 65 | - Record a few of the top apps that took up the most data 66 | - Was this data cellular, or WiFi? 67 | 68 | b. Public WiFi speed test: 69 | - Use a speed test tool (e.g. speedtest.net) to test the speed of the public WiFi, record the result 70 | - Is it faster or slower than the connection you have at home? 71 | - Run the speed test again, record the result 72 | 73 | c. Discuss measurements and units: 74 | - What unit is the data usage of your apps measured in? 75 | - What does MB mean? 76 | - What was some of the top app and how much MB did it use? 77 | - Have participants volunteer their info if they feel comfortable doing so 78 | - Was that surprising? 79 | - Would you be more/less surprised if it was cellular data? What if it was WiFi data? 80 | - Are different data sources worth more? 81 | - Why? What is your cell data limit? 82 | - What unit was the WiFi speed measured in? 83 | - What does Mbps mean? 84 | - How does this relate to the MB from apps? 85 | - Why was the speed different between tests? 86 | 87 | d. Show `bwm-ng` (Bandwidth Monitor - Next Generation) on a mesh node and describe what it is: 88 | - Information provided 89 | - How to toggle between items 90 | 91 | Break into smaller groups: 92 | 93 | - Connect to the node 94 | - SSH into the node 95 | - Run small web server 96 | - Run `bwm-ng` 97 | - Stream a video file that is located on a node's local webserver and observe the metrics 98 | - Use `tc` (Traffic Control) to limit the bandwidth and observe what and how the metrics change 99 | 100 | Discuss results in larger group and ask the following questions: 101 | 102 | - Did difficulty increase measuring two nodes at the same time? 103 | - What would happen if we have a city-wide mesh? 104 | - Ping time 105 | - Throughput 106 | - CPU usage 107 | - Are some metrics more important than others? 108 | - How do you represent a mesh network? 109 | - Physical network topology (e.g. [Toronto Mesh map](https://tomesh.net/map/)) 110 | - Virtual peering topology (e.g. [fc00.org](https://www.fc00.org/)) 111 | 112 | ## 3: Discussion and reflection activity 113 | 114 | Q & A about sharing broken Internet experiences, understanding failure points and why we measure 115 | 116 | - Break into 3 groups 117 | - Each group is assigned a user profile 118 | - Gamer 119 | - Streamer (Youtube, Netflix, etc.) 120 | - Web user with occasional video conferencing calls (web, email, instant messaging, Skype, Hangout, etc.) 121 | - Spend 10 minutes discussing the characteristics of this user and what metrics are important to them and why. Consider some of these questions: 122 | - What are the most used services by the user? 123 | - How would the user be affected if internet access becomes unavailable? 124 | - What would the user consider as "internet went down"? 125 | - What is the threshold for the user? 126 | - Packet loss / poor link quality 127 | - Latency / ping 128 | - Bandwidth speed 129 | - Bandwidth allotment 130 | - Does network traffic trend change throughout the day for the user's connection? 131 | - Look at your local internet provider (Bell, Rogers, etc.), which plan would you suggest for them and why? 132 | - Does wired vs wireless affect the experience? 133 | - Have each group spend 2 minutes presenting their user profile and their findings 134 | - Make the assumption that the 3 profiles live in the same household, does that change any of the recommendations is so how? 135 | - How will things change if services are accessed through / hosted on a community mesh network? 136 | 137 | ## 4: Wrap-up and week ahead 138 | 139 | - Read Sonia Bussu's perspective on [public engagement in the development of IoT](http://blogs.lse.ac.uk/usappblog/2014/12/13/public-engagement-on-the-internet-of-things-is-essential-if-we-are-to-put-societal-values-at-the-centre-of-technological-developments/) 140 | - Browse [Public Lab's website of DIY science projects](https://publiclab.org/methods). Are there any projects of your own that you might want to use technology to explore? 141 | - Optional: Watch the National Film Board series on Antennas: 142 | - [Propogation](https://www.youtube.com/watch?v=7bDyA5t1ldU) 143 | - [Directivity](https://www.youtube.com/watch?v=md7GjQQ2YA0&) 144 | - [Bandwidth](https://www.youtube.com/watch?v=9iV_YICgifA&) 145 | -------------------------------------------------------------------------------- /module-5/handouts/2-bandwidth-testing-with-a-video-stream.md: -------------------------------------------------------------------------------- 1 | Bandwidth testing with a video stream 2 | ===================================== 3 | 4 | ## Connecting to your Raspberry Pi 5 | 6 | 1. Verify that the Raspberry Pi has the SD card in place. Power on the device and wait for a solid green light with a flashing red light. 7 | 8 | 1. Connect your computer's WiFi Client to the Raspberry Pi's WiFi Access Point: 9 | 10 | - SSID: `` 11 | - Password: `password` 12 | 13 | 1. Once your computer is connected to the WiFi Access Point, you can access the Raspberry Pi via a Secure Shell (SSH): 14 | 15 | - Host: `.local` (or `10.0.0.1`) 16 | - Username: `root` 17 | - Password: `root` 18 | 19 | On **macOS or Linux** using **Terminal**, enter `ssh root@example.local` followed by the password `root`. 20 | 21 | On **Windows** using the **PuTTY** graphical interface, enter the `Host` and select `SSH` then click `Open` to initiate an SSH session. Enter the `Username` and `Password` when prompted. 22 | 23 | You are now connected to and able to run commands from your Raspberry Pi. The Raspberry Pis are currently not connected to all the other ones in the room. Find a partner and we will manually get the two Raspberry Pis to talk over a wireless mesh with a series of commands provided. For the rest of this activity, we will use `example` to represent your node. 24 | 25 | For this workshop you will need to open two SSH connections. Repeat the last step to open a second session. 26 | 27 | ## Measuring bandwidth with `bwm-ng` 28 | 29 | 1. `bwm-ng` (Bandwidth Monitor - Next Generation) is a software tool that allows you to see your network usage in real-time. It will list all your interfaces, and how much traffic is moving through them in each direction. In one of your SSH prompts, start `bwm-ng` with the following command: 30 | 31 | **root@example:~#** `bwm-ng` 32 | 33 | Notice the screen that displays all the interfaces on your Raspberry Pi and the current bandwidth being used. Locate the line that contains `wlan0:`. This is the interface for your wireless Access Point. We will be monitoring this connection. 34 | 35 | 1. Understand what the three number columns for each interface represent: 36 | 37 | | Column | Description | 38 | |:--------|:-----------------------------------------| 39 | | `Rx` | Amount of data being received | 40 | | `Tx` | Amount of data that is being transmitted | 41 | | `Total` | The sum of Rx and Tx | 42 | 43 | 1. Values by default are updated every `0.500s` (half a second). You can use the `+` and `-` keys to increase or decrease the sampling. Set the probing interval to `0.500s`. 44 | 45 | 1. Values by default are in `KB/s` (kilobytes per second). You can use the `u` key to cycle between: 46 | 47 | | Unit | Description | 48 | |:-------|:---------------------| 49 | | `KB/s` | Kilobytes per second | 50 | | `kb/s` | Kilobits per second | 51 | | `P/s` | Packets per second | 52 | | `E/s` | Errors per second | 53 | 54 | Set the unit to `kb/s`. 55 | 56 | 1. Values by default are shown as `rate`. You can use the `t` key to cycle between: 57 | 58 | | Type | Description | 59 | |:------------|:------------------------------------------------| 60 | | `rate` | Value on the interface when it was polled | 61 | | `max` | Highest number seen on the interface | 62 | | `sum` | Total data passed since the program was started | 63 | | `avg (30s)` | Average of the past 30 seconds | 64 | 65 | Set the type to `rate`. 66 | 67 | ## Streaming video content with the wireless interface 68 | 69 | 1. Keeping the `bwm-ng` program open in our first SSH session, we will now use the other SSH session to start a mini webserver with `nweb` to share the contents of the `www` folder on the Raspberry Pi: 70 | 71 | **root@example:~#** `nweb 8080 www` 72 | 73 | 1. From the browser of your computer, go to: 74 | 75 | `http://10.0.0.1:8080/bunny.mp4` 76 | 77 | While you enjoy the first few seconds of this short movie, notice the changing values in the `bwm-ng` window. Do you notice spikes in traffic every 30 seconds or so? If not, change to `avg (30s)`, and the spikes will seem to last longer. Keep the video playing for at least 30 seconds to see the spikes. 78 | 79 | When streaming a video, the computer will buffer information ahead of time. This allows the video to continue playing even if there is an interruption in the link. With a fast connection, the buffer fills up very quickly. These are the short spikes. 80 | 81 | 1. Download the video to your computer. What happens to the bandwidth in `bwm-ng`? 82 | 83 | Did you see the bandwidth increase and stay high for the duration of the download? Since you requested the file to be downloaded, instead of buffering blocks as you stream, your computer fetched the entire file as fast as it could. The 9-minute video downloaded in seconds! 84 | 85 | 1. Now we will now use the `tc` (Traffic Control) command to limit the available bandwidth on the wireless interface of the Raspberry Pi. This will emulate a slower internet connection. In the SSH session not running `bwm-ng`, run the following: 86 | 87 | **root@example:~#** `tc qdisc add dev wlan0 handle 1: root htb default 1` 88 | **root@example:~#** `tc class add dev wlan0 parent 1:1 classid 1:1 htb rate 512kbit` 89 | 90 | This limits the bandwidth to only 512 kilobits per second. This is approximately the upload (Tx) speed of a classic 6 Mbps ADSL, that is still used in many areas in Canada. 91 | 92 | Reload the video on your browser: 93 | 94 | - What happens to the bandwidth? 95 | - How does it differ from the previous steps? 96 | - What happens to the video? 97 | - Does the video play smoothly? 98 | 99 | 1. Clear the traffic control by running: 100 | 101 | **root@example:~#** `tc qdisc del dev wlan0 root` 102 | 103 | 1. Repeat the process using values of `1mbit` and `3mbit`. Accomplish this by replacing the `512kbit` value in the above commands with one of the new values. 104 | 105 | To save yourself from having to re-type the whole line, you should be able to use the ↑ and ↓ keys to cycle through previous commands you entered, then you can modify them. 106 | 107 | Remember to keep the video playing for at least 30 seconds, and to run `tc qdisc del dev wlan0 root` to clear the settings. -------------------------------------------------------------------------------- /module-6/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Living on a decentralized network" 4 | module: "6" 5 | contents: 6 | - _articles/module-6/presentation.md 7 | - _articles/module-6/pdf-assets.md 8 | following: _articles/module-6/presentation.md 9 | --- 10 | 11 | # Module 6: Living on a decentralized network 12 | 13 | | **Section** | **Length** | 14 | |------------------------------------------------------------------------------------|------------| 15 | | [**1: Topic introduction**](#1-topic-introduction) | 15 min | 16 | | [**2: Hands-on and material exploration**](#2-hands-on-and-material-exploration) | 40 min | 17 | | [**3: Discussion and reflection activity**](#3-discussion-and-reflection-activity) | 20 min | 18 | | [**4: Wrap-up and week ahead**](#4-wrap-up-and-week-ahead) | 5 min | 19 | | **Workshop length** | 1:30 min | 20 | 21 | ## 1: Topic introduction 22 | 23 | - As the cost of hardware (specifically processors and sensors) drops a lot of the compution and network that's being done isn't just in our computers but in embedded systems all around us 24 | - Discussion format questions: 25 | - What are some examples of internet connected devices that are not personal computers? 26 | - As more devices come online what are some new challenges that can arise? Are the security stakes higher? 27 | - When can it be a bad idea to connect something to the internet? What is at risk? 28 | - Motivation to use low power networks: 29 | - Accessibility: Energy, cost, simplicity 30 | - Ideal for community projects (eg. citizen science projects, emergency communication systems) 31 | 32 | ## 2: Hands-on and material exploration 33 | 34 | Try out a toy 900 MHz long range low power network and visualize the packet flow 35 | 36 | ### Objectives 37 | - Visualize modulated packets using a software defined radio 38 | - Leave the classroom and measure the range of the network using a map software like Google Maps 39 | - Estimate power requirements using a coulomb counter 40 | 41 | ### Materials 42 | - 1 Rasberry Pi running the "steamlink" LoRa back-end connected to a display unit (projecter would be ideal) 43 | - 4-6 LoRa radio ARM boards (sensor nodes) with a push-button as the sensor device 44 | - 1 SDR 45 | - 1 coulomb counter 46 | 47 | See [this repository](https://github.com/steamlink/p2p-workshop-nodes) for help with setup 48 | 49 | ### Format 50 | - 4-6 groups 51 | 52 | ### Activity 53 | - Boot all the sensor nodes and the single Raspberry Pi. The Raspberry Pi should detect sign-on packets from the LoRa nodes and display them on the screen 54 | - Additional packets are sent everytime the button is pressed 55 | - Take turns using the SDR to visual the chirp spread spectrum modulation 56 | - Walk around (including leaving the class room) and see how the packet RSSI changes. How does the RSSI change as the radio signal passes through walls and other objects? 57 | - How far can we go and still receive packets? Use a map software to calculate the distance 58 | - Pass around a coulomb counter to see how much power data packets take during transmission 59 | - Estimate the power limitations for your sensor node by extrapolating from the value you have observed from the Coulomb counter 60 | - If there is more time, we can program the LoRa boards (using Arduino software) to send custom information (for example text or measurement from a light sensor) 61 | 62 | ## 3: Discussion and reflection activity 63 | - We used a button as a sensor. What are some useful sensors we can use instead? 64 | - What are some applications for a low power network that you would like to build to sense information about your environment or to automate events? 65 | - Based on our experience so far, what are some things to keep in mind if we build an alternative long-range network for emergency communication? 66 | - Discuss new smart-city projects currently underway. What are some ethical considations we should think about when building private sensor networks in public spaces? 67 | - Is there a trade-off between convenience and privacy/security? 68 | 69 | ## 4: Wrap-up and week ahead 70 | - Provide useful resources to design and develop with other radio technologies (eg. Mike McCauley's excellent RadioHead library) 71 | - Provide resources on low power micro-controllers for those interested 72 | -------------------------------------------------------------------------------- /module-6/presentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Module Six 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 172 | 173 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /module-6/slide-images/decoding-lora.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/module-6/slide-images/decoding-lora.jpg -------------------------------------------------------------------------------- /module-6/slide-images/sl-testnode0-bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/module-6/slide-images/sl-testnode0-bb.png -------------------------------------------------------------------------------- /package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | RELEASE_VERSION=$1 4 | 5 | ################################################### 6 | # Package archives for releasing to GitHub Release 7 | ################################################### 8 | 9 | # Create directory for release assets ready to be published 10 | rm -rf publish 11 | mkdir publish 12 | 13 | # Package assets in tar.gz and zip formats 14 | tar --create --gzip -f "publish/workshop-materials-${RELEASE_VERSION}.tar.gz" -C output . 15 | cd output; zip --recurse-paths "../publish/workshop-materials-${RELEASE_VERSION}.zip" .; cd .. 16 | 17 | ########################################## 18 | # Generate hosted assets for GitHub Pages 19 | ########################################## 20 | 21 | # Replace home page in site directory with repo README.md 22 | homepage="site/index.md" 23 | rm -f "$homepage" 24 | { 25 | echo "---" 26 | echo "layout: home" 27 | echo "---" 28 | } > "$homepage" 29 | cat "README.md" >> "$homepage" 30 | 31 | # Create directory for release assets in site directory 32 | art="site/_articles" 33 | rm -rf "$art" 34 | mkdir "$art" 35 | 36 | # Create folder for general assets 37 | dst="$art/general" 38 | mkdir "$dst" 39 | 40 | # Create .pdf assets index file 41 | { 42 | echo "---" 43 | echo "layout: page" 44 | echo "title: 'General'" 45 | echo "---" 46 | echo "## General PDF assets" >> "$dst.md" 47 | } > "$dst.md" 48 | 49 | # Copy .pdf assets 50 | for doc in output/general/*.pdf; do 51 | if [ -f $doc ]; then 52 | cp "$doc" "$dst" 53 | filename=$(basename $doc) 54 | echo "* [$filename]($filename)" >> "$dst.md" 55 | fi 56 | done 57 | 58 | # Go through each module 59 | for mod in module-*; do 60 | # Create folder for module 61 | dst="$art/$mod" 62 | mkdir "$dst" 63 | 64 | # Copy .md lesson plan 65 | cp "$mod/README.md" "$dst.md" 66 | 67 | # Create presentation index file 68 | { 69 | echo "---" 70 | echo "layout: page" 71 | echo "title: 'Presentation slides'" 72 | echo "module: '$(echo "$mod" | sed 's/module-/Module /')'" 73 | echo "---" 74 | echo "## $(echo "Presentation slides for $mod" | sed 's/module-/Module /')" 75 | } > "$dst/presentation.md" 76 | 77 | # Copy presentation 78 | cp -r "output/slide-files" "$dst/slide-files" 79 | mkdir "$dst/presentation" 80 | cp -r "output/$mod/slide-images" "$dst/presentation/slide-images" 81 | cp "output/$mod/presentation.html" "$dst/presentation/index.html" 82 | echo "* [presentation](index.html)" >> "$dst/presentation.md" 83 | 84 | # Create .pdf assets index file 85 | { 86 | echo "---" 87 | echo "layout: page" 88 | echo "title: 'PDF assets'" 89 | echo "module: '$(echo "$mod" | sed 's/module-/Module /')'" 90 | echo "---" 91 | echo "## $(echo "PDF assets for $mod" | sed 's/module-/Module /')" 92 | } > "$dst/pdf-assets.md" 93 | 94 | # Copy .pdf assets 95 | mkdir "$dst/pdf-assets" 96 | 97 | echo "" >> "$dst/pdf-assets.md" 98 | echo "### Lesson plan" >> "$dst/pdf-assets.md" 99 | cp "output/$mod/$mod.pdf" "$dst/pdf-assets" 100 | filename="$mod.pdf" 101 | echo "* [$filename]($filename)" >> "$dst/pdf-assets.md" 102 | 103 | if [ -d output/$mod/handouts ] && [ "$(ls output/$mod/handouts/*.pdf 2>/dev/null)" ]; then 104 | echo "" >> "$dst/pdf-assets.md" 105 | echo "### Class handouts" >> "$dst/pdf-assets.md" 106 | for doc in output/$mod/handouts/*.pdf; do 107 | if [ -f $doc ]; then 108 | cp "$doc" "$dst/pdf-assets" 109 | filename=$(basename $doc) 110 | echo "* [$filename]($filename)" >> "$dst/pdf-assets.md" 111 | fi 112 | done 113 | fi 114 | done 115 | 116 | # Build static website 117 | cd site; bundle install; bundle exec jekyll build; cd .. 118 | -------------------------------------------------------------------------------- /pdf.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i|Roboto+Mono:400,700,700i&subset=latin-ext'); 2 | 3 | body { 4 | font-size: 0.625em; 5 | font-family: 'Open Sans' sans-serif; 6 | } 7 | 8 | code, 9 | kbd, 10 | pre, 11 | samp { 12 | font-family: 'Roboto Mono' monospace, serif !important; 13 | } -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | _site 3 | .sass-cache 4 | .jekyll-metadata 5 | 6 | # Generated by build script 7 | _articles 8 | index.md 9 | -------------------------------------------------------------------------------- /site/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "github-pages" 3 | -------------------------------------------------------------------------------- /site/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (4.2.10) 5 | i18n (~> 0.7) 6 | minitest (~> 5.1) 7 | thread_safe (~> 0.3, >= 0.3.4) 8 | tzinfo (~> 1.1) 9 | addressable (2.5.2) 10 | public_suffix (>= 2.0.2, < 4.0) 11 | coffee-script (2.4.1) 12 | coffee-script-source 13 | execjs 14 | coffee-script-source (1.11.1) 15 | colorator (1.1.0) 16 | commonmarker (0.17.13) 17 | ruby-enum (~> 0.5) 18 | concurrent-ruby (1.1.5) 19 | dnsruby (1.61.2) 20 | addressable (~> 2.5) 21 | em-websocket (0.5.1) 22 | eventmachine (>= 0.12.9) 23 | http_parser.rb (~> 0.6.0) 24 | ethon (0.12.0) 25 | ffi (>= 1.3.0) 26 | eventmachine (1.2.7) 27 | execjs (2.7.0) 28 | faraday (0.15.4) 29 | multipart-post (>= 1.2, < 3) 30 | ffi (1.10.0) 31 | forwardable-extended (2.6.0) 32 | gemoji (3.0.0) 33 | github-pages (197) 34 | activesupport (= 4.2.10) 35 | github-pages-health-check (= 1.16.1) 36 | jekyll (= 3.7.4) 37 | jekyll-avatar (= 0.6.0) 38 | jekyll-coffeescript (= 1.1.1) 39 | jekyll-commonmark-ghpages (= 0.1.5) 40 | jekyll-default-layout (= 0.1.4) 41 | jekyll-feed (= 0.11.0) 42 | jekyll-gist (= 1.5.0) 43 | jekyll-github-metadata (= 2.12.1) 44 | jekyll-mentions (= 1.4.1) 45 | jekyll-optional-front-matter (= 0.3.0) 46 | jekyll-paginate (= 1.1.0) 47 | jekyll-readme-index (= 0.2.0) 48 | jekyll-redirect-from (= 0.14.0) 49 | jekyll-relative-links (= 0.6.0) 50 | jekyll-remote-theme (= 0.3.1) 51 | jekyll-sass-converter (= 1.5.2) 52 | jekyll-seo-tag (= 2.5.0) 53 | jekyll-sitemap (= 1.2.0) 54 | jekyll-swiss (= 0.4.0) 55 | jekyll-theme-architect (= 0.1.1) 56 | jekyll-theme-cayman (= 0.1.1) 57 | jekyll-theme-dinky (= 0.1.1) 58 | jekyll-theme-hacker (= 0.1.1) 59 | jekyll-theme-leap-day (= 0.1.1) 60 | jekyll-theme-merlot (= 0.1.1) 61 | jekyll-theme-midnight (= 0.1.1) 62 | jekyll-theme-minimal (= 0.1.1) 63 | jekyll-theme-modernist (= 0.1.1) 64 | jekyll-theme-primer (= 0.5.3) 65 | jekyll-theme-slate (= 0.1.1) 66 | jekyll-theme-tactile (= 0.1.1) 67 | jekyll-theme-time-machine (= 0.1.1) 68 | jekyll-titles-from-headings (= 0.5.1) 69 | jemoji (= 0.10.2) 70 | kramdown (= 1.17.0) 71 | liquid (= 4.0.0) 72 | listen (= 3.1.5) 73 | mercenary (~> 0.3) 74 | minima (= 2.5.0) 75 | nokogiri (>= 1.8.5, < 2.0) 76 | rouge (= 2.2.1) 77 | terminal-table (~> 1.4) 78 | github-pages-health-check (1.16.1) 79 | addressable (~> 2.3) 80 | dnsruby (~> 1.60) 81 | octokit (~> 4.0) 82 | public_suffix (~> 3.0) 83 | typhoeus (~> 1.3) 84 | html-pipeline (2.11.0) 85 | activesupport (>= 2) 86 | nokogiri (>= 1.4) 87 | http_parser.rb (0.6.0) 88 | i18n (0.9.5) 89 | concurrent-ruby (~> 1.0) 90 | jekyll (3.7.4) 91 | addressable (~> 2.4) 92 | colorator (~> 1.0) 93 | em-websocket (~> 0.5) 94 | i18n (~> 0.7) 95 | jekyll-sass-converter (~> 1.0) 96 | jekyll-watch (~> 2.0) 97 | kramdown (~> 1.14) 98 | liquid (~> 4.0) 99 | mercenary (~> 0.3.3) 100 | pathutil (~> 0.9) 101 | rouge (>= 1.7, < 4) 102 | safe_yaml (~> 1.0) 103 | jekyll-avatar (0.6.0) 104 | jekyll (~> 3.0) 105 | jekyll-coffeescript (1.1.1) 106 | coffee-script (~> 2.2) 107 | coffee-script-source (~> 1.11.1) 108 | jekyll-commonmark (1.3.1) 109 | commonmarker (~> 0.14) 110 | jekyll (>= 3.7, < 5.0) 111 | jekyll-commonmark-ghpages (0.1.5) 112 | commonmarker (~> 0.17.6) 113 | jekyll-commonmark (~> 1) 114 | rouge (~> 2) 115 | jekyll-default-layout (0.1.4) 116 | jekyll (~> 3.0) 117 | jekyll-feed (0.11.0) 118 | jekyll (~> 3.3) 119 | jekyll-gist (1.5.0) 120 | octokit (~> 4.2) 121 | jekyll-github-metadata (2.12.1) 122 | jekyll (~> 3.4) 123 | octokit (~> 4.0, != 4.4.0) 124 | jekyll-mentions (1.4.1) 125 | html-pipeline (~> 2.3) 126 | jekyll (~> 3.0) 127 | jekyll-optional-front-matter (0.3.0) 128 | jekyll (~> 3.0) 129 | jekyll-paginate (1.1.0) 130 | jekyll-readme-index (0.2.0) 131 | jekyll (~> 3.0) 132 | jekyll-redirect-from (0.14.0) 133 | jekyll (~> 3.3) 134 | jekyll-relative-links (0.6.0) 135 | jekyll (~> 3.3) 136 | jekyll-remote-theme (0.3.1) 137 | jekyll (~> 3.5) 138 | rubyzip (>= 1.2.1, < 3.0) 139 | jekyll-sass-converter (1.5.2) 140 | sass (~> 3.4) 141 | jekyll-seo-tag (2.5.0) 142 | jekyll (~> 3.3) 143 | jekyll-sitemap (1.2.0) 144 | jekyll (~> 3.3) 145 | jekyll-swiss (0.4.0) 146 | jekyll-theme-architect (0.1.1) 147 | jekyll (~> 3.5) 148 | jekyll-seo-tag (~> 2.0) 149 | jekyll-theme-cayman (0.1.1) 150 | jekyll (~> 3.5) 151 | jekyll-seo-tag (~> 2.0) 152 | jekyll-theme-dinky (0.1.1) 153 | jekyll (~> 3.5) 154 | jekyll-seo-tag (~> 2.0) 155 | jekyll-theme-hacker (0.1.1) 156 | jekyll (~> 3.5) 157 | jekyll-seo-tag (~> 2.0) 158 | jekyll-theme-leap-day (0.1.1) 159 | jekyll (~> 3.5) 160 | jekyll-seo-tag (~> 2.0) 161 | jekyll-theme-merlot (0.1.1) 162 | jekyll (~> 3.5) 163 | jekyll-seo-tag (~> 2.0) 164 | jekyll-theme-midnight (0.1.1) 165 | jekyll (~> 3.5) 166 | jekyll-seo-tag (~> 2.0) 167 | jekyll-theme-minimal (0.1.1) 168 | jekyll (~> 3.5) 169 | jekyll-seo-tag (~> 2.0) 170 | jekyll-theme-modernist (0.1.1) 171 | jekyll (~> 3.5) 172 | jekyll-seo-tag (~> 2.0) 173 | jekyll-theme-primer (0.5.3) 174 | jekyll (~> 3.5) 175 | jekyll-github-metadata (~> 2.9) 176 | jekyll-seo-tag (~> 2.0) 177 | jekyll-theme-slate (0.1.1) 178 | jekyll (~> 3.5) 179 | jekyll-seo-tag (~> 2.0) 180 | jekyll-theme-tactile (0.1.1) 181 | jekyll (~> 3.5) 182 | jekyll-seo-tag (~> 2.0) 183 | jekyll-theme-time-machine (0.1.1) 184 | jekyll (~> 3.5) 185 | jekyll-seo-tag (~> 2.0) 186 | jekyll-titles-from-headings (0.5.1) 187 | jekyll (~> 3.3) 188 | jekyll-watch (2.2.1) 189 | listen (~> 3.0) 190 | jemoji (0.10.2) 191 | gemoji (~> 3.0) 192 | html-pipeline (~> 2.2) 193 | jekyll (~> 3.0) 194 | kramdown (1.17.0) 195 | liquid (4.0.0) 196 | listen (3.1.5) 197 | rb-fsevent (~> 0.9, >= 0.9.4) 198 | rb-inotify (~> 0.9, >= 0.9.7) 199 | ruby_dep (~> 1.2) 200 | mercenary (0.3.6) 201 | mini_portile2 (2.4.0) 202 | minima (2.5.0) 203 | jekyll (~> 3.5) 204 | jekyll-feed (~> 0.9) 205 | jekyll-seo-tag (~> 2.1) 206 | minitest (5.11.3) 207 | multipart-post (2.0.0) 208 | nokogiri (1.10.8) 209 | mini_portile2 (~> 2.4.0) 210 | octokit (4.14.0) 211 | sawyer (~> 0.8.0, >= 0.5.3) 212 | pathutil (0.16.2) 213 | forwardable-extended (~> 2.6) 214 | public_suffix (3.0.3) 215 | rb-fsevent (0.10.3) 216 | rb-inotify (0.10.0) 217 | ffi (~> 1.0) 218 | rouge (2.2.1) 219 | ruby-enum (0.7.2) 220 | i18n 221 | ruby_dep (1.5.0) 222 | rubyzip (2.0.0) 223 | safe_yaml (1.0.5) 224 | sass (3.7.4) 225 | sass-listen (~> 4.0.0) 226 | sass-listen (4.0.0) 227 | rb-fsevent (~> 0.9, >= 0.9.4) 228 | rb-inotify (~> 0.9, >= 0.9.7) 229 | sawyer (0.8.1) 230 | addressable (>= 2.3.5, < 2.6) 231 | faraday (~> 0.8, < 1.0) 232 | terminal-table (1.8.0) 233 | unicode-display_width (~> 1.1, >= 1.1.1) 234 | thread_safe (0.3.6) 235 | typhoeus (1.3.1) 236 | ethon (>= 0.9.0) 237 | tzinfo (1.2.5) 238 | thread_safe (~> 0.1) 239 | unicode-display_width (1.5.0) 240 | 241 | PLATFORMS 242 | ruby 243 | 244 | DEPENDENCIES 245 | github-pages 246 | 247 | BUNDLED WITH 248 | 1.17.2 249 | -------------------------------------------------------------------------------- /site/_config.yml: -------------------------------------------------------------------------------- 1 | title: Building the Peer-to-Peer Internet 2 | subtitle: Workshop Series by Toronto Mesh 3 | email: hello@tomesh.net 4 | twitter: https://twitter.com/tomeshnet 5 | chat: https://chat.tomesh.net/#/room/#p2p-internet-workshop:tomesh.net 6 | description: >- 7 | Open-source syllabus to explore community mesh networks and distributed applications 8 | through social activities and various tinkerings with Raspberry Pi and LoRa systems. 9 | baseurl: "/p2p-internet-workshop" 10 | url: "https://tomeshnet.github.io" 11 | github: 12 | repo: "tomeshnet/p2p-internet-workshop" 13 | branch: "gh-pages" 14 | collections: 15 | articles: 16 | output: true 17 | permalink: /:path/ 18 | 19 | # Build settings 20 | markdown: kramdown 21 | 22 | redcarpet: 23 | extensions: [ 24 | 'no_intra_emphasis', 25 | 'fenced_code_blocks', 26 | 'autolink', 27 | 'strikethrough', 28 | 'superscript', 29 | 'with_toc_data', 30 | 'tables', 31 | 'hardwrap' 32 | ] 33 | 34 | # variables 35 | video: "" 36 | assignment: "Assignment: " 37 | -------------------------------------------------------------------------------- /site/_includes/contents.html: -------------------------------------------------------------------------------- 1 | {% if include.item %} 2 | {% assign item = include.item %} 3 | {% else %} 4 | {% assign item = site.pages | where: "path", "contents.html" | first %} 5 | {% endif %} 6 | 7 | -------------------------------------------------------------------------------- /site/_includes/footer.html: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /site/_includes/navigation.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | 21 | 24 | -------------------------------------------------------------------------------- /site/_includes/videowrapper.html: -------------------------------------------------------------------------------- 1 | #### {{ site.video }} {{ include.title }} 2 | 3 | -------------------------------------------------------------------------------- /site/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{ site.title }}{% if page.title %} : {{ page.title }}{% endif %} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 | {% assign post_count = site.posts|size %} 27 | 30 |
31 | {{ content }} 32 |
33 |
34 | 35 |
36 | {% include footer.html %} 37 |
38 |
39 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /site/_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 10 | 11 |
12 | {{ content }} 13 | 14 | Get started   15 | 16 |
17 | -------------------------------------------------------------------------------- /site/_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | 14 | 53 | {{ content }} 54 | 55 | {% if page.contents %} 56 |

In This Section

57 | {% for path in page.contents %} 58 | {% assign subpage = site.articles | where: "path", path | first %} 59 |

60 | {% if subpage.module %}{{ subpage.module }}.{% endif %} 61 | {{ subpage.title }} 62 | {% if subpage.time %} 63 | ({{ subpage.time }}) 64 | {% endif %} 65 |

66 | {% endfor %} 67 | {% endif %} 68 | 69 | {% if page.following %} 70 | {% assign next = site.articles | where: "path", page.following | first %} 71 | 72 | next: 73 | {{ next.title }}   74 | 75 | 76 |
77 | {% endif %} 78 | 79 | 80 |

81 | 82 | Help us improve content and 83 | suggest changes to this course. 84 |

85 |
86 | -------------------------------------------------------------------------------- /site/contents.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | contents: 4 | - _articles/module-1.md 5 | - _articles/module-2.md 6 | - _articles/module-3.md 7 | - _articles/module-4.md 8 | - _articles/module-5.md 9 | - _articles/module-6.md 10 | - _articles/general.md 11 | --- 12 | 13 | {% include contents.html %} -------------------------------------------------------------------------------- /site/css/syntax.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #ffffff; } 3 | .highlight .c { color: #888888 } /* Comment */ 4 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 5 | .highlight .k { color: #008800; font-weight: bold } /* Keyword */ 6 | .highlight .cm { color: #888888 } /* Comment.Multiline */ 7 | .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ 8 | .highlight .c1 { color: #888888 } /* Comment.Single */ 9 | .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .ge { font-style: italic } /* Generic.Emph */ 12 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 13 | .highlight .gh { color: #333333 } /* Generic.Heading */ 14 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 15 | .highlight .go { color: #888888 } /* Generic.Output */ 16 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 17 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 18 | .highlight .gu { color: #666666 } /* Generic.Subheading */ 19 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 20 | .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ 21 | .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ 22 | .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ 23 | .highlight .kp { color: #008800 } /* Keyword.Pseudo */ 24 | .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ 25 | .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ 26 | .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ 27 | .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ 28 | .highlight .na { color: #336699 } /* Name.Attribute */ 29 | .highlight .nb { color: #003388 } /* Name.Builtin */ 30 | .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ 31 | .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ 32 | .highlight .nd { color: #555555 } /* Name.Decorator */ 33 | .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ 34 | .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ 35 | .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ 36 | .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ 37 | .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ 38 | .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ 39 | .highlight .nv { color: #336699 } /* Name.Variable */ 40 | .highlight .ow { color: #008800 } /* Operator.Word */ 41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ 43 | .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ 44 | .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ 45 | .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ 46 | .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ 47 | .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ 48 | .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ 49 | .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ 50 | .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ 51 | .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ 52 | .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ 53 | .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ 54 | .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ 55 | .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ 56 | .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ 57 | .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ 58 | .highlight .vc { color: #336699 } /* Name.Variable.Class */ 59 | .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ 60 | .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ 61 | .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ 62 | -------------------------------------------------------------------------------- /site/img/cc-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /site/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/site/img/favicon.png -------------------------------------------------------------------------------- /site/img/footer-icon-conduct.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /site/img/footer-icon-email.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/img/footer-icon-github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/img/footer-icon-help.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/img/footer-icon-irc.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /site/img/footer-icon-terms.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/img/footer-icon-twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/img/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/site/img/hero.png -------------------------------------------------------------------------------- /slide-files/fonts/jost/LICENSE.md: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE 2 | ===================== 3 | 4 | Version 1.1 - 26 February 2007 5 | 6 | PREAMBLE 7 | The goals of the Open Font License (OFL) are to stimulate worldwide 8 | development of collaborative font projects, to support the font creation 9 | efforts of academic and linguistic communities, and to provide a free and 10 | open framework in which fonts may be shared and improved in partnership 11 | with others. 12 | 13 | The OFL allows the licensed fonts to be used, studied, modified and 14 | redistributed freely as long as they are not sold by themselves. The 15 | fonts, including any derivative works, can be bundled, embedded, 16 | redistributed and/or sold with any software. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | 27 | "Original Version" refers to the collection of Font Software components as 28 | distributed by the Copyright Holder(s). 29 | 30 | "Modified Version" refers to any derivative made by adding to, deleting, 31 | or substituting — in part or in whole — any of the components of the 32 | Original Version, by changing formats or by porting the Font Software to a 33 | new environment. 34 | 35 | "Author" refers to any designer, engineer, programmer, technical 36 | writer or other person who contributed to the Font Software. 37 | 38 | PERMISSION & CONDITIONS 39 | Permission is hereby granted, free of charge, to any person obtaining 40 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 41 | redistribute, and sell modified and unmodified copies of the Font 42 | Software, subject to the following conditions: 43 | 44 | 1) Neither the Font Software nor any of its individual components, 45 | in Original or Modified Versions, may be sold by itself. 46 | 47 | 2) Original or Modified Versions of the Font Software may be bundled, 48 | redistributed and/or sold with any software, provided that each copy 49 | contains the above copyright notice and this license. These can be 50 | included either as stand-alone text files, human-readable headers or 51 | in the appropriate machine-readable metadata fields within text or 52 | binary files as long as those fields can be easily viewed by the user. 53 | 54 | 55 | 3) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 56 | Software shall not be used to promote, endorse or advertise any 57 | Modified Version, except to acknowledge the contribution(s) of the 58 | Copyright Holder(s) and the Author(s) or with their explicit written 59 | permission. 60 | 61 | 4) The Font Software, modified or unmodified, in part or in whole, 62 | must be distributed entirely under this license, and must not be 63 | distributed under any other license. The requirement for fonts to 64 | remain under this license does not apply to any document created 65 | using the Font Software. 66 | 67 | TERMINATION 68 | This license becomes null and void if any of the above conditions are 69 | not met. 70 | 71 | DISCLAIMER 72 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 73 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 74 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 75 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 76 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 77 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 78 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 79 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 80 | OTHER DEALINGS IN THE FONT SOFTWARE. 81 | -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-100-hairline.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-100-hairline.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-100-hairlineitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-100-hairlineitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-200-thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-200-thin.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-200-thinitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-200-thinitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-300-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-300-light.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-300-lightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-300-lightitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-400-book.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-400-book.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-400-bookitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-400-bookitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-500-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-500-medium.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-500-mediumitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-500-mediumitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-600-semi.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-600-semi.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-600-semiitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-600-semiitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-700-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-700-bold.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-700-bolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-700-bolditalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-800-heavy.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-800-heavy.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-800-heavyitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-800-heavyitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-900-black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-900-black.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost-900-blackitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/jost/jost-900-blackitalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/jost/jost.css: -------------------------------------------------------------------------------- 1 | /* Hairline */ 2 | @font-face { 3 | font-family: 'Jost*'; 4 | font-style: normal; 5 | font-weight: 100; 6 | src: local('Jost* Hairline'), url(jost-100-hairline.woff2) format('woff2'); 7 | } 8 | 9 | @font-face { 10 | font-family: 'Jost*'; 11 | font-style: italic; 12 | font-weight: 100; 13 | src: local('Jost* HairlineItalic'), url(jost-100-hairlineitalic.woff2) format('woff2'); 14 | } 15 | 16 | /* Thin */ 17 | @font-face { 18 | font-family: 'Jost*'; 19 | font-style: normal; 20 | font-weight: 200; 21 | src: local('Jost* Thin'), url(jost-200-thin.woff2) format('woff2'); 22 | } 23 | 24 | @font-face { 25 | font-family: 'Jost*'; 26 | font-style: italic; 27 | font-weight: 200; 28 | src: local('Jost* ThinItalic'), url(jost-200-thinitalic.woff2) format('woff2'); 29 | } 30 | 31 | /* Light */ 32 | @font-face { 33 | font-family: 'Jost*'; 34 | font-style: normal; 35 | font-weight: 300; 36 | src: local('Jost* Light'), url(jost-300-light.woff2) format('woff2'); 37 | } 38 | 39 | @font-face { 40 | font-family: 'Jost*'; 41 | font-style: italic; 42 | font-weight: 300; 43 | src: local('Jost* LightItalic'), url(jost-300-lightitalic.woff2) format('woff2'); 44 | } 45 | 46 | /* Book */ 47 | @font-face { 48 | font-family: 'Jost*'; 49 | font-style: normal; 50 | font-weight: 400; 51 | src: local('Jost* Book'), url(jost-400-book.woff2) format('woff2'); 52 | } 53 | 54 | @font-face { 55 | font-family: 'Jost*'; 56 | font-style: italic; 57 | font-weight: 400; 58 | src: local('Jost* BookItalic'), url(jost-400-bookitalic.woff2) format('woff2'); 59 | } 60 | 61 | /* Medium */ 62 | @font-face { 63 | font-family: 'Jost*'; 64 | font-style: normal; 65 | font-weight: 500; 66 | src: local('Jost* Medium'), url(jost-500-medium.woff2) format('woff2'); 67 | } 68 | 69 | @font-face { 70 | font-family: 'Jost*'; 71 | font-style: italic; 72 | font-weight: 500; 73 | src: local('Jost* MediumItalic'), url(jost-500-mediumitalic.woff2) format('woff2'); 74 | } 75 | 76 | /* Semi */ 77 | @font-face { 78 | font-family: 'Jost*'; 79 | font-style: normal; 80 | font-weight: 600; 81 | src: local('Jost* Semi'), url(jost-600-semi.woff2) format('woff2'); 82 | } 83 | 84 | @font-face { 85 | font-family: 'Jost*'; 86 | font-style: italic; 87 | font-weight: 600; 88 | src: local('Jost* SemiItalic'), url(jost-600-semiitalic.woff2) format('woff2'); 89 | } 90 | 91 | /* Bold */ 92 | @font-face { 93 | font-family: 'Jost*'; 94 | font-style: normal; 95 | font-weight: 700; 96 | src: local('Jost* Bold'), url(jost-700-bold.woff2) format('woff2'); 97 | } 98 | 99 | @font-face { 100 | font-family: 'Jost*'; 101 | font-style: italic; 102 | font-weight: 700; 103 | src: local('Jost* BoldItalic'), url(jost-700-bolditalic.woff2) format('woff2'); 104 | } 105 | 106 | /* Heavy */ 107 | @font-face { 108 | font-family: 'Jost*'; 109 | font-style: normal; 110 | font-weight: 800; 111 | src: local('Jost* Heavy'), url(jost-800-heavy.woff2) format('woff2'); 112 | } 113 | 114 | @font-face { 115 | font-family: 'Jost*'; 116 | font-style: italic; 117 | font-weight: 800; 118 | src: local('Jost* HeavyItalic'), url(jost-800-heavyitalic.woff2) format('woff2'); 119 | } 120 | 121 | /* Black */ 122 | @font-face { 123 | font-family: 'Jost*'; 124 | font-style: normal; 125 | font-weight: 900; 126 | src: local('Jost* Black'), url(jost-900-black.woff2) format('woff2'); 127 | } 128 | 129 | @font-face { 130 | font-family: 'Jost*'; 131 | font-style: italic; 132 | font-weight: 900; 133 | src: local('Jost* BlackItalic'), url(jost-900-blackitalic.woff2) format('woff2'); 134 | } -------------------------------------------------------------------------------- /slide-files/fonts/ubuntu-mono/LICENSE.txt: -------------------------------------------------------------------------------- 1 | ------------------------------- 2 | UBUNTU FONT LICENCE Version 1.0 3 | ------------------------------- 4 | 5 | PREAMBLE 6 | This licence allows the licensed fonts to be used, studied, modified and 7 | redistributed freely. The fonts, including any derivative works, can be 8 | bundled, embedded, and redistributed provided the terms of this licence 9 | are met. The fonts and derivatives, however, cannot be released under 10 | any other licence. The requirement for fonts to remain under this 11 | licence does not require any document created using the fonts or their 12 | derivatives to be published under this licence, as long as the primary 13 | purpose of the document is not to be a vehicle for the distribution of 14 | the fonts. 15 | 16 | DEFINITIONS 17 | "Font Software" refers to the set of files released by the Copyright 18 | Holder(s) under this licence and clearly marked as such. This may 19 | include source files, build scripts and documentation. 20 | 21 | "Original Version" refers to the collection of Font Software components 22 | as received under this licence. 23 | 24 | "Modified Version" refers to any derivative made by adding to, deleting, 25 | or substituting -- in part or in whole -- any of the components of the 26 | Original Version, by changing formats or by porting the Font Software to 27 | a new environment. 28 | 29 | "Copyright Holder(s)" refers to all individuals and companies who have a 30 | copyright ownership of the Font Software. 31 | 32 | "Substantially Changed" refers to Modified Versions which can be easily 33 | identified as dissimilar to the Font Software by users of the Font 34 | Software comparing the Original Version with the Modified Version. 35 | 36 | To "Propagate" a work means to do anything with it that, without 37 | permission, would make you directly or secondarily liable for 38 | infringement under applicable copyright law, except executing it on a 39 | computer or modifying a private copy. Propagation includes copying, 40 | distribution (with or without modification and with or without charging 41 | a redistribution fee), making available to the public, and in some 42 | countries other activities as well. 43 | 44 | PERMISSION & CONDITIONS 45 | This licence does not grant any rights under trademark law and all such 46 | rights are reserved. 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining a 49 | copy of the Font Software, to propagate the Font Software, subject to 50 | the below conditions: 51 | 52 | 1) Each copy of the Font Software must contain the above copyright 53 | notice and this licence. These can be included either as stand-alone 54 | text files, human-readable headers or in the appropriate machine- 55 | readable metadata fields within text or binary files as long as those 56 | fields can be easily viewed by the user. 57 | 58 | 2) The font name complies with the following: 59 | (a) The Original Version must retain its name, unmodified. 60 | (b) Modified Versions which are Substantially Changed must be renamed to 61 | avoid use of the name of the Original Version or similar names entirely. 62 | (c) Modified Versions which are not Substantially Changed must be 63 | renamed to both (i) retain the name of the Original Version and (ii) add 64 | additional naming elements to distinguish the Modified Version from the 65 | Original Version. The name of such Modified Versions must be the name of 66 | the Original Version, with "derivative X" where X represents the name of 67 | the new work, appended to that name. 68 | 69 | 3) The name(s) of the Copyright Holder(s) and any contributor to the 70 | Font Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except (i) as required by this licence, (ii) to 72 | acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with 73 | their explicit written permission. 74 | 75 | 4) The Font Software, modified or unmodified, in part or in whole, must 76 | be distributed entirely under this licence, and must not be distributed 77 | under any other licence. The requirement for fonts to remain under this 78 | licence does not affect any document created using the Font Software, 79 | except any version of the Font Software extracted from a document 80 | created using the Font Software may only be distributed under this 81 | licence. 82 | 83 | TERMINATION 84 | This licence becomes null and void if any of the above conditions are 85 | not met. 86 | 87 | DISCLAIMER 88 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 89 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 90 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 91 | COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 92 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 93 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 94 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 95 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER 96 | DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /slide-files/fonts/ubuntu-mono/UbuntuMono-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/ubuntu-mono/UbuntuMono-Bold.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/ubuntu-mono/UbuntuMono-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/ubuntu-mono/UbuntuMono-BoldItalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/ubuntu-mono/UbuntuMono-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/ubuntu-mono/UbuntuMono-Italic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/ubuntu-mono/UbuntuMono-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/ubuntu-mono/UbuntuMono-Regular.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/ubuntu-mono/ubuntu-mono.css: -------------------------------------------------------------------------------- 1 | /* Regular */ 2 | @font-face { 3 | font-family: 'Ubuntu Mono'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: local('Ubuntu Mono'), local('UbuntuMono-Regular'), url(UbuntuMono-Regular.woff2) format('woff2'); 7 | } 8 | 9 | @font-face { 10 | font-family: 'Ubuntu Mono'; 11 | font-style: italic; 12 | font-weight: 400; 13 | src: local('Ubuntu Mono Italic'), local('UbuntuMono-Italic'), url(UbuntuMono-Italic.woff2) format('woff2'); 14 | } 15 | 16 | /* Bold */ 17 | @font-face { 18 | font-family: 'Ubuntu Mono'; 19 | font-style: normal; 20 | font-weight: 700; 21 | src: local('Ubuntu Mono Bold'), local('UbuntuMono-Bold'), url(UbuntuMono-Bold.woff2) format('woff2'); 22 | } 23 | 24 | @font-face { 25 | font-family: 'Ubuntu Mono'; 26 | font-style: italic; 27 | font-weight: 700; 28 | src: local('Ubuntu Mono Bold Italic'), local('UbuntuMono-BoldItalic'), url(UbuntuMono-BoldItalic.woff2) format('woff2'); 29 | } -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2017, The Mozilla Foundation 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-Bold.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-BoldItalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-Italic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-Light.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-LightItalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-Medium.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-MediumItalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-Regular.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-SemiBold.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/ZillaSlab-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomeshnet/p2p-internet-workshop/983c55672efb42b61feaa81149795ac6c32549f9/slide-files/fonts/zilla-slab/ZillaSlab-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /slide-files/fonts/zilla-slab/zilla-slab.css: -------------------------------------------------------------------------------- 1 | /* Light */ 2 | @font-face { 3 | font-family: 'Zilla Slab'; 4 | font-style: normal; 5 | font-weight: 300; 6 | src: local('Zilla Slab Light'), local('ZillaSlab-Light'), url(ZillaSlab-Light.woff2) format('woff2'); 7 | } 8 | 9 | @font-face { 10 | font-family: 'Zilla Slab'; 11 | font-style: italic; 12 | font-weight: 300; 13 | src: local('Zilla Slab Light Italic'), local('ZillaSlab-LightItalic'), url(ZillaSlab-LightItalic.woff2) format('woff2'); 14 | } 15 | 16 | /* Regular */ 17 | @font-face { 18 | font-family: 'Zilla Slab'; 19 | font-style: normal; 20 | font-weight: 400; 21 | src: local('Zilla Slab'), local('ZillaSlab-Regular'), url(ZillaSlab-Regular.woff2) format('woff2'); 22 | } 23 | 24 | @font-face { 25 | font-family: 'Zilla Slab'; 26 | font-style: italic; 27 | font-weight: 400; 28 | src: local('Zilla Slab Italic'), local('ZillaSlab-Italic'), url(ZillaSlab-Italic.woff2) format('woff2'); 29 | } 30 | 31 | /* Medium */ 32 | @font-face { 33 | font-family: 'Zilla Slab'; 34 | font-style: normal; 35 | font-weight: 500; 36 | src: local('Zilla Slab Medium'), local('ZillaSlab-Medium'), url(ZillaSlab-Medium.woff2) format('woff2'); 37 | } 38 | 39 | @font-face { 40 | font-family: 'Zilla Slab'; 41 | font-style: italic; 42 | font-weight: 500; 43 | src: local('Zilla Slab Medium Italic'), local('ZillaSlab-MediumItalic'), url(ZillaSlab-MediumItalic.woff2) format('woff2'); 44 | } 45 | 46 | /* SemiBold */ 47 | @font-face { 48 | font-family: 'Zilla Slab'; 49 | font-style: normal; 50 | font-weight: 600; 51 | src: local('Zilla Slab SemiBold'), local('ZillaSlab-SemiBold'), url(ZillaSlab-SemiBold.woff2) format('woff2'); 52 | } 53 | 54 | @font-face { 55 | font-family: 'Zilla Slab'; 56 | font-style: italic; 57 | font-weight: 600; 58 | src: local('Zilla Slab SemiBold Italic'), local('ZillaSlab-SemiBoldItalic'), url(ZillaSlab-SemiBoldItalic.woff2) format('woff2'); 59 | } 60 | 61 | /* Bold */ 62 | @font-face { 63 | font-family: 'Zilla Slab'; 64 | font-style: normal; 65 | font-weight: 700; 66 | src: local('Zilla Slab Bold'), local('ZillaSlab-Bold'), url(ZillaSlab-Bold.woff2) format('woff2'); 67 | } 68 | 69 | @font-face { 70 | font-family: 'Zilla Slab'; 71 | font-style: italic; 72 | font-weight: 700; 73 | src: local('Zilla Slab Bold Italic'), local('ZillaSlab-BoldItalic'), url(ZillaSlab-BoldItalic.woff2) format('woff2'); 74 | } -------------------------------------------------------------------------------- /slide-files/polyfills.js: -------------------------------------------------------------------------------- 1 | exports.apply = function () { 2 | forEach([Array, window.NodeList, window.HTMLCollection], extend); 3 | }; 4 | 5 | function forEach (list, f) { 6 | var i; 7 | 8 | for (i = 0; i < list.length; ++i) { 9 | f(list[i], i); 10 | } 11 | } 12 | 13 | function extend (object) { 14 | var prototype = object && object.prototype; 15 | 16 | if (!prototype) { 17 | return; 18 | } 19 | 20 | prototype.forEach = prototype.forEach || function (f) { 21 | forEach(this, f); 22 | }; 23 | 24 | prototype.filter = prototype.filter || function (f) { 25 | var result = []; 26 | 27 | this.forEach(function (element) { 28 | if (f(element, result.length)) { 29 | result.push(element); 30 | } 31 | }); 32 | 33 | return result; 34 | }; 35 | 36 | prototype.map = prototype.map || function (f) { 37 | var result = []; 38 | 39 | this.forEach(function (element) { 40 | result.push(f(element, result.length)); 41 | }); 42 | 43 | return result; 44 | }; 45 | } -------------------------------------------------------------------------------- /slide-files/remark.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | + 5 | - 6 | 7 |
8 |
9 |
10 |
11 |
Notes for current slide
12 |
13 |
14 |
15 |
Notes for next slide
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Paused 26 |
27 |
28 |
29 |
30 |

Help

31 |

Keyboard shortcuts

32 | 33 | 34 | 40 | 41 | 42 | 43 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 68 | 69 | 70 | 71 | 76 | 77 | 78 | 79 | 82 | 83 | 84 | 85 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 97 | 101 | 102 | 103 |
35 | , 36 | , 37 | Pg Up, 38 | k 39 | Go to previous slide
44 | , 45 | , 46 | Pg Dn, 47 | Space, 48 | j 49 | Go to next slide
54 | Home 55 | Go to first slide
60 | End 61 | Go to last slide
66 | Number + Return 67 | Go to specific slide
72 | b / 73 | m / 74 | f 75 | Toggle blackout / mirrored / fullscreen mode
80 | c 81 | Clone slideshow
86 | p 87 | Toggle presenter mode
92 | t 93 | Restart the presentation timer
98 | ?, 99 | h 100 | Toggle this help
104 |
105 |
106 | 107 | 108 | 111 | 112 | 113 |
109 | Esc 110 | Back to slideshow
114 |
115 |
116 | -------------------------------------------------------------------------------- /slide-files/slide.css: -------------------------------------------------------------------------------- 1 | @import url('fonts/jost/jost.css'); 2 | @import url('fonts/zilla-slab/zilla-slab.css'); 3 | @import url('fonts/ubuntu-mono/ubuntu-mono.css'); 4 | 5 | /* Typography */ 6 | body { 7 | font-family: 'Zilla Slab', serif; 8 | } 9 | 10 | h1 { 11 | font-family: 'Jost*','Futura', sans-serif; 12 | font-weight: 600; 13 | color: #FFCD50; 14 | } 15 | 16 | h2 { 17 | font-family: 'Jost*','Futura', sans-serif; 18 | font-weight: 600; 19 | font-size: 1.7em !important; 20 | color: #FFCD50; 21 | } 22 | 23 | h3 { 24 | font-family: 'Zilla Slab', serif; 25 | font-weight: 700; 26 | color: #ddeaed; 27 | } 28 | 29 | p,ul,ol { 30 | color: #ddeaed; 31 | line-height: 1.4em; 32 | margin-top: 0.6em; 33 | margin-bottom: 0; 34 | } 35 | 36 | li { 37 | margin-top: 0.3em; 38 | } 39 | 40 | a, a:visited { 41 | color: #3EB1CF; 42 | text-decoration: none; 43 | } 44 | 45 | a:hover { 46 | color: #78d3eb; 47 | } 48 | 49 | .remark-code, .remark-inline-code { 50 | font-family: 'Ubuntu Mono', monospace; 51 | padding: 5px; 52 | border-radius: 3px; 53 | } 54 | 55 | .remark-inline-code { 56 | font-size: 0.8em; 57 | background-color: #3f424d; 58 | color: #FFCD50; 59 | } 60 | 61 | .highlight { 62 | border-radius: 1px; 63 | background-color: #4d5478; 64 | padding-left: 0.18em; 65 | padding-right: 0.18em; 66 | } 67 | 68 | .footnote { 69 | color: #9ba4a5; 70 | position: fixed; 71 | top: 90%; 72 | left: 6.5%; 73 | width: 100%; 74 | } 75 | 76 | /* Slide Layout */ 77 | div.remark-slide-content { 78 | background-color: #1c1f2b; 79 | } 80 | 81 | /* Table Styling */ 82 | table { 83 | margin-top: 1.6em; 84 | } 85 | 86 | tr { 87 | color: #ddeaed; 88 | background-color: #3f424d; 89 | } 90 | 91 | td { 92 | padding-left: 0.3em; 93 | padding-right: 0.3em; 94 | padding-top: 0.2em; 95 | padding-bottom: 0.2em; 96 | } 97 | 98 | th { 99 | color: #FFCD50; 100 | padding: 0.3em; 101 | } -------------------------------------------------------------------------------- /wip-pdf.css: -------------------------------------------------------------------------------- 1 | @import url('slide-files/fonts/jost/jost.css'); 2 | @import url('slide-files/fonts/zilla-slab/zilla-slab.css'); 3 | @import url('slide-files/fonts/ubuntu-mono/ubuntu-mono.css'); 4 | 5 | h1,h2 { 6 | font-family: 'Jost*','Futura', sans-serif; 7 | } 8 | 9 | h3,h4 { 10 | font-family: 'Jost*','Futura', sans-serif; 11 | } 12 | 13 | body { 14 | font-size: 0.625em; 15 | font-family: 'Zilla Slab', serif; 16 | } 17 | 18 | a { 19 | font-size: 0.625em; 20 | font-family: 'Zilla-Slab' serif; 21 | color: #258ca7; 22 | } 23 | 24 | code, 25 | kbd, 26 | pre, 27 | samp { 28 | font-family: 'Ubuntu Mono', monospace !important; 29 | } 30 | --------------------------------------------------------------------------------