├── .gitignore ├── LICENSE.txt ├── README.md ├── toe ├── LICENSE ├── README.md ├── dist │ └── tile.js ├── gulpfile.js ├── package-lock.json ├── package.json ├── src │ ├── tile │ │ └── tile.js │ └── urbit │ │ ├── app │ │ ├── toe.hoon │ │ └── toe │ │ │ └── js │ │ │ └── tile.js │ │ ├── lib │ │ └── toe.hoon │ │ ├── mar │ │ └── toe │ │ │ ├── cancel.hoon │ │ │ ├── player.hoon │ │ │ ├── turno.hoon │ │ │ └── winner.hoon │ │ └── sur │ │ └── toe.hoon ├── subs.png ├── tie.gif └── toe.png └── wip ├── app ├── blockio.hoon ├── echo.hoon ├── foos.hoon ├── lead.hoon ├── life.hoon ├── mail.hoon ├── mesh.hoon ├── ping.hoon ├── pong.hoon ├── sink.hoon ├── source.hoon ├── square.hoon ├── string-tester.hoon ├── sum.hoon ├── talkbot.hoon ├── taskk.hoon ├── tumblr.hoon ├── up.hoon └── wiki.hoon ├── click ├── README.md ├── app │ ├── click.hoon │ └── click │ │ └── js │ │ └── tile.js └── src │ ├── gulpfile.js │ ├── package.json │ ├── tile │ └── tile.js │ └── urbit │ └── app │ ├── click.hoon │ └── click │ └── js │ └── tile.js ├── gen ├── cow │ ├── quotes.txt │ └── say.hoon ├── fun │ └── bf.hoon ├── hello │ ├── h1.hoon │ ├── h2.hoon │ └── h3.hoon ├── project-euler │ ├── p1.hoon │ ├── p14.hoon │ ├── p2.hoon │ ├── p3.hoon │ ├── p4.hoon │ ├── p5.hoon │ ├── p6.hoon │ └── p9.hoon ├── qr.hoon ├── taskk │ └── yaml.hoon ├── tumblr │ └── feed.hoon └── weather.hoon ├── hello ├── README.md ├── app │ ├── hello.hoon │ └── hello │ │ └── js │ │ └── tile.js └── src │ ├── .urbitrc │ ├── gulpfile.js │ ├── package.json │ ├── tile │ └── tile.js │ └── urbit │ └── app │ ├── hello.hoon │ └── hello │ └── js │ └── tile.js ├── lib ├── blockio.hoon ├── jumblr.hoon ├── lisp99.hoon ├── nock.hoon ├── parse-sexpr.hoon ├── ski.hoon ├── sorts.hoon ├── string.hoon ├── strings-kmp.hoon ├── strings-piglatin.hoon └── tumblr-parse.hoon ├── mar ├── blockio │ ├── balance.hoon │ └── withdraw.hoon ├── mail │ ├── message.hoon │ └── send.hoon ├── mesh │ ├── color.hoon │ ├── friend.hoon │ ├── friends.hoon │ └── network.hoon ├── ping │ └── message.hoon ├── taskk │ ├── change-phase.hoon │ ├── create-issue.hoon │ ├── delete-issue.hoon │ ├── issue.hoon │ └── request-board.hoon ├── tumblr │ ├── blog-post.hoon │ ├── blog-posts.hoon │ ├── get-posts.hoon │ └── user-info.hoon └── wiki │ ├── articles.hoon │ └── change.hoon ├── sec ├── com │ └── tumblr.hoon └── io │ └── block.hoon ├── speakrune ├── README.md └── gen │ └── speakrune.hoon ├── sur ├── blockio.hoon ├── mail │ ├── message.hoon │ └── send.hoon ├── mesh.hoon ├── ping │ └── message.hoon ├── taskk.hoon ├── tumblr.hoon └── wiki.hoon └── web ├── examples.md ├── examples ├── app.md ├── app │ ├── blockio.md │ ├── echo.md │ ├── feed.md │ ├── foos.md │ ├── lead.md │ ├── life.md │ ├── mail.md │ ├── mesh.md │ ├── ping.md │ ├── pong.md │ ├── sink-source.md │ ├── square.md │ ├── sum.md │ ├── talkbot.md │ ├── taskk.md │ ├── tumblr.md │ ├── up.md │ └── wiki.md ├── gen.md ├── lib.md ├── mar.md ├── sur.md └── web.md └── pages ├── feed.hoon ├── feed ├── feed.css ├── feed.js ├── init.hoon └── init.js ├── foos.hoon ├── foos ├── foos.css └── foos.js ├── ford ├── 10 │ └── lib.hoon ├── 11 │ └── lib.hoon ├── 12 │ └── lib │ │ ├── 1.md │ │ └── 2.md ├── 1.hoon ├── 10.hoon ├── 11.hoon ├── 12.hoon ├── 2.hoon ├── 3.hoon ├── 4.hoon ├── 5.hoon ├── 6.hoon ├── 7.hoon ├── 8.hoon ├── 9.hoon ├── ford.css ├── hello.hoon └── hello │ └── lib.hoon ├── lead.hoon ├── lead ├── lead.css └── lead.js ├── mail.hoon ├── mail ├── mail.css └── mail.js ├── mesh.hoon ├── mesh ├── mesh.css └── mesh.js ├── taskk.html ├── taskk ├── main.css └── main.js ├── wiki.hoon └── wiki ├── main.js ├── marked └── marked.min.js ├── vue-router └── vue-router.js ├── vue └── vue.js └── wiki.css /.gitignore: -------------------------------------------------------------------------------- 1 | .DS* 2 | *.swp 3 | *.swo 4 | *.swn 5 | dist/ 6 | node_modules/ 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **All examples in this repository are obsolete as of late 2020 (with most in /wip/ obsolete even earlier). Please consult the [developer's guide](https://urbit.org/using/develop/) or community projects like [Urbit Lab](https://gitlab.com/lannel-holten/urbit-lab).** 2 | 3 | ## Introduction 4 | 5 | This is an open repository for Urbit example code. 6 | 7 | There are generators (short Dojo commands), libraries (to be loaded into 8 | Dojo), Landscape and Gall applications, and marks and structures that 9 | these example appilcations use. 10 | 11 | Give these a try by following the installation instructions below, and 12 | [peruse the list](#examples). 13 | 14 | ## Installation 15 | 16 | First, you'll need a running urbit. [Install 17 | Urbit](https://urbit.org/using/install), then 18 | [boot a ship](https://urbit.org/using/install/#booting-your-ship). 19 | 20 | For development purposes, [fake ships](https://urbit.org/using/develop/#creating-a-development-ship) 21 | are best. If you need live network connectivity, comets are recommended. 22 | 23 | ## Get started! 24 | 25 | Some applications are working examples of Landscape applications with specific 26 | types of functionality you can play around with. 27 | Others are generators, libraries for Dojo, and more. 28 | 29 | The top folder directory is listed per example; each example has folders you 30 | copy into your Urbit ship (eg. /app, /lib, /mar). Once you've copied the 31 | example into your ship, 32 | `|commit %home` (or whatever [%desk](https://urbit.org/using/operations/using-your-ship/#quickstart-2) you're using) 33 | to update your ship filesystem. 34 | 35 | ### Getting started with Landscape tiles 36 | 37 | Landscape tiles also use the [React](https://reactjs.org/) framework and require 38 | compilation if you want to change them -- find their source in the /src folder, 39 | `npm install` their dependencies, change the Urbit ship location in the `.urbitrc` file to your ship location, and `npm run serve`. 40 | 41 | If you just want to try out the Landscape tile examples, then all you need 42 | to do is copy the other folders into your ship. 43 | 44 | You'll find Landscape running on http://localhost:PORT, PORT being 80, 8080, 8081, 45 | and so on, depending on your operating system's free ports; see your ship's boot message 46 | for a notification as to what port HTTP is available on. If you haven't used 47 | Landscape before, you'll need to enter `+code` on your ship to get the password 48 | to authenticate yourself with on the Landscape interface. 49 | 50 | See also the [Urbit documentation](https://urbit.org/using/install/#using-landscape) 51 | for more information. 52 | 53 | ## Examples 54 | 55 | Each example has more information in its directory -- click an example below 56 | to learn more about it. 57 | 58 | ## Learn a lot, and have fun! 59 | 60 | The number one goal for this repository is for it to be fun! People are always 61 | around on [Chat](https://urbit.org/using/operations/using-your-ship/#quickstart). Help each other out, and don't hesitate if 62 | you have an idea for a contribution. We'd love to make this both a learning 63 | resource and a record of what people in the community are coming up with. 64 | 65 | Give us feedback [via email](mailto:support@urbit.org) after 66 | you've played around with these for a little bit. Let us know about your ideas, 67 | requests, and/or problems and we'll try and get back to you quickly. Pull 68 | requests are more than welcome. 69 | -------------------------------------------------------------------------------- /toe/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Jose Luis Bellod Cisneros 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /toe/README.md: -------------------------------------------------------------------------------- 1 | # TIC-TAC-TOE for Urbit 2 | 3 | [![Header](toe.png)](https://youtu.be/cKofR65sTHM "TIC-TAC-TOE for Urbit") 4 | 5 | 6 | ## Features 7 | 8 | - Network multiplayer. 9 | - Board state printed in the console. 10 | - Notifications for incoming requests to play. 11 | - Uses a list to keep track of incoming and outgoing subscriptions. 12 | - Pending requests are queued and pulled after current game finishes. 13 | - Styled text to print crosses and noughts on board, and game. notifications. 14 | - Integration with Landscape. 15 | 16 | ## Installation 17 | 18 | In order to run your application on your ship, you will need Urbit v.0.8.0 or higher. On your Urbit ship, if you haven't already, mount your pier to Unix with `|mount %`. 19 | 20 | Then you need to add the path to you urbit's pier in .urbitrc. The file is not provided by this repo so you need to create it manually: 21 | 22 | ``` 23 | module.exports = { 24 | URBIT_PIERS: [ 25 | "PATH/TO/YOUR/PIER", 26 | ] 27 | }; 28 | 29 | ``` 30 | 31 | You have two options to mount the game into your pier: 32 | 33 | - ##### `npm run build` 34 | 35 | This builds your application and copies it into your Urbit ship's desk. In your Urbit (v.0.8.0 or higher) `|commit %home` (or `%your-desk-name`) to synchronize your changes. 36 | 37 | - ##### `npm run serve` 38 | 39 | Builds the application and copies it into your Urbit ship's desk, watching for changes. In your Urbit (v.0.8.0 or higher) `|commit %home` (or `%your-desk-name`) to synchronize your changes. 40 | 41 | When you make changes, the `urbit` directory will update with the compiled application and, if you're running `npm run serve`, it will automatically copy itself to your Urbit ship when you save your changes (more information on that below). 42 | 43 | ## Playing 44 | 45 | ![Playing](tie.gif) 46 | 47 | In your urbit's Dojo, run the command: 48 | 49 | ~your-urbit:dojo> |start %toe 50 | 51 | The list of commands are: 52 | 53 | - `'~ship-name'`: sends request to ~ship 54 | - Only if the prompt is `| shall we play a game?` 55 | - `'!'`: cancels the current game. (if any, unqueues next subscription) 56 | - `'l'`: list current subscriptions (any time during the game) 57 | - ![list|20%](subs.png) 58 | - `'1/1'`: board coordinates (`[1-3/1-3]`) 59 | - Only if the prompt is `| ~zod:[X] <- ~dev:[O] |` 60 | - `'Y/y or N/n'`: confirm/reject request to play `[Y/N]` 61 | - Only if the prompt is: 62 | - `| ~zod wins! continue? (Y/N) |` 63 | - `| waiting for ~zod (!=quit) |` 64 | 65 | A web frontend is also available on your Urbit's Landscape Interface. 66 | 67 | ## In Progress 68 | - Heavy frontend refactor 69 | -------------------------------------------------------------------------------- /toe/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var rollup = require('gulp-better-rollup'); 3 | var sucrase = require('@sucrase/gulp-plugin'); 4 | var minify = require('gulp-minify'); 5 | 6 | var resolve = require('rollup-plugin-node-resolve'); 7 | var commonjs = require('rollup-plugin-commonjs'); 8 | var rootImport = require('rollup-plugin-root-import'); 9 | var globals = require('rollup-plugin-node-globals'); 10 | 11 | 12 | var urbitrc = require('./.urbitrc'); 13 | 14 | gulp.task('tile-jsx-transform', function(cb) { 15 | return gulp.src('./src/tile/**/*.js') 16 | .pipe(sucrase({ 17 | transforms: ['jsx'] 18 | })) 19 | .pipe(gulp.dest('dist')); 20 | }); 21 | 22 | 23 | gulp.task('tile-js-imports', function(cb) { 24 | return gulp.src('dist/tile.js') 25 | .pipe(rollup({ 26 | plugins: [ 27 | commonjs({ 28 | namedExports: { 29 | 'node_modules/react/index.js': [ 'Component' ], 30 | } 31 | }), 32 | rootImport({ 33 | root: `${__dirname}/dist/js`, 34 | useEntry: 'prepend', 35 | extensions: '.js' 36 | }), 37 | globals(), 38 | resolve() 39 | ] 40 | }, 'umd')) 41 | .on('error', function(e){ 42 | console.log(e); 43 | cb(); 44 | }) 45 | .pipe(gulp.dest('./src/urbit/app/toe/js/')) 46 | .on('end', cb); 47 | }); 48 | 49 | gulp.task('tile-js-minify', function () { 50 | return gulp.src('./src/urbit/app/toe/js/tile.js') 51 | .pipe(minify()) 52 | .pipe(gulp.dest('./src/urbit/app/toe/js/')); 53 | }); 54 | 55 | gulp.task('urbit-copy', function () { 56 | let ret = gulp.src('./src/urbit/**/*'); 57 | 58 | urbitrc.URBIT_PIERS.forEach(function(pier) { 59 | ret = ret.pipe(gulp.dest(pier)); 60 | }); 61 | 62 | return ret; 63 | }); 64 | 65 | gulp.task('tile-js-bundle-dev', gulp.series('tile-jsx-transform', 'tile-js-imports')); 66 | gulp.task('tile-js-bundle-prod', 67 | gulp.series('tile-jsx-transform', 'tile-js-imports', 'tile-js-minify') 68 | ); 69 | gulp.task('bundle-prod', gulp.series('tile-js-bundle-prod', 'urbit-copy')); 70 | gulp.task('default', gulp.series('tile-js-bundle-dev', 'urbit-copy')); 71 | gulp.task('watch', gulp.series('default', function() { 72 | gulp.watch('./src/tile/**/*.js', gulp.parallel('tile-js-bundle-dev')); 73 | gulp.watch('./src/urbit/**/*', gulp.parallel('urbit-copy')); 74 | })); 75 | -------------------------------------------------------------------------------- /toe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tic-tac-toe", 3 | "version": "0.0.2", 4 | "description": "TIC-TAC-TOE for Urbit", 5 | "main": "npm run build", 6 | "scripts": { 7 | "build": "gulp", 8 | "serve": "gulp watch" 9 | }, 10 | "author": "Jose L. Bellod Cisneros", 11 | "license": "MIT", 12 | "repository": "https://github.com/yosoyubik/tic-tac-toe", 13 | "devDependencies": { 14 | "@sucrase/gulp-plugin": "^2.0.0", 15 | "css-loader": "3.2.0", 16 | "cssnano": "^4.1.10", 17 | "gulp": "4.0.2", 18 | "gulp-better-rollup": "^4.0.1", 19 | "gulp-cssimport": "^7.0.0", 20 | "gulp-minify": "^3.1.0", 21 | "gulp-postcss": "^8.0.0", 22 | "rollup": "^1.6.0", 23 | "rollup-plugin-commonjs": "^9.2.0", 24 | "rollup-plugin-node-globals": "^1.4.0", 25 | "rollup-plugin-node-resolve": "^4.0.0", 26 | "rollup-plugin-root-import": "^0.2.3", 27 | "style-loader": "1.0.0", 28 | "sucrase": "^3.8.0" 29 | }, 30 | "dependencies": { 31 | "classnames": "^2.2.6", 32 | "fs-extra": "^8.1.0", 33 | "gulp-cli": "2.2.0", 34 | "lodash": "^4.17.11", 35 | "moment": "^2.20.1", 36 | "mousetrap": "^1.6.3", 37 | "mv": "^2.1.1", 38 | "promise": "^8.0.3", 39 | "prompt": "^1.0.0", 40 | "react": "^16.5.2", 41 | "react-dom": "^16.8.6", 42 | "react-router-dom": "^5.0.0", 43 | "replace-in-file": "^4.1.1", 44 | "urbit-ob": "^3.1.1", 45 | "urbit-sigil-js": "1.3.8" 46 | }, 47 | "resolutions": { 48 | "natives": "1.1.3" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /toe/src/urbit/lib/toe.hoon: -------------------------------------------------------------------------------- 1 | :: /lib/toe/hoon 2 | :: 3 | |% 4 | +| %players 5 | :: default, player's icons are harcoded 6 | :: me/ joiner/ first-to-replay = [X green] 7 | :: ze/inviter/second-to-confirm = [O red] 8 | :: 9 | ++ player-a |=([me=@p ze=@p] ~[me^[%'X' %g] ze^[%'O' %r]]) 10 | ++ player-b |=([me=@p ze=@p] ~[me^[%'O' %g] ze^[%'X' %r]]) 11 | +| %intro-text 12 | ++ welcome 13 | :- %klr 14 | :~ [[~ ~ ~] " "] 15 | [[`%un ~ ~] "Tic-Tac-Toe"] 16 | [[~ ~ ~] " "] 17 | == 18 | ++ brought-by "brought to you by W.O.P.R {copyright} " 19 | ++ wopr txt+(weld empties brought-by) 20 | ++ shall-we klr+~[[[`%un ~ ~] txt="shall we play a game?"]] 21 | :: 22 | +| %prompt-messages 23 | :: 24 | ++ choose " | enter @p (e.g. ~zod) | " 25 | ++ waiting " | waiting for " 26 | ++ abort "(!=quit)" 27 | ++ keep-on " continue? (Y/N) | " 28 | ++ confirm " | play with " 29 | :: 30 | +| %action-messages 31 | :: 32 | ++ no-subscribers klr+~[no-klr [[```%b] txt="* no players yet..."]] 33 | ++ spot-taken klr+~[no-klr [[```%r] txt="* spot taken"]] 34 | ++ wait-your-turn klr+~[no-klr [[```%r] txt="* wait for your turn"]] 35 | ++ instruct 36 | klr+~[no-klr [[```%b] txt="* choose a board position (e.g. 2/2)"]] 37 | ++ frowned-upon 38 | :- %klr 39 | :~ [[~ ~ ~] " * "] 40 | :- [```%y] 41 | txt="playing with yourself is frowned upon... " 42 | == 43 | ++ cancel-game 44 | |= guest=tape 45 | klr+~[[[```%b] " [{guest} cancelled your game...]"]] 46 | :: 47 | +| %text-helpers 48 | :: 49 | ++ row-sep klr+~[[[~ ~ ~] " ---------"]] 50 | ++ new-line txt+"" 51 | ++ empties " " 52 | ++ no-klr [[~ ~ ~] " "] 53 | ++ unline [`%un ~ ~] 54 | ++ empty-style klr+~[no-klr] 55 | ++ copyright (trip (tuft `@c`169)) 56 | ++ clear clr+~ 57 | ++ reset set+~ 58 | :: 59 | +| %easter-eggs 60 | ++ falken 61 | :- %mor 62 | :~ klr+~[[[`%un ~ ~] txt="Greetings professor Falken."]] 63 | klr+~[[[`%un ~ ~] txt="A strange game."]] 64 | klr+~[[[`%un ~ ~] txt="They only winning move is not to play."]] 65 | empty-style 66 | klr+~[[[`%un ~ `%b] txt="How about a nice game of chess?"]] 67 | == 68 | ++ joshua 69 | :- %mor 70 | :~ klr+~[no-klr [unline "FALKEN'S MAZE"]] 71 | klr+~[no-klr [unline "BLACK JACK"]] 72 | klr+~[no-klr [unline "GIN RUMMY"]] 73 | klr+~[no-klr [unline "HEARTS"]] 74 | klr+~[no-klr [unline "BRIDGE"]] 75 | klr+~[no-klr [unline "CHECKERS"]] 76 | klr+~[no-klr [unline "CHESS"]] 77 | klr+~[no-klr [unline "POKER"]] 78 | klr+~[no-klr [unline "FIGHTER COMBAT"]] 79 | klr+~[no-klr [unline "GUERRILLA ENGAGEMENT"]] 80 | klr+~[no-klr [unline "DESERT WARFARE"]] 81 | klr+~[no-klr [unline "AIR-TO-GROUND ACTIONS"]] 82 | klr+~[no-klr [unline "THEATERWIDE TACTICAL WARFARE"]] 83 | klr+~[no-klr [unline "THEATERWIDE BIOTOXIC AND CHEMICAL WARFARE"]] 84 | empty-style 85 | klr+~[no-klr [[`%un ~ `%r] "GLOBAL THERMONUCLEAR WAR"]] 86 | == 87 | -- 88 | -------------------------------------------------------------------------------- /toe/src/urbit/mar/toe/cancel.hoon: -------------------------------------------------------------------------------- 1 | /- *toe 2 | :: A minimal cancel mark 3 | :: 4 | |_ toe-cancel 5 | ++ grab 6 | |% 7 | ++ noun toe-cancel 8 | -- 9 | -- 10 | -------------------------------------------------------------------------------- /toe/src/urbit/mar/toe/player.hoon: -------------------------------------------------------------------------------- 1 | /- *toe 2 | :: A minimal player mark 3 | :: 4 | |_ toe-player 5 | ++ grab 6 | |% 7 | ++ noun toe-player 8 | -- 9 | -- 10 | -------------------------------------------------------------------------------- /toe/src/urbit/mar/toe/turno.hoon: -------------------------------------------------------------------------------- 1 | /- *toe 2 | :: A minimal turno mark 3 | :: 4 | |_ toe-turno 5 | ++ grab 6 | |% 7 | ++ noun toe-turno 8 | -- 9 | -- 10 | -------------------------------------------------------------------------------- /toe/src/urbit/mar/toe/winner.hoon: -------------------------------------------------------------------------------- 1 | /- *toe 2 | :: A minimal winner mark 3 | :: 4 | |_ toe-winner 5 | ++ grab 6 | |% 7 | ++ noun toe-winner 8 | -- 9 | -- 10 | -------------------------------------------------------------------------------- /toe/src/urbit/sur/toe.hoon: -------------------------------------------------------------------------------- 1 | ::/sur/toe/hoon 2 | :: 3 | |% 4 | :: 5 | +| %data-structures 6 | :: 7 | +$ game-room [board=board-game =toers who=@p] 8 | +$ game-rooms (list [=ship room=(unit game-room)]) 9 | +$ outcome (unit ?(%wins %tie)) 10 | +$ stone ?(%'X' %'O') 11 | :: $players: each player has a stone (%x/%o) and color (%g/%r) 12 | :: 13 | +$ player [=stone color=tint] 14 | +$ toers (map ship player) 15 | +$ coord ?(%1 %2 %3) 16 | +$ position [coord coord] 17 | :: $board-state: internal board for our game [@ @] -> icon 18 | :: 19 | +$ board-game (map position player) 20 | :: $game-state: current game state 21 | :: 22 | +$ game-state ?(%begin %wait %confirm %play %rematch) 23 | :: 24 | +$ action ?(%accept %rematch) 25 | :: 26 | +| %marks 27 | :: Marks sent in each move, as defined in %/mar/toe/ 28 | :: 29 | +$ toe-player [msg=action per=player] 30 | +$ toe-winner [out=tape tur=toe-turno] 31 | +$ toe-turno [per=player spo=position] 32 | +$ toe-cancel %bye 33 | -- 34 | -------------------------------------------------------------------------------- /toe/subs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbit/examples/d7b106cd85c96b97b1c7010a1208cf1aace8bce5/toe/subs.png -------------------------------------------------------------------------------- /toe/tie.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbit/examples/d7b106cd85c96b97b1c7010a1208cf1aace8bce5/toe/tie.gif -------------------------------------------------------------------------------- /toe/toe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbit/examples/d7b106cd85c96b97b1c7010a1208cf1aace8bce5/toe/toe.png -------------------------------------------------------------------------------- /wip/app/echo.hoon: -------------------------------------------------------------------------------- 1 | :: Accepts any noun from dojo and prints it out 2 | :: 3 | :::: /===/app/echo/hoon 4 | :: 5 | !: 6 | |% 7 | += move [bone card] 8 | += card $% ~ 9 | == 10 | -- 11 | :: 12 | |_ [bow=bowl:gall ~] ::< stateless 13 | :: 14 | ++ poke-noun 15 | |= non=* 16 | ^- [(list move) _+>.$] 17 | ~& echo+noun+non 18 | [~ +>.$] 19 | :: 20 | -- 21 | -------------------------------------------------------------------------------- /wip/app/foos.hoon: -------------------------------------------------------------------------------- 1 | :: store results of foosball games 2 | :: 3 | :::: /===/app/foos/hoon 4 | :: 5 | !: :: insert stack trace for this core 6 | |% :: core with data structures 7 | += move [bone card] 8 | += card $% [%diff diff-content] 9 | == 10 | += diff-content $% [$json json] 11 | == 12 | += axle (list result) :: app state: results of all past games 13 | += result $: bcons=@t bscore=@ud :: record of result 14 | ycons=@t 15 | yscore=@ud 16 | == 17 | -- 18 | :: 19 | :: 20 | |_ [bow=bowl:gall vat=axle] :: system data & app state data struct 21 | :: 22 | ++ prep _`. :: wipe state when app code is changed 23 | :: 24 | ++ poke-json :: receive JSON 25 | |= jon=json 26 | ^- [(list move) _+>.$] 27 | ~& poked+jon 28 | =+ ^- parsedresult/result :: push on result of reparsing JSON 29 | ~| bad-json+jon :: produce p in stack trace if q crashes 30 | %- need :: crash if ~ (on parse-fail) 31 | %- => dejs-soft:format :: from ++jo get "ot", obj-tuple parser 32 | :: parse tuple from ++json object "jon". 33 | (ot bcons+so bscore+ni ycons+so yscore+ni ~) 34 | jon 35 | =. vat [parsedresult vat] :: change state to [newresult oldstate] 36 | :_ +>.$ :: return (changed) app core 37 | spam :: and update subscribers 38 | :: 39 | ++ result-to-json :: reassemble ++json to respond to client 40 | |= result 41 | ^- json 42 | %- pairs:enjs:format :~ :: produce ++json object 43 | bcons+[%s bcons] :: produce ++json string 44 | ycons+[%s ycons] 45 | bscore+(numb:enjs:format bscore) :: produce ++json number from @u 46 | yscore+(numb:enjs:format yscore) 47 | == 48 | :: 49 | ++ spam :: update subscribers 50 | ^- (list move) 51 | %+ murn ~(tap by sup.bow) :: ∀ 52 | |= [ost=bone his=ship pax=path] 53 | ?^ pax ~ %- some :: empty paths 54 | [ost %diff ~+((peek his pax))] :: update state 55 | :: 56 | :: called whenever ther is a change in state. 57 | :: sends the result to all subscribers. 58 | ++ peek 59 | |= [his=ship pax=path] 60 | ^- diff-content 61 | :- %json 62 | `json`[%a (turn vat result-to-json)]:: send all results as ++json to client 63 | :: 64 | ++ peer :: subscription shim 65 | |= pax=path 66 | ^- [(list move) _+>.$] 67 | ?^ pax `+> 68 | [[ost.bow %diff (peek src.bow pax)]~ +>] 69 | :: 70 | -- 71 | -------------------------------------------------------------------------------- /wip/app/lead.hoon: -------------------------------------------------------------------------------- 1 | :: simple leaderboard 2 | :: 3 | :::: /===/app/lead/hoon 4 | :: 5 | !: 6 | |% 7 | += axle 8 | $% [%0 p=(map @t @ud)] 9 | == 10 | += diff-contents :: subscription frame 11 | $% [%json p=json] :: json 12 | == :: 13 | += kiss 14 | $% [%new-lead name=cord] :: new leader 15 | [%add-lead name=cord] :: add to leader 16 | == 17 | += move [bone card] :: output operation 18 | += card $% [%diff diff-contents] 19 | == 20 | -- 21 | :: 22 | |_ [bow=bowl:gall vat=axle] 23 | :: 24 | ++ prep 25 | |= old=(unit) 26 | [~ +>.$] 27 | :: 28 | ++ peer 29 | |= [pax=path] 30 | ^- [(list move) _+>] 31 | ?~ pax 32 | [`(list move)`[[ost.bow %diff %json vat-json] ~] +>.$] 33 | :_ +>.$ 34 | :_ ~ 35 | ?+ -.pax 36 | ~_(leaf+"you need to specify a path" ~|(%not-found !!)) 37 | %data [ost.bow %diff %json (frond:enjs:format %conn %b &)] 38 | == 39 | :: 40 | ++ vat-json 41 | ^- json 42 | :- %o 43 | %- ~(urn by p.vat) 44 | |= [k=@t v=@ud] 45 | [%n (scot %ud v)] 46 | :: 47 | ++ deliver 48 | |= pkg=[@tas json] 49 | %+ turn (prey:pubsub:userlib /data bow) 50 | |= [ost=bone his=ship pax=path] 51 | [ost %diff %json (frond:enjs:format pkg)] 52 | :: 53 | ++ poke-json 54 | |= [jon=json] 55 | ~& poked+jon 56 | ^- [(list move) _+>] 57 | =+ ^= jop 58 | ^- kiss 59 | %- need %. jon 60 | => dejs-soft:format %- of 61 | :~ [%new-lead so] 62 | [%add-lead so] 63 | == 64 | ?- -.jop 65 | %new-lead 66 | ?: (~(has by p.vat) +.jop) 67 | ~_ [%leaf "That name is already in the leaderboard."] 68 | ~|(%not-new !!) 69 | =. p.vat 70 | (~(put by p.vat) name.jop 0) 71 | :_ +>.$ 72 | (deliver %upd-lead (frond:enjs:format name.jop [%n (scot %ud 0)])) 73 | %add-lead 74 | =+ ledr=(~(get by p.vat) name.jop) 75 | ?~ ledr 76 | ~_ [%leaf "That name is not in the leaderboard."] 77 | ~|(%not-new !!) 78 | =+ scor=(need ledr) 79 | =. p.vat 80 | %- ~(urn by p.vat) 81 | |= [k=@t v=@ud] 82 | ?:(=(k name.jop) +(v) v) 83 | :_ +>.$ 84 | (deliver %upd-lead (frond:enjs:format name.jop [%n (scot %ud (add scor 1))])) 85 | == 86 | :: 87 | -- 88 | -------------------------------------------------------------------------------- /wip/app/mail.hoon: -------------------------------------------------------------------------------- 1 | :: Send simple messages between urbits 2 | :: 3 | :::: /===/app/mail/hoon 4 | :: 5 | /- mail-message, mail-send 6 | [. mail-message mail-send] 7 | :: 8 | !: 9 | |% 10 | += move [bone card] 11 | += card $% [%poke path dock poke-contents] 12 | [%diff diff-contents] 13 | == 14 | += poke-contents $% [%mail-message mail-message] 15 | == 16 | += diff-contents $% [%json json] 17 | == 18 | -- 19 | :: 20 | |_ $: bow=bowl:gall 21 | sen=(list mail-message) ::< sent messages 22 | rec=(list mail-message) ::< received messages 23 | == 24 | :: 25 | ++ prep _`. 26 | :: 27 | ++ peer 28 | |= pax=path 29 | ^- [(list move) _+>.$] 30 | =/ ordered-messages=(list mail-message) 31 | %+ sort 32 | rec 33 | |= [a=mail-message b=mail-message] 34 | (gth tim.a tim.b) 35 | :_ +>.$ 36 | :_ ~ 37 | :^ ost.bow %diff %json 38 | (inbox-to-json ordered-messages) 39 | :: 40 | ++ inbox-to-json 41 | |= box=(list mail-message) 42 | ^- json 43 | :- %a 44 | %+ turn box 45 | |= a=mail-message 46 | %- pairs:enjs:format 47 | :~ tim+(time:enjs:format tim.a) 48 | fom+s+(scot %p fom.a) 49 | to+s+(scot %p to.a) 50 | sub+s+sub.a 51 | bod+s+(of-wain:format bod.a) 52 | == 53 | ++ poke-mail-send 54 | |= sen=mail-send ::< to, subject, body 55 | ^- [(list move) _+>.$] 56 | =/ out=mail-message 57 | [now.bow our.bow to.sen sub.sen bod.sen] 58 | =. ^sen 59 | [out ^sen] 60 | ~& mail+sending+'Sending message!' 61 | :_ +>.$ 62 | :~ :* ost.bow 63 | %poke 64 | / 65 | [[to.out %mail] %mail-message out] 66 | == 67 | == 68 | ++ poke-mail-message 69 | |= mes=mail-message 70 | ?> =(to.mes our.bow) 71 | ~& mail+received+'New message!' 72 | ~& mail+time+tim.mes 73 | ~& mail+from+fom.mes 74 | ~& mail+to+to.mes 75 | ~& mail+sub+sub.mes 76 | ~& mail+bod+bod.mes 77 | =. rec 78 | [mes rec] 79 | =/ ord=(list mail-message) ::< ordered messages 80 | %+ sort 81 | rec 82 | |= [a=mail-message b=mail-message] 83 | (gth tim.a tim.b) 84 | :_ +>.$ 85 | %+ turn ~(tap by sup.bow) 86 | |= [o=bone *] 87 | [o %diff %json `json`(inbox-to-json ord)] 88 | :: 89 | ++ coup 90 | |= [wir=wire err=(unit tang)] 91 | ^- [(list move) _+>.$] 92 | ?~ err 93 | ~& mail+success+'Message sent!' 94 | [~ +>.$] 95 | ~& mail+error+'Message failed to send. Error:' 96 | ~& mail+error+err 97 | [~ +>.$] 98 | :: 99 | -- 100 | -------------------------------------------------------------------------------- /wip/app/mesh.hoon: -------------------------------------------------------------------------------- 1 | :: Simple social network 2 | :: 3 | :::: /===/app/mesh/hoon 4 | :: 5 | /- mesh 6 | [. mesh] 7 | !: 8 | |% 9 | += move [bone card] 10 | += card $% [%peer wire dock path] 11 | [%pull wire dock $~] 12 | [%diff diff-contents] 13 | == 14 | += diff-contents $% [%mesh-friends color friends] 15 | [%mesh-network color network] 16 | == 17 | -- 18 | :: 19 | |_ [bow=bowl:gall [col=color net=network]] ::< color, social net. 20 | :: 21 | ::++ prep _`. 22 | ++ poke-mesh-color 23 | |= col=color 24 | ^- [(list move) _+>.$] 25 | =. ^col col 26 | ~& mesh+'Color set! Notifying subscribers:' 27 | ~& mesh+color+col 28 | [spam +>.$] 29 | :: 30 | ++ poke-mesh-friend 31 | |= fen=friend 32 | ^- [(list move) _+>.$] 33 | ~& :- %mesh 34 | (crip (weld (weld "Friending " (scow %p fen)) "!")) 35 | :_ +>.$ 36 | :_ ~ 37 | :* ost.bow 38 | %peer 39 | /subscribe 40 | [fen %mesh] 41 | /mesh-friends 42 | == 43 | :: 44 | ++ reap 45 | |= [wire err=(unit tang)] 46 | ^- [(list move) _+>.$] 47 | ?^ err (mean u.err) 48 | ~! +<.reap 49 | =. net 50 | =/ my-net (~(get ju net) our.bow) 51 | ?: (~(has by my-net) src.bow) 52 | net 53 | =. my-net (~(put by my-net) src.bow '') 54 | (~(put by net) our.bow my-net) 55 | ~& mesh+'Friend subscribe successful!' 56 | ~& mesh+ship+src.bow 57 | [spam +>.$] 58 | :: 59 | ++ coup 60 | |= [wire err=(unit tang)] 61 | ^- [(list move) _+>.$] 62 | ?^ err (mean u.err) 63 | [~ +>.$] 64 | :: 65 | ++ diff-mesh-friends 66 | |= [wir=wire col=color fes=friends] 67 | ^- [(list move) _+>.$] 68 | ~& mesh+diff+'Network update!' 69 | ~& mesh+diff+[source+src.bow color+col friends+fes] 70 | =+ old-net=net 71 | =. net (~(put by net) src.bow fes) 72 | =. net 73 | =/ my-net (~(get ju net) our.bow) 74 | ?. (~(has by my-net) src.bow) net 75 | =. my-net (~(put by my-net) src.bow col) 76 | (~(put by net) our.bow my-net) 77 | ?: =(net old-net) [~ +>.$] 78 | [spam +>.$] 79 | :: 80 | ++ spam 81 | ^- (list move) 82 | %+ murn ~(tap by sup.bow) 83 | |= [ost=bone shp=ship pax=path] 84 | %+ bind ~+((peek shp pax)) 85 | |=(dif=diff-contents [ost %diff dif]) 86 | :: 87 | ++ peek 88 | |= [src=ship pax=path] 89 | ^- (unit diff-contents) 90 | ?~ pax ~ 91 | ?+ i.pax ~ 92 | %web 93 | `(peek-web src t.pax) 94 | %mesh-friends 95 | `(peek-mesh-friends src t.pax) 96 | == 97 | :: 98 | ++ peek-web 99 | |= ^ 100 | [%mesh-network col net] 101 | ++ peek-mesh-friends 102 | |= ^ 103 | :- %mesh-friends 104 | [col (~(get ju net) our.bow)] 105 | :: 106 | ++ peer-web 107 | |= pax=path 108 | ^- [(list move) _+>.$] 109 | ~& pax 110 | [[ost.bow %diff (peek-web src.bow pax)]~ +>.$] 111 | :: 112 | ++ peer-mesh-friends 113 | |= pax=path 114 | ^- [(list move) _+>.$] 115 | ~& mesh+'Someone friended you!' 116 | ~& mesh+ship+src.bow 117 | :_ +>.$ 118 | :_ ~ 119 | :* ost.bow 120 | %diff 121 | (peek-mesh-friends src.bow pax) 122 | == 123 | :: 124 | -- 125 | -------------------------------------------------------------------------------- /wip/app/ping.hoon: -------------------------------------------------------------------------------- 1 | :: Allows one ship to ping another with a string of text 2 | :: 3 | :::: /===/app/ping/hoon 4 | :: 5 | /- ping-message 6 | :: 7 | !: 8 | |% 9 | += move [bone card] 10 | += card $% [%poke wire dock poke-contents] 11 | == 12 | += poke-contents $% [%atom @] 13 | == 14 | -- 15 | |_ [bow=bowl:gall ~] ::< stateless 16 | :: 17 | ++ poke-ping-message 18 | |= ping-message 19 | ~& ping+'Message sent!' 20 | ^- [(list move) _+>.$] 21 | :_ +>.$ 22 | :_ ~ 23 | [ost.bow %poke /sending [to dap.bow] %atom message] 24 | :: 25 | ++ poke-atom 26 | |= arg=@ 27 | ~& ping+'Message received!' 28 | ^- [(list move) _+>.$] 29 | ~& ping+message+(@t arg) 30 | [~ +>.$] 31 | :: 32 | ++ coup |=(* `+>) 33 | -- 34 | -------------------------------------------------------------------------------- /wip/app/pong.hoon: -------------------------------------------------------------------------------- 1 | :: Allows one urbit to send the string 'Pong' to 2 | :: another urbit. 3 | :: 4 | :::: /===/app/pong/hoon 5 | :: 6 | !: 7 | |% 8 | += move [bone card] 9 | += card $% [%poke wire dock poke-contents] 10 | == 11 | += poke-contents $% [%atom @] 12 | == 13 | -- 14 | |_ [bow=bowl:gall ~] ::< stateless 15 | :: 16 | ++ poke-urbit 17 | |= to=ship 18 | ^- [(list move) _+>.$] 19 | ~& pong+'Outgoing pong!' 20 | :_ +>.$ 21 | ~[[ost.bow %poke /sending [to dap.bow] %atom 'Pong']] 22 | :: 23 | ++ poke-atom 24 | |= tom=@ 25 | ^- [(list move) _+>.$] 26 | ~& pong+'Incoming pong!' 27 | ~& pong+received+`@t`tom 28 | [~ +>.$] 29 | :: 30 | ++ coup |=(* [~ +>.$]) 31 | :: 32 | -- 33 | -------------------------------------------------------------------------------- /wip/app/sink.hoon: -------------------------------------------------------------------------------- 1 | :: Sets up a simple subscription to source.hoon 2 | :: 3 | :::: /===/app/sink/hoon 4 | :: 5 | !: 6 | |% 7 | += move [bone card] 8 | += card $% [%peer wire dock path] 9 | [%pull wire dock ~] 10 | == 11 | -- 12 | :: 13 | |_ [bow=bowl:gall val=?] ::< available? (y or n) 14 | :: 15 | ++ poke-noun 16 | |= non=* 17 | ^- [(list move) _+>.$] 18 | ?: &(=(%on non) val) 19 | :_ +>.$(val |) 20 | :~ :* ost.bow 21 | %peer 22 | /subscribe 23 | [our.bow %source] 24 | /example-path 25 | == 26 | == 27 | ?: &(=(%off non) !val) 28 | :_ +>.$(val &) 29 | ~[[ost.bow %pull /subscribe [our.bow %source] ~]] 30 | ~& ?: val 31 | sink+unsubscribed+'You are now unsubscribed!' 32 | sink+subscribed+'You are now subscribed!' 33 | [~ +>.$] 34 | :: 35 | ++ diff-noun 36 | |= [wir=wire non=*] 37 | ^- [(list move) _+>.$] 38 | ~& sink+received-data+' You got something!' 39 | ~& sink+data+non 40 | [~ +>.$] 41 | :: 42 | ++ coup 43 | |= [wir=wire err=(unit tang)] 44 | ^- [(list move) _+>.$] 45 | ?~ err 46 | ~& sink+success+'Poke succeeded!' 47 | [~ +>.$] 48 | ~& sink+error+'Poke failed. Error:' 49 | ~& sink+error+err 50 | [~ +>.$] 51 | :: 52 | ++ reap 53 | |= [wir=wire err=(unit tang)] 54 | ^- [(list move) _+>.$] 55 | ?~ err 56 | ~& sink+success+'Peer succeeded!' 57 | [~ +>.$] 58 | ~& sink+error+'Peer failed. Error:' 59 | ~& sink+error+err 60 | [~ +>.$] 61 | :: 62 | -- 63 | -------------------------------------------------------------------------------- /wip/app/source.hoon: -------------------------------------------------------------------------------- 1 | :: Sends subscription updates to sink.hoon 2 | :: 3 | :::: /===/app/source/hoon 4 | :: 5 | !: 6 | :: 7 | |% 8 | += move [bone card] 9 | += card $% [%diff diff-contents] 10 | == 11 | += diff-contents $% [%noun *] 12 | == 13 | -- 14 | :: 15 | |_ [bow=bowl:gall ~] ::< stateless 16 | :: 17 | ++ poke-noun 18 | |= non=* 19 | ^- [(list move) _+>.$] 20 | :_ +>.$ 21 | %+ turn (prey:pubsub:userlib /example-path bow) 22 | |=([o=bone *] [o %diff %noun non]) 23 | :: 24 | ++ peer-example-path 25 | |= pax=path 26 | ^- [(list move) _+>.$] 27 | ~& source+peer-notify+'Someone subscribed to you!' 28 | ~& source+[ship+src.bow path+pax] 29 | [~ +>.$] 30 | :: 31 | ++ coup 32 | |= [wir=wire err=(unit tang)] 33 | ^- [(list move) _+>.$] 34 | ?~ err 35 | ~& source+success+'Poke succeeded!' 36 | [~ +>.$] 37 | ~& source+error+'Poke failed. Error:' 38 | ~& source+error+err 39 | [~ +>.$] 40 | :: 41 | ++ reap 42 | |= [wir=wire err=(unit tang)] 43 | ^- [(list move) _+>.$] 44 | ?~ err 45 | ~& source+success+'Peer succeeded!' 46 | [~ +>.$] 47 | ~& source+error+'Peer failed. Error:' 48 | ~& source+error+err 49 | [~ +>.$] 50 | :: 51 | -- 52 | -------------------------------------------------------------------------------- /wip/app/square.hoon: -------------------------------------------------------------------------------- 1 | :: Accepts an atom from the dojo and squares it. 2 | :: 3 | :::: /===/app/square/hoon 4 | :: 5 | !: 6 | |% ::> no moves in :square 7 | += move [bone card] ::> no cards in :square 8 | += card $% ~ 9 | == 10 | -- 11 | :: 12 | |_ [bow=bowl:gall ~] ::< stateless 13 | :: 14 | ++ poke-atom 15 | |= tom=@ 16 | ^- [(list move) _+>.$] 17 | ~& square+(mul tom tom) 18 | [~ +>.$] 19 | :: 20 | ++ coup 21 | |= [wir=wire err=(unit tang)] 22 | ^- [(list move) _+>.$] 23 | ?~ err 24 | ~& square+success+'Poke succeeded!' 25 | [~ +>.$] 26 | ~& square+error+'Poke failed. Error:' 27 | ~& square+error+err 28 | [~ +>.$] 29 | :: 30 | -- 31 | -------------------------------------------------------------------------------- /wip/app/string-tester.hoon: -------------------------------------------------------------------------------- 1 | :: Primitive tester for the String library. 2 | /+ string 3 | !: 4 | |_ {bowl:gall $~} 5 | ++ poke-noun 6 | |= * 7 | ^- {(list move) _+>.$} 8 | =+ ^= results :~ 9 | 10 | ~& %sum 11 | (test sum:string "123" 150) 12 | 13 | ~& %tail 14 | (test tail:string ["0123" 2] "23") 15 | (test tail:string ["0123" 5] "0123") 16 | (test tail:string ["0123" 0] "") 17 | 18 | ~& %get 19 | (test get:string ["0123" 1 3] "12") 20 | (test get:string ["0123" 2 1] "") 21 | (test get:string ["0123" 3 6] "3") 22 | 23 | ~& %starts-with 24 | (test starts-with:string ["abcd" "ab"] &) 25 | (test starts-with:string ["abcd" "bc"] |) 26 | 27 | ~& %ends-with 28 | (test ends-with:string ["abcd" "cd"] &) 29 | (test ends-with:string ["abcd" "bc"] |) 30 | 31 | ~& %contains 32 | (test contains:string ["abcd" "bc"] &) 33 | (test contains:string ["abcd" "de"] |) 34 | 35 | ~& %contains-any 36 | (test contains-any:string ["abcd" ["de" "bc" ~]] &) 37 | (test contains-any:string ["abcd" ["de" "fg" ~]] |) 38 | 39 | ~& %contains-all 40 | (test contains-all:string ["abcd" ["ab" "bc" ~]] &) 41 | (test contains-all:string ["abcd" ["ab" "de" ~]] |) 42 | 43 | ~& %find-last 44 | (test find-last:string ["0103" "0"] [~ 2]) 45 | (test find-last:string ["0103" "4"] ~) 46 | 47 | ~& %find-nth 48 | (test find-nth:string ["0103" "0" 2] [~ 2]) 49 | (test find-nth:string ["0103" "0" 3] ~) 50 | 51 | ~& %find-first-any 52 | (test find-any:string ["012345" ["12" "2" "4" ~]] [~ 1 "12"]) 53 | (test find-any:string ["012345" ["a" "b" "c" ~]] ~) 54 | 55 | ~& %find-last-any 56 | (test find-last-any:string ["012345" ["1" "2" "34" ~]] [~ 3 "34"]) 57 | (test find-last-any:string ["012345" ["a" "b" "c" ~]] ~) 58 | 59 | ~& %trim-left 60 | (test trim-left:string " a b c " "a b c ") 61 | 62 | ~& %trim-right 63 | (test trim-right:string " a b c " " a b c") 64 | 65 | ~& %trim 66 | (test trim:string " a b c " "a b c") 67 | 68 | ~& %delete 69 | (test delete:string ["0123" 1 3] "03") 70 | (test delete:string ["0123" 2 5] "01") 71 | 72 | ~& %delete-first 73 | (test delete-first:string ["0103" "0"] "103") 74 | (test delete-first:string ["0103" "4"] "0103") 75 | 76 | ~& %delete-last 77 | (test delete-last:string ["0103" "0"] "013") 78 | (test delete-last:string ["0103" "4"] "0103") 79 | 80 | ~& %delete-nth 81 | (test delete-nth:string ["0103" "0" 2] "013") 82 | (test delete-nth:string ["0103" "0" 3] "0103") 83 | 84 | ~& %delete-all 85 | (test delete-all:string ["0103" "0"] "13") 86 | (test delete-all:string ["0103" "4"] "0103") 87 | 88 | ~& %replace 89 | (test replace:string ["0123" [1 3] "abc"] "0abc3") 90 | (test replace:string ["0123" [2 5] "abc"] "01abc") 91 | 92 | ~& %replace-first 93 | (test replace-first:string ["0103" "0" "abc"] "abc103") 94 | (test replace-first:string ["0103" "4" "abc"] "0103") 95 | 96 | ~& %replace-last 97 | (test replace-last:string ["0103" "0" "abc"] "01abc3") 98 | (test replace-last:string ["0103" "4" "abc"] "0103") 99 | 100 | ~& %replace-nth 101 | (test replace-nth:string ["0103" "0" "abc" 2] "01abc3") 102 | (test replace-nth:string ["0103" "0" "abc" 3] "0103") 103 | 104 | ~& %replace-all 105 | (test replace-all:string ["0103" "0" "abc"] "abc1abc3") 106 | (test replace-all:string ["0103" "4" "abc"] "0103") 107 | 108 | ~& %split 109 | (test split:string ["ab, c!, 1,2 " ", "] ["ab" "c!" "1,2 " ~]) 110 | 111 | ~& %glue 112 | (test glue:string [["a" "bc" "d" ~] ", "] "a, bc, d") 113 | (test glue:string [["a" "bc" "d" ~] ""] "abcd") 114 | 115 | == 116 | ~? (levy (ly results) |=(r/? r)) [%all-passed "(:"] 117 | [~ +>.$] 118 | 119 | ++ test 120 | |* {func/gate args/* expect/*} 121 | ^- ? 122 | =+ output=(func args) 123 | =+ ^= res =(output expect) 124 | ~? !res :* 125 | %failed 126 | %with-args args 127 | %expected expect 128 | %got output 129 | == 130 | res 131 | -- 132 | -------------------------------------------------------------------------------- /wip/app/sum.hoon: -------------------------------------------------------------------------------- 1 | :: Keeps track of the sum of all the atoms it has been 2 | :: poked with and prints the sum out 3 | :: 4 | :::: /===/app/sum/hoon 5 | :: 6 | !: 7 | |% 8 | += move [bone card] 9 | += card $% ~ 10 | == 11 | -- 12 | |_ [bow=bowl:gall sum=@] ::< sum is our app state 13 | :: 14 | ++ poke-atom 15 | |= tom=@ 16 | ^- [(list move) _+>.$] 17 | ~& sum+(add sum tom) 18 | [~ +>.$(sum (add sum tom))] 19 | :: 20 | ++ coup 21 | |= [wir=wire err=(unit tang)] 22 | ^- [(list move) _+>.$] 23 | ?~ err 24 | ~& sum+success+'Poke succeeded!' 25 | [~ +>.$] 26 | ~& sum+error+'Poke failed. Error:' 27 | ~& sum+error+err 28 | [~ +>.$] 29 | :: 30 | -- 31 | -------------------------------------------------------------------------------- /wip/app/taskk.hoon: -------------------------------------------------------------------------------- 1 | :: A simple task-tracking app 2 | :: 3 | :::: /===/app/taskk/hoon 4 | :: 5 | /? 310 6 | /- taskk 7 | [taskk .] 8 | |% 9 | ++ card 10 | $% [%info wire @p toro] :: write to clay 11 | [%warp wire sock riff] :: watch a dir 12 | [%diff %taskk-create-issue tape tape tape] :: update subscribers 13 | [%diff %json json] 14 | == 15 | ++ move [bone card] 16 | -- 17 | !: 18 | |_ [hid=bowl state=[subp=path wpat=path]] 19 | :: 20 | ++ poke-taskk-create-issue 21 | |= iss=issue 22 | ^- [(list move) _+>.$] 23 | :_ +>.$ 24 | %+ welp 25 | %+ turn :: notify all subscribers 26 | (prey subp.state hid) 27 | |= [o=bone *] 28 | :- o 29 | :+ %diff 30 | %taskk-create-issue 31 | iss 32 | :~ :- ost.hid :: list of moves 33 | :^ %info 34 | /writing 35 | our.hid 36 | %+ foal 37 | %+ welp 38 | wpat.state 39 | :~ (crip pha.iss) 40 | (crip iss.iss) 41 | %md 42 | == 43 | [%md !>((crip des.iss))] 44 | == 45 | :: delete issue 46 | ++ poke-taskk-delete-issue 47 | |= iss=issue-ref 48 | ~& %delete-issue-called 49 | ^- [(list move) _+>.$] 50 | :_ +>.$ 51 | :~ :- ost.hid 52 | :^ %info 53 | /deleting 54 | our.hid 55 | %- fray 56 | %+ welp 57 | wpat.state 58 | :~ (crip pha.iss) 59 | (crip iss.iss) 60 | %md 61 | == 62 | == 63 | :: 64 | :: change board phase 65 | ++ poke-taskk-change-phase 66 | |= iss=change-ref 67 | ~& %change-phase-called 68 | ^- [(list move) _+>.$] 69 | =/ inp=path 70 | %+ welp 71 | wpat.state 72 | :~ (crip fpha.iss) 73 | (crip iss.iss) 74 | %md 75 | == 76 | :_ +>.$ 77 | :~ :- ost.hid 78 | :^ %info 79 | /moving 80 | our.hid 81 | %+ furl 82 | %- fray 83 | inp 84 | %+ foal 85 | %+ welp 86 | wpat.state 87 | :~ (crip fpha.iss) 88 | (crip iss.iss) 89 | %md 90 | == 91 | [%md !>(.^(* %cx inp))] 92 | == 93 | :: request a board 94 | ++ poke-taskk-request-board 95 | |= board=[ho=tape bo=tape] 96 | ^- [(list move) _+>.$] 97 | :_ +>.$ 98 | %+ turn 99 | (prey subp.state hid) 100 | |= [o=bone *] 101 | :- o 102 | :+ %diff 103 | %json 104 | %- jobe 105 | :~ ['action-completed' (jape "request-board")] 106 | ['response-data' (crawl-path wpat.state)] 107 | == 108 | :: 109 | ++ crawl-path 110 | |= pax=path 111 | |- ^- json 112 | =+ a=.^(arch cy+pax) 113 | ?~ fil.a 114 | :- %a 115 | %+ turn 116 | (sort (~(tap by dir.a)) aor) 117 | |= [p=@t ~] 118 | [%a [[%s p] (crawl-path (welp pax /[p])) ~]] 119 | =+ txt=.^(@t cx+pax) 120 | [%s txt] 121 | :: 122 | :: subscribe to taskk front end 123 | :: 124 | ++ peer 125 | |= pax=path 126 | ~& [%subscribed-to pax] 127 | :_ %= +>.$ 128 | state :- pax 129 | %+ welp 130 | %+ tope 131 | [our.hid %home da+now.hid] 132 | (flop (limo ['app' 'taskk' ~])) 133 | pax 134 | == 135 | %+ welp 136 | (watch-dir (welp /app/taskk pax)) 137 | :~ :^ ost.hid 138 | %diff 139 | %json 140 | %- jobe 141 | ~[['action-completed' (jape "connect")]] 142 | == 143 | :: 144 | :: watch board dir for changes 145 | ++ watch-dir 146 | |= a=path 147 | ::~& [%watch-dir a] 148 | ^- (list move) 149 | :~ :- ost.hid 150 | :^ %warp 151 | a 152 | [our.hid our.hid] 153 | :- %home 154 | :- ~ 155 | [%next %z da+now.hid a] 156 | == 157 | ::will update subscribers that node changed 158 | ::once that works reasonably 159 | ::++ writ 160 | :: |= [way=wire rot=riot] 161 | :: ~& [%rot rot] 162 | :: =/ car=card 163 | :: :+ %diff 164 | :: %json 165 | :: %+ joba 166 | :: 'updated' 167 | :: (jape "true") 168 | :: :- %+ welp 169 | :: %+ turn 170 | :: (prey subp.state hid) 171 | :: |= [o=bone *] 172 | :: [o car] 173 | :: [(watch-dir way) +>.$] 174 | ++ prep _`. 175 | -- 176 | -------------------------------------------------------------------------------- /wip/app/up.hoon: -------------------------------------------------------------------------------- 1 | :: Up-ness monitor. Accepts atom url, 'on', or 'off' 2 | :: 3 | :::: /===/app/up/hoon 4 | :: 5 | !: 6 | :: 7 | |% 8 | += move [bone card] 9 | += card 10 | $% [%hiss wire ~ %httr [%purl p=purl:eyre]] 11 | [%wait wire @da] 12 | == 13 | += action 14 | $% [%on ~] :: enable polling('on') 15 | [%off ~] :: disable polling('off) 16 | [%target p=cord] :: set poll target('http:==...') 17 | == 18 | -- 19 | |_ [bow=bowl:gall on=_| in-progress=_| target=@t] 20 | :: 21 | ++ poke-atom 22 | |= url-or-command=@t 23 | ^- [(list move) _+>.$] 24 | =+ ^- act=action 25 | ?: ?=(%on url-or-command) [%on ~] 26 | ?: ?=(%off url-or-command) [%off ~] 27 | [%target url-or-command] 28 | ?- -.act 29 | %target [~ +>.$(target p.act)] 30 | %off [~ +>.$(on |)] 31 | %on 32 | :- ?: |(on in-progress) ~ 33 | :~ :* ost.bow 34 | %hiss 35 | /request 36 | ~ 37 | %httr 38 | %purl 39 | (need (de-purl:html target)) 40 | == 41 | == 42 | +>.$(on &, in-progress &) 43 | == 44 | 45 | ++ sigh-httr 46 | |= [wir=wire code=@ud headers=mess:eyre body=(unit octs)] 47 | ~& 'arrive here' 48 | ^- [(list move) _+>.$] 49 | ?: &((gte code 200) (lth code 300)) 50 | ~& [%all-is-well code] 51 | :_ +>.$ 52 | [ost.bow %wait /timer (add ~s10 now.bow)]~ 53 | ~& [%we-have-a-problem code] 54 | ~& [%headers headers] 55 | ~& [%body body] 56 | :_ +>.$ 57 | [ost.bow %wait /timer (add ~s10 now.bow)]~ 58 | ++ wake-timer 59 | |= [wir=wire ~] ^- [(list move) _+>.$] 60 | ?: on 61 | :_ +>.$ 62 | :~ :* ost.bow 63 | %hiss 64 | /request 65 | ~ 66 | %httr 67 | %purl 68 | (need (de-purl:html target)) 69 | == 70 | == 71 | [~ +>.$(in-progress |)] 72 | :: 73 | ++ prep ~& target _`. 74 | :: 75 | -- 76 | -------------------------------------------------------------------------------- /wip/click/README.md: -------------------------------------------------------------------------------- 1 | # click 2 | 3 | A landscape tile that sends a click with some JSON back to your Dojo, with a consistent state. Copy /app into your ship, `|commit %home` and `|start %example` to see your new tile in Landscape. 4 | 5 | ## Using Landscape 6 | 7 | You'll find Landscape running on http://localhost:PORT, PORT being 80, 8080, 8081, 8 | and so on, depending on your operating system's free ports; see your ship's boot message 9 | for a notification as to what port HTTP is available on. If you haven't used 10 | Landscape before, you'll need to enter `+code` on your ship to get the password 11 | to authenticate yourself with on the Landscape interface. 12 | See also the [Urbit documentation](https://urbit.org/docs/getting-started/booting-a-ship/#using-landscape) 13 | for more information. 14 | 15 | ## How 'click' works 16 | 17 | The application is started with `click.hoon` in the [/app](app) folder on your ship. 18 | It tells eyre, the HTTP vane of Arvo, where it's located, and the `launch` and `modulo` 19 | applications to subscribe to it and present it as a tile in Landscape. Landscape provides 20 | access to your ship with an `api` window object. 21 | 22 | The 'click' [tile.js](src/tile/tile.js), mounted in Landscape as part of the application, 23 | uses that api window object to poke the running click application, which, when it receives 24 | a poke with JSON, prints it to the Dojo and increments the state counter. 25 | 26 | For the poke handler's code, see [here](app/click.hoon#L50). 27 | 28 | ## Playing with 'click' 29 | 30 | Landscape tiles also use the [React](https://reactjs.org/) framework and require 31 | compilation if you want to change them -- find their source in the /src folder, 32 | `npm install` their dependencies, change the Urbit ship location in the `.urbitrc` file to your ship location, and `npm run serve`. 33 | -------------------------------------------------------------------------------- /wip/click/app/click.hoon: -------------------------------------------------------------------------------- 1 | /+ *server 2 | /= tile-js 3 | /^ octs 4 | /; as-octs:mimes:html 5 | /: /===/app/click/js/tile 6 | /| /js/ 7 | /~ ~ 8 | == 9 | =, format 10 | |% 11 | +$ effect (pair bone syscall) 12 | +$ poke 13 | $% [%launch-action [@tas path @t]] 14 | == 15 | +$ syscall 16 | $% [%poke wire dock poke] 17 | [%http-response =http-event:http] 18 | [%connect wire binding:eyre term] 19 | [%diff %json json] 20 | == 21 | -- 22 | |_ [bol=bowl:gall cis=@] 23 | ++ this . 24 | ++ bound 25 | |= [wir=wire success=? binding=binding:eyre] 26 | ^- (quip effect _this) 27 | [~ this] 28 | ++ prep 29 | |= old=(unit @) 30 | ^- (quip effect _this) 31 | =/ launcha 32 | [%launch-action [%click /clicktile '/~click/js/tile.js']] 33 | :_ 34 | ?~ old 35 | this 36 | this(cis (need old)) 37 | :~ 38 | [ost.bol %connect / [~ /'~click'] %click] 39 | [ost.bol %poke /click [our.bol %launch] launcha] 40 | == 41 | ++ peer-clicktile 42 | |= pax=path 43 | [[ost.bol %diff %json *json]~ this] 44 | ++ send-tile-diff 45 | |= jon=json 46 | ^- (list effect) 47 | %+ turn (prey:pubsub:userlib /clicktile bol) 48 | |= [=bone ^] 49 | [bone %diff %json jon] 50 | ++ poke-json 51 | |= jon=json 52 | ^- (quip effect _+>.$) 53 | ~& (weld "Click recieved from Landscape! ~ Total Clicks: " (scow %ud cis)) 54 | :_ +>.$(cis +(cis)) 55 | %+ turn (prey:pubsub:userlib /clicktile bol) 56 | |= [=bone ^] 57 | [bone %diff %json jon] 58 | ++ poke-handle-http-request 59 | %- (require-authorization:app ost.bol effect this) 60 | |= =inbound-request:eyre 61 | ^- (quip effect _this) 62 | =/ request-line (parse-request-line url.request.inbound-request) 63 | =/ back-path (flop site.request-line) 64 | =/ name=@t 65 | =/ back-path (flop site.request-line) 66 | ?~ back-path 67 | '' 68 | i.back-path 69 | ?~ back-path 70 | [[ost.bol %http-response not-found:app]~ this] 71 | ?: =(name 'tile') 72 | [[ost.bol %http-response (js-response:app tile-js)]~ this] 73 | [[ost.bol %http-response not-found:app]~ this] 74 | -- 75 | -------------------------------------------------------------------------------- /wip/click/app/click/js/tile.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classnames from 'classnames'; 3 | import _ from 'lodash'; 4 | 5 | 6 | export default class clickTile extends Component { 7 | constructor(props) { 8 | super(props); 9 | let ship = window.ship; 10 | let api = window.api; 11 | } 12 | 13 | pokeShip() { 14 | api.action('click', 'json', {click: "yes"}); 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 |

Click

21 | this.pokeShip()}>Send a Click to your Ship!. 22 |
23 | ); 24 | } 25 | 26 | } 27 | 28 | window.clickTile = clickTile; 29 | -------------------------------------------------------------------------------- /wip/click/src/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var rollup = require('gulp-better-rollup'); 3 | var sucrase = require('@sucrase/gulp-plugin'); 4 | var minify = require('gulp-minify'); 5 | 6 | var resolve = require('rollup-plugin-node-resolve'); 7 | var commonjs = require('rollup-plugin-commonjs'); 8 | var rootImport = require('rollup-plugin-root-import'); 9 | var globals = require('rollup-plugin-node-globals'); 10 | 11 | /*** 12 | Main config options 13 | ***/ 14 | 15 | var urbitrc = require('./.urbitrc'); 16 | 17 | /*** 18 | End main config options 19 | ***/ 20 | 21 | gulp.task('tile-jsx-transform', function(cb) { 22 | return gulp.src('tile/**/*.js') 23 | .pipe(sucrase({ 24 | transforms: ['jsx'] 25 | })) 26 | .pipe(gulp.dest('dist')); 27 | }); 28 | 29 | 30 | gulp.task('tile-js-imports', function(cb) { 31 | return gulp.src('dist/tile.js') 32 | .pipe(rollup({ 33 | plugins: [ 34 | commonjs({ 35 | namedExports: { 36 | 'node_modules/react/index.js': [ 'Component' ], 37 | } 38 | }), 39 | rootImport({ 40 | root: `${__dirname}/dist/js`, 41 | useEntry: 'prepend', 42 | extensions: '.js' 43 | }), 44 | globals(), 45 | resolve() 46 | ] 47 | }, 'umd')) 48 | .on('error', function(e){ 49 | console.log(e); 50 | cb(); 51 | }) 52 | .pipe(gulp.dest('./urbit/app/click/js/')) 53 | .on('end', cb); 54 | }); 55 | 56 | gulp.task('tile-js-minify', function () { 57 | return gulp.src('./urbit/app/click/js/tile.js') 58 | .pipe(minify()) 59 | .pipe(gulp.dest('./urbit/app/click/js/')); 60 | }); 61 | 62 | gulp.task('urbit-copy', function () { 63 | let ret = gulp.src('urbit/**/*'); 64 | 65 | urbitrc.URBIT_PIERS.forEach(function(pier) { 66 | ret = ret.pipe(gulp.dest(pier)); 67 | }); 68 | 69 | return ret; 70 | }); 71 | 72 | gulp.task('tile-js-bundle-dev', gulp.series('tile-jsx-transform', 'tile-js-imports')); 73 | gulp.task('tile-js-bundle-prod', 74 | gulp.series('tile-jsx-transform', 'tile-js-imports', 'tile-js-minify')); 75 | 76 | gulp.task('bundle-prod', gulp.series('tile-js-bundle-prod', 'urbit-copy')); 77 | 78 | gulp.task('default', gulp.series('tile-js-bundle-dev', 'urbit-copy')); 79 | gulp.task('watch', gulp.series('default', function() { 80 | gulp.watch('tile/**/*.js', gulp.parallel('tile-js-bundle-dev')); 81 | gulp.watch('urbit/**/*', gulp.parallel('urbit-copy')); 82 | })); 83 | -------------------------------------------------------------------------------- /wip/click/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-landscape-app", 3 | "version": "0.2.2", 4 | "description": "Get started with a Landscape application.", 5 | "main": "node install.js", 6 | "scripts": { 7 | "start": "node install.js", 8 | "build": "gulp", 9 | "serve": "gulp watch" 10 | }, 11 | "author": "Tlon Corp", 12 | "license": "MIT", 13 | "repository": "https://github.com/urbit/create-landscape-app", 14 | "devDependencies": { 15 | "@sucrase/gulp-plugin": "^2.0.0", 16 | "cssnano": "^4.1.10", 17 | "gulp": "^4.0.0", 18 | "gulp-better-rollup": "^4.0.1", 19 | "gulp-cssimport": "^7.0.0", 20 | "gulp-minify": "^3.1.0", 21 | "gulp-postcss": "^8.0.0", 22 | "rollup": "^1.6.0", 23 | "rollup-plugin-commonjs": "^9.2.0", 24 | "rollup-plugin-node-globals": "^1.4.0", 25 | "rollup-plugin-node-resolve": "^4.0.0", 26 | "rollup-plugin-root-import": "^0.2.3", 27 | "sucrase": "^3.8.0" 28 | }, 29 | "dependencies": { 30 | "classnames": "^2.2.6", 31 | "fs-extra": "^8.1.0", 32 | "lodash": "^4.17.11", 33 | "moment": "^2.20.1", 34 | "mousetrap": "^1.6.3", 35 | "mv": "^2.1.1", 36 | "promise": "^8.0.3", 37 | "prompt": "^1.0.0", 38 | "react": "^16.5.2", 39 | "react-dom": "^16.8.6", 40 | "react-router-dom": "^5.0.0", 41 | "replace-in-file": "^4.1.1", 42 | "urbit-ob": "^3.1.1" 43 | }, 44 | "resolutions": { 45 | "natives": "1.1.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /wip/click/src/tile/tile.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classnames from 'classnames'; 3 | import _ from 'lodash'; 4 | 5 | 6 | export default class clickTile extends Component { 7 | constructor(props) { 8 | super(props); 9 | let ship = window.ship; 10 | let api = window.api; 11 | } 12 | 13 | pokeShip() { 14 | api.action('click', 'json', {click: "yes"}); 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 |

Click

21 | this.pokeShip()}>Send a Click to your Ship!. 22 |
23 | ); 24 | } 25 | 26 | } 27 | 28 | window.clickTile = clickTile; 29 | -------------------------------------------------------------------------------- /wip/click/src/urbit/app/click.hoon: -------------------------------------------------------------------------------- 1 | /+ *server 2 | /= tile-js 3 | /^ octs 4 | /; as-octs:mimes:html 5 | /: /===/app/click/js/tile 6 | /| /js/ 7 | /~ ~ 8 | == 9 | =, format 10 | |% 11 | +$ effect (pair bone syscall) 12 | +$ poke 13 | $% [%launch-action [@tas path @t]] 14 | == 15 | +$ syscall 16 | $% [%poke wire dock poke] 17 | [%http-response =http-event:http] 18 | [%connect wire binding:eyre term] 19 | [%diff %json json] 20 | == 21 | -- 22 | |_ [bol=bowl:gall cis=@] 23 | ++ this . 24 | ++ bound 25 | |= [wir=wire success=? binding=binding:eyre] 26 | ^- (quip effect _this) 27 | [~ this] 28 | ++ prep 29 | |= old=(unit @) 30 | ^- (quip effect _this) 31 | =/ launcha 32 | [%launch-action [%click /clicktile '/~click/js/tile.js']] 33 | :_ 34 | ?~ old 35 | this 36 | this(cis (need old)) 37 | :~ 38 | [ost.bol %connect / [~ /'~click'] %click] 39 | [ost.bol %poke /click [our.bol %launch] launcha] 40 | == 41 | ++ peer-clicktile 42 | |= pax=path 43 | [[ost.bol %diff %json *json]~ this] 44 | ++ send-tile-diff 45 | |= jon=json 46 | ^- (list effect) 47 | %+ turn (prey:pubsub:userlib /clicktile bol) 48 | |= [=bone ^] 49 | [bone %diff %json jon] 50 | ++ poke-json 51 | |= jon=json 52 | ^- (quip effect _+>.$) 53 | ~& (weld "Click recieved from Landscape! ~ Total Clicks: " (scow %ud cis)) 54 | :_ +>.$(cis +(cis)) 55 | %+ turn (prey:pubsub:userlib /clicktile bol) 56 | |= [=bone ^] 57 | [bone %diff %json jon] 58 | ++ poke-handle-http-request 59 | %- (require-authorization:app ost.bol effect this) 60 | |= =inbound-request:eyre 61 | ^- (quip effect _this) 62 | =/ request-line (parse-request-line url.request.inbound-request) 63 | =/ back-path (flop site.request-line) 64 | =/ name=@t 65 | =/ back-path (flop site.request-line) 66 | ?~ back-path 67 | '' 68 | i.back-path 69 | ?~ back-path 70 | [[ost.bol %http-response not-found:app]~ this] 71 | ?: =(name 'tile') 72 | [[ost.bol %http-response (js-response:app tile-js)]~ this] 73 | [[ost.bol %http-response not-found:app]~ this] 74 | -- 75 | -------------------------------------------------------------------------------- /wip/click/src/urbit/app/click/js/tile.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classnames from 'classnames'; 3 | import _ from 'lodash'; 4 | 5 | 6 | export default class clickTile extends Component { 7 | constructor(props) { 8 | super(props); 9 | let ship = window.ship; 10 | let api = window.api; 11 | } 12 | 13 | pokeShip() { 14 | api.action('click', 'json', {click: "yes"}); 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 |

Click

21 | this.pokeShip()}>Send a Click to your Ship!. 22 |
23 | ); 24 | } 25 | 26 | } 27 | 28 | window.clickTile = clickTile; 29 | -------------------------------------------------------------------------------- /wip/gen/cow/say.hoon: -------------------------------------------------------------------------------- 1 | :: The classic unix "cowsay" implemented in hoon 2 | :: 3 | :: To see a cow say a quote from gen/cow/quotes.txt run: 4 | :: 5 | :: +cow/say 6 | :: 7 | /- sole 8 | /+ *generators, pretty-file 9 | :- %ask 10 | |= [[now=@da eny=@uvJ bec=beak] ~ ~] 11 | =/ max-length=@ 80 12 | =/ file-path=path /(scot %p p.bec)/[q.bec]/(scot r.bec)/gen/cow/quotes/txt 13 | =/ file=tang (pretty-file .^(noun (cat 3 %c %x) file-path)) 14 | =/ line=tank (snag (~(rad og eny) (lent file)) file) 15 | =/ tongue=tape "U" 16 | =/ thoughts=tape "o" 17 | =/ eyes=tape "oo" 18 | |^ 19 | ^- (sole-product:sole (cask tang)) 20 | =/ bubble=(list [%leaf tape]) (turn message bars) 21 | =/ bubble-width=@ (lent (snag 0 bubble)) 22 | =/ horizontal-border=[%leaf tape] 23 | leaf+(weld " " (reap (sub bubble-width 5) '-')) 24 | =/ slant-gap=tape (reap (sub bubble-width 5) ' ') 25 | =/ top-slant=[%leaf tape] leaf+" /{slant-gap}\\" 26 | =/ bottom-slant=[%leaf tape] leaf+" \\{slant-gap}/" 27 | %+ produce %tang 28 | ;: weld 29 | :~ leaf+" || ||" 30 | leaf+" {tongue} ||----w |" 31 | leaf+" (__)\\ )\\/\\" 32 | leaf+" {thoughts} ({eyes})\\_______" 33 | leaf+" {thoughts} ^__^" 34 | == 35 | ~[horizontal-border bottom-slant] 36 | bubble 37 | ~[top-slant horizontal-border] 38 | == 39 | ++ message 40 | ^- (list tape) 41 | =/ quote=tape 42 | ?+ line "" 43 | [%leaf *] p.line 44 | == 45 | (flop (split quote)) 46 | ++ split 47 | |= tap=tape 48 | ^- (list tape) 49 | ?: (gth (lent tap) max-length) 50 | =/ trimmed=[p=tape q=tape] (trim max-length tap) 51 | (weld ~[p.trimmed] (split q.trimmed)) 52 | ~[tap] 53 | ++ bars 54 | |= tap=tape 55 | ^- [%leaf tape] 56 | =/ tape-length=@ (lent tap) 57 | ?: (lth tape-length max-length) 58 | =/ padded-tap=tape (weld tap (reap (sub max-length tape-length) ' ')) 59 | leaf+"| {padded-tap} |" 60 | leaf+"| {tap} |" 61 | -- 62 | -------------------------------------------------------------------------------- /wip/gen/fun/bf.hoon: -------------------------------------------------------------------------------- 1 | :: Brainfuck in Hoon. Esoception. 2 | :: Run in :dojo with: 3 | :: 4 | :: +fun/bf 42 5 | :: 6 | :::: /===/gen/fun/bf/hoon 7 | :: 8 | !: 9 | :: 10 | :- %say 11 | |= [^ [in=@ $~] $~] 12 | :- %noun 13 | =< (bf ">++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.>>+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++.") :: run vm 14 | :: 15 | |% 16 | ++ bf 17 | |= input=(list @) 18 | =+ [ip=0 current=0 left=(reap 0 0) right=(reap 30 0)] 19 | |- ^- (list @) 20 | ?: =(ip (lent input)) 21 | (welp left [current [right]]) 22 | ?+ `@`(snag ip input) 23 | $(ip +(ip)) 24 | $'+' $(ip +(ip), current +(current)) 25 | $'-' $(ip +(ip), current (dec current)) 26 | $'>' %= $ 27 | ip +(ip) 28 | left (welp left ~[current]) 29 | current (snag 0 right) 30 | right (slag 1 right) 31 | == 32 | $'<' %= $ 33 | ip +(ip) 34 | left (scag (dec (lent left)) left) 35 | current (snag (dec (lent left)) left) 36 | right (welp ~[current] right) 37 | == 38 | $'[' ?. =(current 0) 39 | $(ip +(ip)) 40 | =+ [nest=0 pos=+(ip)] 41 | |- 42 | =+ char=`@`(snag pos input) 43 | ?: =(char '[') 44 | $(nest +(nest), pos +(pos)) 45 | ?: =(char ']') 46 | ?: =(nest 0) 47 | ^$(ip +(pos)) 48 | $(nest (dec nest), pos +(pos)) 49 | $(pos +(pos)) 50 | $']' ?: =(current 0) 51 | $(ip +(ip)) 52 | =+ [nest=0 pos=(dec ip)] 53 | |- 54 | =+ char=`@`(snag pos input) 55 | ?: =(char ']') 56 | $(nest +(nest), pos (dec pos)) 57 | ?: =(char '[') 58 | ?: =(nest 0) 59 | ^$(ip +(pos)) 60 | $(nest (dec nest), pos (dec pos)) 61 | $(pos (dec pos)) 62 | $'.' ~& `@t`current 63 | $(ip +(ip)) 64 | $',' %= $ 65 | ip +(ip) 66 | current (cut 3 [0 1] in) 67 | in (rsh 3 1 in) 68 | == 69 | == 70 | -- 71 | -------------------------------------------------------------------------------- /wip/gen/hello/h1.hoon: -------------------------------------------------------------------------------- 1 | :: Hello world example 2 | :: Run in :dojo with: 3 | :: 4 | :: ~your-urbit:dojo/examples> +hello/h1 5 | :: 'Hello, world!' 6 | :: 7 | :::: /===/gen/hello/h1/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | 'Hello, world!' 14 | -------------------------------------------------------------------------------- /wip/gen/hello/h2.hoon: -------------------------------------------------------------------------------- 1 | :: Keyword argumented hello world example 2 | :: Run in :dojo with: 3 | :: 4 | :: ~your-urbit:dojo/examples> +hello/h2 'Mars' 5 | :: 'Hello, Mars!' 6 | :: 7 | :::: /===/gen/hello/h2/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say 12 | |= [^ [[txt=@t ~] ~]] 13 | :- %noun 14 | (crip (weld (weld "Hello, " (trip txt)) "!")) 15 | -------------------------------------------------------------------------------- /wip/gen/hello/h3.hoon: -------------------------------------------------------------------------------- 1 | :: Keyword argumented hello world example. Defaults if 2 | :: no sample given. 3 | :: 4 | :: Run in :dojo with: 5 | :: 6 | :: ~your-urbit:dojo/examples> +hello/h3, =txt 'Mars' 7 | :: 'Hello, Mars!' 8 | :: 9 | :: ~your-urbit:dojo/examples> +hello/h3 10 | :: 'Hello, universe' 11 | :: 12 | :::: /===/gen/hello/h3/hoon 13 | :: 14 | !: 15 | :: 16 | :- %say 17 | |= [^ [~ txt=_'universe']] 18 | :- %noun 19 | (crip (weld (weld "Hello, " (trip txt)) "!")) 20 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p1.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 1 2 | :: https://projecteuler.net/problem=1 3 | :: 4 | :: run in dojo with: 5 | :: ~your-urbit:dojo/examples> +project-euler/p1 6 | :: 7 | :::: /===/gen/project-euler/p1/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | =< (sum 1.000) 14 | :: 15 | |% 16 | ++ three 17 | |= a=@ 18 | =| b=@ 19 | |- ^- @u 20 | ?: (lth a b) 21 | 0 22 | (add b $(b (add 3 b))) 23 | :: 24 | ++ five 25 | |= a=@ 26 | =| b=@ 27 | |- ^- @ 28 | ?: (lte a b) 29 | 0 30 | ?: =((mod b 3) 0) 31 | $(b (add b 5)) 32 | (add b $(b (add b 5))) 33 | :: 34 | ++ sum 35 | |= a=@u 36 | (add (five a) (three a)) 37 | -- 38 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p14.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 14 2 | :: https://projecteuler.net/problem=14 3 | :: 4 | :: run in dojo with: 5 | :: ~your-urbit:dojo/examples> +project-euler/p14 6 | :: 7 | :::: /===/gen/project-euler/p14/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | =< (longcol 1.000.000) :: With a manual cache, many times faster 14 | :: 15 | !. 16 | :: 17 | |% 18 | ++ collatz :: given a, returns the number of steps needed to reach 1 19 | |= [a=@u cache=(map @u @u)] 20 | =+ [curr=a len=1] 21 | |- ^- @u 22 | ?: =(curr 1) 23 | len 24 | ?: (~(has by cache) curr) :: if the len is cached... 25 | (add (dec len) (~(got by cache) curr)) :: return the len + cached len 26 | ?: =((mod curr 2) 0) 27 | $(curr (div curr 2), len +(len)) 28 | $(curr (add (mul curr 3) 1), len +(len)) 29 | :: 30 | ++ longcol :: find the longest collatz sequence under a 31 | |= [a=@u] 32 | =+ [len=0 num=0 acc=1 cache=(molt `(list (pair @ @))`[[2 1] [4 2] ~])] 33 | |- ^- [@u @u] 34 | =+ col=(collatz acc cache) 35 | ?: =(acc a) 36 | [num len] 37 | ?: (lte len col) 38 | $(len col, num acc, acc +(acc), cache (~(put by cache) acc col)) 39 | $(acc +(acc), cache (~(put by cache) acc col)) 40 | -- 41 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p2.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 2 2 | :: https://projecteuler.net/problem=2 3 | :: 4 | :: run in dojo with: 5 | :: ~your-urbit:dojo/examples> +project-euler/p2 6 | :: 7 | :::: /===/gen/project-euler/p2/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | =< (fib 4.000.000) 14 | :: 15 | |% 16 | ++ fib 17 | |= lim=@ 18 | =+ [fst=1 scd=2] 19 | |- 20 | ?. (lte scd lim) 21 | ~ 22 | ?: =((mod scd 2) 0) 23 | (add scd $(fst scd, scd (add fst scd))) 24 | $(fst scd, scd (add fst scd)) 25 | -- 26 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p3.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 3 2 | :: https://projecteuler.net/problem=3 3 | :: 4 | :: run in dojo with: 5 | :: ~your-urbit:dojo/examples> +project-euler/p3 6 | :: 7 | :::: /===/gen/project-euler/p3/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | =< (lpf 600.851.475.143) 14 | :: 15 | |% 16 | ++ lpf 17 | |= a=@ 18 | =+ b=2 19 | |- ^- @ 20 | ?: (lth a (mul b 2)) 21 | a 22 | ?: =((mod a b) 0) 23 | $(a (div a b)) 24 | $(b +(b)) 25 | -- 26 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p4.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 4 2 | :: https://projecteuler.net/problem=4 3 | :: 4 | :: > A palindromic number reads the same both ways. The largest palindrome made 5 | :: > from the product of two 2-digit numbers is 9009 = 91 × 99. 6 | :: > Find the largest palindrome made from the product of two 3-digit numbers. 7 | :: 8 | :: run in dojo with: 9 | :: ~your-urbit:dojo/examples> +project-euler/p4 10 | :: 11 | :::: /===/gen/project-euler/p4/hoon 12 | :: 13 | !: 14 | :: 15 | :- %say |= * 16 | :- %noun 17 | =< (largest-palindrome [999 999]) 18 | :: 19 | |% 20 | ++ largest-palindrome 21 | |= [a=@u b=@u] :: gate, takes cell nums 22 | =| p=@u :: palindr. var, set l8r 23 | |- ^- @u :: loop, produce a num: 24 | ?> &((lth a 1.000) (lth b 1.000)) :: assert (sure) a&b are 25 | ?> &((gte a 100) (gth b 100)) :: three-digit numbers. 26 | ?: (lth (mul a b) p) :: if a*b < p, 27 | p :: produce p 28 | %= $ :: otherwise, call loop: 29 | p |- ^- @u :: p -> prod. loop. num: 30 | ?: (lth (mul a b) p) :: if a*b < p 31 | p :: produce p. 32 | ?: =(<(mul a b)> (flop <(mul a b)>)) :: = list of chars 33 | (mul a b) :: ^if palinr., prod a*b 34 | $(b (dec b)) :: else, call loop w b-1 35 | a (dec a) :: a -> a - 1. 36 | == 37 | -- 38 | 39 | :: > +examples/euler4 40 | :: 906.609 41 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p5.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 5 2 | :: https://projecteuler.net/problem=5 3 | :: 4 | :: run in dojo with: 5 | :: ~your-urbit:dojo/examples> +project-euler/p5 6 | :: 7 | :::: /===/gen/project-euler/p5/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | =< (lcm 20) 14 | :: 15 | !. 16 | :: 17 | |% 18 | ++ sieve :: given a, check if a%div==0, incrementing div until it's lim, or .y 19 | |= [a=@u lim=@u] 20 | =+ div=1 21 | |- ^- @f 22 | ?: =(div lim) 23 | .y 24 | ?: =((mod a div) 0) 25 | $(div +(div)) 26 | .n 27 | :: 28 | ++ lcm :: check if sieve returns .y, incrementing the number until it does 29 | |= a=@u 30 | =+ b=a 31 | |- ^- @u 32 | ?: =((sieve b a) .y) 33 | b 34 | $(b (add b a)) 35 | -- 36 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p6.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 6 2 | :: https://projecteuler.net/problem=6 3 | :: 4 | :: run in dojo with: 5 | :: ~your-urbit:dojo/examples> +project-euler/p6 6 | :: 7 | :::: /===/gen/project-euler/p6/hoon 8 | :: 9 | !: 10 | :: 11 | :- %say |= * 12 | :- %noun 13 | =< (diff 100) 14 | :: 15 | |% 16 | ++ sq 17 | |= a=@u 18 | (mul a a) 19 | ++ sum 20 | |= a=@u 21 | =+ b=1 22 | |- ^- @u 23 | ?: (lth a b) 24 | 0 25 | (add b $(b +(b))) 26 | :: 27 | ++ sumsq 28 | |= a=@u 29 | =+ b=1 30 | |- ^- @u 31 | ?: (lth a b) 32 | 0 33 | (add (sq b) $(b +(b))) 34 | :: 35 | ++ diff 36 | |= a=@u 37 | (sub (sq (sum a)) (sumsq a)) 38 | -- 39 | -------------------------------------------------------------------------------- /wip/gen/project-euler/p9.hoon: -------------------------------------------------------------------------------- 1 | :: Project Euler 9 2 | :: https://projecteuler.net/problem=9 3 | :: 4 | :: > A Pythagorean triplet is a set of three natural numbers, a < b < c, for 5 | :: > which, 6 | :: > > a2 + b2 = c2 7 | :: > For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2. 8 | :: > There exists exactly one Pythagorean triplet for which a + b + c = 1000. 9 | :: > Find the product abc. 10 | :: 11 | :: run in dojo with: 12 | :: ~your-urbit:dojo/examples> +project-euler/p9 13 | :: 14 | :::: /===/gen/project-euler/p9/hoon 15 | :: 16 | !: 17 | :: 18 | :- %say |= * 19 | :- %noun 20 | =< (find-pythagorean-triplet-abc-sum-eq-one-thousand [1 1 998]) 21 | :: 22 | |% 23 | ++ find-pythagorean-triplet-abc-sum-eq-one-thousand 24 | |= [a=@u b=@u c=@u] :: gate takes 3-num cell 25 | |- ^- @u :: loop, prod is 1 num. 26 | ?: ?! =((add (add a b) c) 1.000) :: if a+b+c not= 1000, 27 | a :: produce a. 28 | %= $ :: else, call loop: 29 | a |- ^- @u :: a -> inner loop prod: 30 | ?: =((add (mul a a) (mul b b)) (mul c c)) :: if abc are pyth. trip 31 | ~& [a b c] :: println cell [a b c]. 32 | (mul (mul a b) c) :: & produce abc. 33 | ?: (lth c b) :: else, if no combos =, 34 | +(a) :: increment a (reloop). 35 | $(b +(b), c (dec c)) :: else, loop w b+1 c-1. 36 | c (dec c) :: c -> decrement c, c=1 37 | == 38 | -- 39 | 40 | :: > +examples/euler9 41 | :: [200 375 425] 42 | :: 31.875.000 43 | -------------------------------------------------------------------------------- /wip/gen/taskk/yaml.hoon: -------------------------------------------------------------------------------- 1 | :: Format issue to yaml 2 | :: 3 | :::: /===/gen/taskk/yaml/hoon 4 | :: 5 | /? 310 6 | :- %say 7 | |= {^ {aut/tape ass/tape tit/tape des/tape $~} $~} 8 | :- %taskk 9 | %- crip 10 | """ 11 | --- 12 | author: {aut} 13 | assignee: {ass} 14 | title: {tit} 15 | --- 16 | {des} 17 | """ 18 | -------------------------------------------------------------------------------- /wip/gen/tumblr/feed.hoon: -------------------------------------------------------------------------------- 1 | :: Display tumblr feed 2 | :: 3 | :::: /===/gen/tumblr/feed/hoon 4 | :: 5 | /- tumblr 6 | !: 7 | :::: 8 | :: 9 | :- %say 10 | |= $: {now/@da eny/@uvJ bek/beak} 11 | {{who/@t $~} $~} 12 | == 13 | =/ pax %+ welp 14 | /(scot %p p.bek)/tumblr/(scot %da now) 15 | ?: =(who 'dashboard') 16 | /user/dashboard/tumblr-blog-posts 17 | /blog/[who]/posts/tumblr-blog-posts 18 | :- %tang 19 | %+ turn (flop .^((list post:tumblr) %gx pax)) 20 | |= a/post:tumblr ^- tank 21 | ?- -.a 22 | $photo-post :+ %rose 23 | [": " `~] 24 | :~ leaf+"PHOTO POST" 25 | leaf+"post url: {<(trip post-url.a)>}" 26 | leaf+"image url: {<(trip ->->+.photos.a)>}" 27 | == 28 | $video-post :+ %rose 29 | [": " `~] 30 | :~ leaf+"VIDEO POST" 31 | leaf+"post url: {<(trip post-url.a)>}" 32 | leaf+"video caption: {<(trip caption.a)>}" 33 | == 34 | $quote-post :+ %rose 35 | [": " `~] 36 | :~ leaf+"QUOTE POST" 37 | leaf+"post url: {<(trip post-url.a)>}" 38 | leaf+(trip text.a) 39 | leaf+(trip source.a) 40 | == 41 | $link-post :+ %rose 42 | [": " `~] 43 | :~ leaf+"LINK POST" 44 | leaf+"post url: {<(trip post-url.a)>}" 45 | leaf+(trip title.a) 46 | leaf+(trip url.a) 47 | == 48 | $text-post :+ %rose 49 | [": " `~] 50 | :~ leaf+"TEXT POST" 51 | leaf+"post url: {<(trip post-url.a)>}" 52 | leaf+(trip title.a) 53 | leaf+(trip body.a) 54 | == 55 | $def-post :+ %rose 56 | [": " `~] 57 | :~ leaf+"DEFAULT POST" 58 | leaf+"post url: {<(trip post-url.a)>}" 59 | == 60 | == 61 | -------------------------------------------------------------------------------- /wip/gen/weather.hoon: -------------------------------------------------------------------------------- 1 | :: Fetch the current weather from the Open Weather Map API 2 | :: 3 | :: Sign up for an API key here: https://home.openweathermap.org/users/sign_up 4 | :: Then run in the dojo with your city, country and API key: 5 | :: 6 | :: +weather "san+jose" "us" "YOUR_API_KEY_HERE" 7 | :: 8 | /- sole 9 | /+ generators 10 | =, generators 11 | :- %get 12 | |= [* [city=tape country=tape appid=tape ~] ~] 13 | ^- (sole-request:sole (cask tang)) 14 | =/ escaped-city (en-urlt:html city) 15 | =/ escaped-country (en-urlt:html country) 16 | %+ curl (scan "http://api.openweathermap.org/data/2.5/weather?q={escaped-city}%2C{escaped-country}&APPID={appid}" auri:de-purl:html) 17 | |= hit=httr:eyre 18 | ?~ r.hit !! 19 | =/ my-json (need (de-json:html q.u.r.hit)) 20 | =, dejs:format 21 | =/ my-map ((om same) my-json) 22 | =/ name ((ot 'name'^sa ~) my-json) 23 | =/ main (~(got by my-map) %main) 24 | =/ wind (~(got by my-map) %wind) 25 | =/ temp (trip ((ot 'temp'^no ~) main)) 26 | =/ speed (trip ((ot 'speed'^no ~) wind)) 27 | %+ produce %tang 28 | :~ leaf+"Wind speed: {speed} meters per second" 29 | leaf+"Temperature: {temp} degrees kelvin" 30 | leaf+"Results for {name}" 31 | == 32 | -------------------------------------------------------------------------------- /wip/hello/README.md: -------------------------------------------------------------------------------- 1 | # hello 2 | 3 | A Landscape tile that sends a hello with some JSON back to your Dojo. Copy /app into your ship, `|commit %home` and `|start %hello` to see your new tile in Landscape. 4 | 5 | ## Using Landscape 6 | 7 | You'll find Landscape running on http://localhost:PORT, PORT being 80, 8080, 8081, 8 | and so on, depending on your operating system's free ports; see your ship's boot message 9 | for a notification as to what port HTTP is available on. If you haven't used 10 | Landscape before, you'll need to enter `+code` on your ship to get the password 11 | to authenticate yourself with on the Landscape interface. 12 | See also the [Urbit documentation](https://urbit.org/docs/getting-started/booting-a-ship/#using-landscape) 13 | for more information. 14 | 15 | ## How 'hello' works 16 | 17 | The application is started with `hello.hoon` in the [/app](app) folder on your ship. 18 | It tells eyre, the HTTP vane of Arvo, where it's located, and the `launch` and `modulo` 19 | applications to subscribe to it and present it as a tile in Landscape. Landscape provides 20 | access to your ship with an `api` window object. 21 | 22 | The 'hello' [tile.js](src/tile/tile.js), mounted in Landscape as part of the application, 23 | uses that api window object to poke the running hello application, which, when it receives 24 | a poke with JSON, prints it to the Dojo. 25 | 26 | For the poke handler's code, see [here](app/hello.hoon#L54). 27 | 28 | ## Playing with 'hello' 29 | 30 | Landscape tiles also use the [React](https://reactjs.org/) framework and require 31 | compilation if you want to change them -- find their source in the /src folder, 32 | `npm install` their dependencies, change the Urbit ship location in the `.urbitrc` file to your ship location, and `npm run serve`. -------------------------------------------------------------------------------- /wip/hello/app/hello.hoon: -------------------------------------------------------------------------------- 1 | /+ *server 2 | /= tile-js 3 | /^ octs 4 | /; as-octs:mimes:html 5 | /: /===/app/hello/js/tile 6 | /| /js/ 7 | /~ ~ 8 | == 9 | =, format 10 | |% 11 | :: 12 | +$ effect (pair bone syscall) 13 | :: 14 | +$ poke 15 | $% [%launch-action [@tas path @t]] 16 | == 17 | :: 18 | +$ syscall 19 | $% [%poke wire dock poke] 20 | [%http-response =http-event:http] 21 | [%connect wire binding:eyre term] 22 | [%diff %json json] 23 | == 24 | :: 25 | -- 26 | :: 27 | |_ [bol=bowl:gall ~] 28 | :: "this" is a shorthand for returning the state. 29 | ++ this . 30 | :: 31 | ++ bound 32 | |= [wir=wire success=? binding=binding:eyre] 33 | ^- (quip effect _+>.$) 34 | [~ +>.$] 35 | :: 36 | ++ prep 37 | |= old=(unit ~) 38 | ^- (quip effect _this) 39 | =/ launcha 40 | [%launch-action [%hello /hellotile '/~hello/js/tile.js']] 41 | :_ this 42 | :~ 43 | [ost.bol %connect / [~ /'~hello'] %hello] 44 | [ost.bol %poke /hello [our.bol %launch] launcha] 45 | == 46 | :: 47 | :: 48 | ++ peer-hellotile 49 | |= pax=path 50 | ^- (quip effect _this) 51 | [[ost.bol %diff %json *json]~ this] 52 | :: 53 | :: 54 | ++ poke-json 55 | |= jon=json 56 | ^- (quip effect _+>.$) 57 | ~& 'Hello received from the Landscape interface!' 58 | ~& jon 59 | :_ +>.$ 60 | %+ turn (prey:pubsub:userlib /testingtile bol) 61 | |= [=bone ^] 62 | [bone %diff %json jon] 63 | :: 64 | ++ send-tile-diff 65 | |= jon=json 66 | ^- (list effect) 67 | %+ turn (prey:pubsub:userlib /hellotile bol) 68 | |= [=bone ^] 69 | [bone %diff %json jon] 70 | :: 71 | ++ poke-handle-http-request 72 | %- (require-authorization:app ost.bol effect this) 73 | |= =inbound-request:eyre 74 | ^- (quip effect _this) 75 | =/ request-line (parse-request-line url.request.inbound-request) 76 | =/ back-path (flop site.request-line) 77 | =/ name=@t 78 | =/ back-path (flop site.request-line) 79 | ?~ back-path 80 | '' 81 | i.back-path 82 | :: 83 | ?~ back-path 84 | [[ost.bol %http-response not-found:app]~ this] 85 | ?: =(name 'tile') 86 | [[ost.bol %http-response (js-response:app tile-js)]~ this] 87 | [[ost.bol %http-response not-found:app]~ this] 88 | :: 89 | -- 90 | -------------------------------------------------------------------------------- /wip/hello/src/.urbitrc: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | URBIT_PIERS: [ 3 | "/Users/you/urbit/zod/home", 4 | ] 5 | }; 6 | -------------------------------------------------------------------------------- /wip/hello/src/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var rollup = require('gulp-better-rollup'); 3 | var sucrase = require('@sucrase/gulp-plugin'); 4 | var minify = require('gulp-minify'); 5 | 6 | var resolve = require('rollup-plugin-node-resolve'); 7 | var commonjs = require('rollup-plugin-commonjs'); 8 | var rootImport = require('rollup-plugin-root-import'); 9 | var globals = require('rollup-plugin-node-globals'); 10 | 11 | /*** 12 | Main config options 13 | ***/ 14 | 15 | var urbitrc = require('./.urbitrc'); 16 | 17 | /*** 18 | End main config options 19 | ***/ 20 | 21 | gulp.task('tile-jsx-transform', function(cb) { 22 | return gulp.src('tile/**/*.js') 23 | .pipe(sucrase({ 24 | transforms: ['jsx'] 25 | })) 26 | .pipe(gulp.dest('dist')); 27 | }); 28 | 29 | 30 | gulp.task('tile-js-imports', function(cb) { 31 | return gulp.src('dist/tile.js') 32 | .pipe(rollup({ 33 | plugins: [ 34 | commonjs({ 35 | namedExports: { 36 | 'node_modules/react/index.js': [ 'Component' ], 37 | } 38 | }), 39 | rootImport({ 40 | root: `${__dirname}/dist/js`, 41 | useEntry: 'prepend', 42 | extensions: '.js' 43 | }), 44 | globals(), 45 | resolve() 46 | ] 47 | }, 'umd')) 48 | .on('error', function(e){ 49 | console.log(e); 50 | cb(); 51 | }) 52 | .pipe(gulp.dest('./urbit/app/hello/js/')) 53 | .on('end', cb); 54 | }); 55 | 56 | gulp.task('tile-js-minify', function () { 57 | return gulp.src('./urbit/app/hello/js/tile.js') 58 | .pipe(minify()) 59 | .pipe(gulp.dest('./urbit/app/hello/js/')); 60 | }); 61 | 62 | gulp.task('urbit-copy', function () { 63 | let ret = gulp.src('urbit/**/*'); 64 | 65 | urbitrc.URBIT_PIERS.forEach(function(pier) { 66 | ret = ret.pipe(gulp.dest(pier)); 67 | }); 68 | 69 | return ret; 70 | }); 71 | 72 | gulp.task('tile-js-bundle-dev', gulp.series('tile-jsx-transform', 'tile-js-imports')); 73 | gulp.task('tile-js-bundle-prod', 74 | gulp.series('tile-jsx-transform', 'tile-js-imports', 'tile-js-minify')); 75 | 76 | gulp.task('bundle-prod', gulp.series('tile-js-bundle-prod', 'urbit-copy')); 77 | 78 | gulp.task('default', gulp.series('tile-js-bundle-dev', 'urbit-copy')); 79 | gulp.task('watch', gulp.series('default', function() { 80 | gulp.watch('tile/**/*.js', gulp.parallel('tile-js-bundle-dev')); 81 | gulp.watch('urbit/**/*', gulp.parallel('urbit-copy')); 82 | })); 83 | -------------------------------------------------------------------------------- /wip/hello/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-landscape-app", 3 | "version": "0.2.2", 4 | "description": "Get started with a Landscape application.", 5 | "main": "node install.js", 6 | "scripts": { 7 | "start": "node install.js", 8 | "build": "gulp", 9 | "serve": "gulp watch" 10 | }, 11 | "author": "Tlon Corp", 12 | "license": "MIT", 13 | "repository": "https://github.com/urbit/create-landscape-app", 14 | "devDependencies": { 15 | "@sucrase/gulp-plugin": "^2.0.0", 16 | "cssnano": "^4.1.10", 17 | "gulp": "^4.0.0", 18 | "gulp-better-rollup": "^4.0.1", 19 | "gulp-cssimport": "^7.0.0", 20 | "gulp-minify": "^3.1.0", 21 | "gulp-postcss": "^8.0.0", 22 | "rollup": "^1.6.0", 23 | "rollup-plugin-commonjs": "^9.2.0", 24 | "rollup-plugin-node-globals": "^1.4.0", 25 | "rollup-plugin-node-resolve": "^4.0.0", 26 | "rollup-plugin-root-import": "^0.2.3", 27 | "sucrase": "^3.8.0" 28 | }, 29 | "dependencies": { 30 | "classnames": "^2.2.6", 31 | "fs-extra": "^8.1.0", 32 | "lodash": "^4.17.11", 33 | "moment": "^2.20.1", 34 | "mousetrap": "^1.6.3", 35 | "mv": "^2.1.1", 36 | "promise": "^8.0.3", 37 | "prompt": "^1.0.0", 38 | "react": "^16.5.2", 39 | "react-dom": "^16.8.6", 40 | "react-router-dom": "^5.0.0", 41 | "replace-in-file": "^4.1.1", 42 | "urbit-ob": "^3.1.1" 43 | }, 44 | "resolutions": { 45 | "natives": "1.1.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /wip/hello/src/tile/tile.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classnames from 'classnames'; 3 | import _ from 'lodash'; 4 | 5 | 6 | export default class helloTile extends Component { 7 | constructor(props) { 8 | super(props); 9 | let ship = window.ship; 10 | let api = window.api; 11 | } 12 | 13 | pokeShip() { 14 | api.action('hello', 'json', {JSONkey: "JSONvalue"}); 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 |

Hello

21 | this.pokeShip()}>Say hello. 22 |
23 | ); 24 | } 25 | 26 | } 27 | 28 | window.helloTile = helloTile; 29 | -------------------------------------------------------------------------------- /wip/hello/src/urbit/app/hello.hoon: -------------------------------------------------------------------------------- 1 | /+ *server 2 | /= tile-js 3 | /^ octs 4 | /; as-octs:mimes:html 5 | /: /===/app/hello/js/tile 6 | /| /js/ 7 | /~ ~ 8 | == 9 | =, format 10 | |% 11 | :: 12 | +$ effect (pair bone syscall) 13 | :: 14 | +$ poke 15 | $% [%launch-action [@tas path @t]] 16 | == 17 | :: 18 | +$ syscall 19 | $% [%poke wire dock poke] 20 | [%http-response =http-event:http] 21 | [%connect wire binding:eyre term] 22 | [%diff %json json] 23 | == 24 | :: 25 | -- 26 | :: 27 | |_ [bol=bowl:gall ~] 28 | :: "this" is a shorthand for returning the state. 29 | ++ this . 30 | :: 31 | ++ bound 32 | |= [wir=wire success=? binding=binding:eyre] 33 | ^- (quip effect _+>.$) 34 | [~ +>.$] 35 | :: 36 | ++ prep 37 | |= old=(unit ~) 38 | ^- (quip effect _this) 39 | =/ launcha 40 | [%launch-action [%hello /hellotile '/~hello/js/tile.js']] 41 | :_ this 42 | :~ 43 | [ost.bol %connect / [~ /'~hello'] %hello] 44 | [ost.bol %poke /hello [our.bol %launch] launcha] 45 | == 46 | :: 47 | :: 48 | ++ peer-hellotile 49 | |= pax=path 50 | ^- (quip effect _this) 51 | [[ost.bol %diff %json *json]~ this] 52 | :: 53 | :: 54 | ++ poke-json 55 | |= jon=json 56 | ^- (quip effect _+>.$) 57 | ~& 'Hello received from the Landscape interface!' 58 | ~& jon 59 | :_ +>.$ 60 | %+ turn (prey:pubsub:userlib /testingtile bol) 61 | |= [=bone ^] 62 | [bone %diff %json jon] 63 | :: 64 | ++ send-tile-diff 65 | |= jon=json 66 | ^- (list effect) 67 | %+ turn (prey:pubsub:userlib /hellotile bol) 68 | |= [=bone ^] 69 | [bone %diff %json jon] 70 | :: 71 | ++ poke-handle-http-request 72 | %- (require-authorization:app ost.bol effect this) 73 | |= =inbound-request:eyre 74 | ^- (quip effect _this) 75 | =/ request-line (parse-request-line url.request.inbound-request) 76 | =/ back-path (flop site.request-line) 77 | =/ name=@t 78 | =/ back-path (flop site.request-line) 79 | ?~ back-path 80 | '' 81 | i.back-path 82 | :: 83 | ?~ back-path 84 | [[ost.bol %http-response not-found:app]~ this] 85 | ?: =(name 'tile') 86 | [[ost.bol %http-response (js-response:app tile-js)]~ this] 87 | [[ost.bol %http-response not-found:app]~ this] 88 | :: 89 | -- 90 | -------------------------------------------------------------------------------- /wip/lib/blockio.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/blockio/lib 3 | :: 4 | /- blockio 5 | [. ^blockio] 6 | |% 7 | ++ net-cur ::< network to currency 8 | |= net/tape 9 | ^- currency 10 | ?: =(net "BTC") %btc 11 | ?: =(net "LTC") %ltc 12 | ?: =(net "DOGE") %doge 13 | ?: =(net "BTCTEST") %btc-test 14 | ?: =(net "LTCTEST") %ltc-test 15 | ?: =(net "DOGETEST") %doge-test 16 | ~&([%strange-net net] !!) 17 | :: 18 | ++ cur-net 19 | |= cur/currency 20 | ^- tape 21 | ?- cur 22 | $btc "BTC" 23 | $ltc "LTC" 24 | $doge "DOGE" 25 | $btc-test "BTCTEST" 26 | $ltc-test "LTCTEST" 27 | $doge-test "DOGETEST" 28 | == 29 | -- 30 | -------------------------------------------------------------------------------- /wip/lib/jumblr.hoon: -------------------------------------------------------------------------------- 1 | :: Convert Tumblr sur to json 2 | :: 3 | :::: /===/lib/jumblr/hoon 4 | :: 5 | /- tumblr 6 | |% 7 | ++ jrip 8 | |= a/@t 9 | ^- json 10 | (jape (trip a)) 11 | ++ jlay 12 | |= a/{width/@u embed-code/@t} 13 | ^- json 14 | (jobe width+(jone width.a) embed-code+(jrip embed-code.a) ~) 15 | ++ joto 16 | |= a/photo:tumblr 17 | ^- json 18 | %- jobe 19 | =* osa original-size.a 20 | =* asa alt-sizes.a 21 | :~ caption+(jrip caption.a) 22 | :- %original-size 23 | %- jobe 24 | :~ width+(jone width.osa) 25 | height+(jone height.osa) 26 | url+(jrip url.osa) 27 | == 28 | :- %alt-sizes 29 | :- %a 30 | %+ turn 31 | asa 32 | |= b/photo-size:tumblr 33 | %- jobe 34 | :~ width+(jone width.b) 35 | height+(jone height.b) 36 | url+(jrip url.b) 37 | == 38 | == 39 | ++ jost 40 | |= bp/post:tumblr 41 | ^- json 42 | ?- -.bp 43 | $photo-post %- jobe 44 | :~ blog-name+(jrip blog-name.bp) 45 | id+(jone id.bp) 46 | post-url+(jrip post-url.bp) 47 | type+(jrip type.bp) 48 | date+(jrip date.bp) 49 | timestamp+(jone timestamp.bp) 50 | format+(jrip format.bp) 51 | caption+(jrip caption.bp) 52 | :- %tags 53 | a+(turn tags.bp |=(a/@t (jrip a))) 54 | :- %photos 55 | a+(turn photos.bp joto) 56 | == 57 | $video-post %- jobe 58 | :~ blog-name+(jrip blog-name.bp) 59 | id+(jone id.bp) 60 | post-url+(jrip post-url.bp) 61 | type+(jrip type.bp) 62 | date+(jrip date.bp) 63 | timestamp+(jone timestamp.bp) 64 | format+(jrip format.bp) 65 | caption+(jrip caption.bp) 66 | :- %tags 67 | a+(turn tags.bp |=(a/@t (jrip a))) 68 | :- %player 69 | a+(turn player.bp jlay) 70 | == 71 | $quote-post %- jobe 72 | :~ blog-name+(jrip blog-name.bp) 73 | id+(jone id.bp) 74 | post-url+(jrip post-url.bp) 75 | type+(jrip type.bp) 76 | date+(jrip date.bp) 77 | timestamp+(jone timestamp.bp) 78 | source-url+(jrip source-url.bp) 79 | source-title+(jrip source-title.bp) 80 | text+(jrip text.bp) 81 | source+(jrip source.bp) 82 | :- %tags 83 | a+(turn tags.bp |=(a/@t (jrip a))) 84 | == 85 | $text-post %- jobe 86 | :~ blog-name+(jrip blog-name.bp) 87 | id+(jone id.bp) 88 | post-url+(jrip post-url.bp) 89 | type+(jrip type.bp) 90 | date+(jrip date.bp) 91 | timestamp+(jone timestamp.bp) 92 | format+(jrip format.bp) 93 | title+(jrip title.bp) 94 | body+(jrip body.bp) 95 | :- %tags 96 | a+(turn tags.bp |=(a/@t (jrip a))) 97 | == 98 | $link-post %- jobe 99 | :~ blog-name+(jrip blog-name.bp) 100 | id+(jone id.bp) 101 | post-url+(jrip post-url.bp) 102 | type+(jrip type.bp) 103 | date+(jrip date.bp) 104 | timestamp+(jone timestamp.bp) 105 | format+(jrip format.bp) 106 | title+(jrip title.bp) 107 | url+(jrip url.bp) 108 | :- %photos 109 | a+(turn photos.bp joto) 110 | :- %tags 111 | a+(turn tags.bp |=(a/@t (jrip a))) 112 | == 113 | $def-post %- jobe 114 | :~ blog-name+(jrip blog-name.bp) 115 | id+(jone id.bp) 116 | post-url+(jrip post-url.bp) 117 | type+(jrip type.bp) 118 | date+(jrip date.bp) 119 | timestamp+(jone timestamp.bp) 120 | format+(jrip format.bp) 121 | :- %tags 122 | a+(turn tags.bp |=(a/@t (jrip a))) 123 | == 124 | == 125 | -- 126 | -------------------------------------------------------------------------------- /wip/lib/lisp99.hoon: -------------------------------------------------------------------------------- 1 | :: "99 lisp problems" http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html 2 | :: arms accessible in dojo after `/+ lisp99` (two spaces (`gap`) in between) 3 | :: try `test:lisp99` 4 | :: 5 | :::: /===/lib/lisp99/hoon 6 | :: 7 | !: 8 | :: 9 | |% += s-expr (list ?(s-expr term)) 10 | -- 11 | |% 12 | ++ test 13 | :* (p01 "abcd") (p02 "abcd") (p03 "abcde" 3) (p04 "abc") 14 | (p05 "sdrawkcab") (p06 "godsdog") (p07 ~["ab" %c "d"] "ef" ~["g"] ~) 15 | (p08 "aaaabccaadeeee") (p09 "aaaabccaadeeee") (p10 "aaaabccaadeeee") 16 | == 17 | ++ p01 last-cell 18 | ++ last-cell 19 | |=(a=s-expr ?~(+.a a $(a +.a))) 20 | :: 21 | ++ p02 but-last-cell 22 | ++ but-last-cell :: broken for the moment 23 | |=(a=s-expr =+(|2.a ?~(- a $(a +.a)))) 24 | :: 25 | ++ p03 element-at 26 | ++ element-at 27 | |=([a=s-expr k=@u] ?:(=(1 k) -.a $(a +.a, k (dec k)))) 28 | :: 29 | ++ p04 length 30 | ++ length 31 | |=(a=s-expr ?~(a 0 +($(a t.a)))) 32 | :: 33 | ++ p05 reverse 34 | ++ reverse 35 | |=(a=s-expr =|(b=s-expr |-(?~(a b $(a +.a, b [-.a b]))))) 36 | :: 37 | ++ p06 palinodrome-p 38 | ++ palinodrome-p 39 | |=(a=s-expr =(a (reverse a))) 40 | :: 41 | ++ p07 flatten 42 | ++ flatten 43 | |= a=s-expr ^+ a 44 | ?~ a ~ 45 | ?~ i.a t.a 46 | ?@ i.a [i.a $(a t.a)] 47 | (weld $(a i.a) $(a t.a)) 48 | :: 49 | ++ p08 compress 50 | ++ compress 51 | |= a=s-expr 52 | ?~ a ~ 53 | |- ^- s-expr 54 | ?~ t.a a 55 | ?: =(i.a i.t.a) 56 | $(t.a t.t.a) 57 | [i.a $(a t.a)] 58 | :: 59 | ++ p09 pack 60 | ++ pack 61 | |= a=s-expr ^- s-expr 62 | ?~ a ~ 63 | |- ^- [i=s-expr t=s-expr] 64 | ?~ t.a [a]~ 65 | ?: =(i.a i.t.a) 66 | [[-.i i] t]:$(a t.a) 67 | [[i.a]~ $(a t.a)] 68 | :: 69 | ++ p10 encode 70 | ++ encode 71 | |= a=s-expr 72 | ?~ a ~ 73 | |- ^- (list [@u ?(s-expr term)]) 74 | ?~ t.a [1 i.a]~ 75 | ?: =(i.a i.t.a) 76 | [[+(-) +]:- +]:$(a t.a) 77 | [[1 i.a] $(a t.a)] 78 | -- 79 | -------------------------------------------------------------------------------- /wip/lib/parse-sexpr.hoon: -------------------------------------------------------------------------------- 1 | :: Simple library for parsing s-expressions 2 | :: 3 | :: arms accessible in dojo after `/+ parse-sexpr` (two spaces (`gap`) in between) 4 | :: try `test:parse-sexpr` 5 | :: 6 | :::: /===/lib/parse-sexpr/hoon 7 | :: 8 | !: 9 | :: 10 | |% 11 | :: A symbolic expression is either a symbol or more s-exprs. 12 | :: Symbols are stored as terms, Hoon constants. 13 | += s-expr (list $@(term [$~ p=s-expr])) 14 | :: Whitespace between s-exprs can be (zero or more) spaces and newlines. 15 | ++ whitespace (star (mask " \0a")) 16 | :: An s-expr is either a symbol (term) or more s-exprs. 17 | ++ element ;~(pose sym (stag ~ toplevel)) 18 | :: Parses s-exprs. 19 | ++ toplevel 20 | :: Recursive parser, output should fit our mold. 21 | %+ knee *s-expr 22 | :: Caches parser to prevent recreation during recursion. 23 | |. ~+ 24 | :: Parse elements, separated by whitespace, surrounded by ( and ). 25 | %+ ifix [pel per] 26 | (more whitespace element) 27 | :: 28 | ++ test (scan """ 29 | (a 30 | b 31 | (c (d e) f) 32 | g) 33 | """ toplevel) 34 | -- 35 | -------------------------------------------------------------------------------- /wip/lib/ski.hoon: -------------------------------------------------------------------------------- 1 | :: SKI calculus to Nock compiler 2 | :: 3 | :: arms accessible in dojo after `/+ ski` (two spaces (`gap`) in between) 4 | :: try `test:ski` 5 | :: 6 | :::: /===/lib/ski/hoon 7 | :: 8 | !: 9 | :: 10 | =< apex 11 | |% 12 | ++ apex |=(a=tape (compile (scan a ski-rule))) 13 | += skis (list ?($s $k $i skis)) 14 | ++ whit (star ;~(pose ace (just '\0a'))) 15 | ++ ski-rule 16 | %+ knee *skis |. ~+ 17 | %+ ifix [whit whit] 18 | %+ more whit 19 | ;~ pose 20 | (cold %s (mask "sS")) 21 | (cold %k (mask "kK")) 22 | (cold %i (mask "iI")) 23 | (ifix pel^per ski-rule) 24 | :: 25 | :: %+ cook |=(a=skis k+[a]~) 26 | :: (ifix sel^ser ski-rule) 27 | == 28 | :: 29 | ++ compile 30 | |= a=skis ^- nock 31 | =. a (flop a) 32 | ?~ a $(a [%i]~) 33 | |- ^- nock 34 | =/ tal 35 | ?- i.a 36 | $s [[%1 [%1 2]] [%1 [%0 1]] [[%1 1] [%0 1]]] 37 | $k [[%1 1] [%0 1]] 38 | $i [%0 1] 39 | * ^$(a i.a) 40 | == 41 | ?~ t.a tal 42 | [%2 [%0 1] %2 [%1 tal] [%1 $(a t.a)]] 43 | -- 44 | |% 45 | ++ test .*([1 42] .*(7 (ski "S (K(SI)) K"))) :: (\x.\y. yx) 7 (\x.42) 46 | -- 47 | :: i [0 1] 48 | :: k [[1 1] [0 1]] 49 | :: s [[1 1 2] [1 0 1] [[1 1] [0 1]]] 50 | :: : [2 [0 1] 2 [1 +] [1 -]] :: .*(. .*(%r %l)) 51 | 52 | 53 | :: so (sxy) becomes \z.(((s x) y) z) becomes .*(z .*(y .*(x s))) 54 | :: i.e. [2 [0 1] 2 [1 y] [1 2 [1 x] [1 s]]] 55 | 56 | :: [2 `1 2 57 | :: |+[2 `1 2 [2 `1 2 |+i |+[2 |+i |+S]]] 58 | :: |+[2 `1 2 [2 `1 2 |+i |+[2 |+i |+S]]] 59 | :: ] 60 | :: (((S I) I) ((S I) I)) 61 | :: SII(SII) 62 | 63 | :: \x. [\y [2 y X]] 64 | :: [\y [2 y X]] 65 | :: [[1 2] [0 1] [1 X]] 66 | 67 | :: [[1 1 2] [1 0 1] [[1 1] [0 1]]] 68 | :: [\x [\y [2 y x]]] 69 | 70 | :: \ 71 | :: .*(.*(z y) .*(z x)) 72 | :: ((x z) (y z)) 73 | 74 | :: ((f x) y) 75 | 76 | :: .*(y .*(x f)) 77 | 78 | :: \xy. foo 79 | :: [[1 2] [[1 0 1] [1 1] [0 1]] 1 1 ...] 80 | :: -> [2 [[0 1] [1 x]] 1 ...] 81 | :: -> .*([y x] ...) 82 | -------------------------------------------------------------------------------- /wip/lib/sorts.hoon: -------------------------------------------------------------------------------- 1 | :: Simple library of basic sorting CS algorithms 2 | :: 3 | :: arms accessible in dojo after `/+ sorts` (two spaces (`gap`) in between) 4 | :: try `test:sorts` 5 | :: 6 | :::: /===/lib=sorts/hoon 7 | :: 8 | !: 9 | :: 10 | |% 11 | ++ test 12 | |= * 13 | =/ a=(list @u) ~[5 2 3 8 1 13 1] 14 | :* insertion-sort+(insertion-sort a) 15 | bubble-sort+(bubble-sort a) 16 | merge-sort+(merge-sort a) 17 | == 18 | :: 19 | ++ insertion-sort 20 | |= a=(list @u) :: gate, list of numbers 21 | =/ b=(list @u) ~ :: var, b = empty list. 22 | |- ^- (list @u) :: loop, prod. list nums 23 | ?~ a b :: ifno a (~), produce b 24 | %= $ :: else, call loop: 25 | a t.a :: a->tail a (~ if none) 26 | b |- ^- (list @u) :: b->loop prod, list @s 27 | ?~ b [i.a ~] :: ifno b, prod. head a. 28 | ?: (lth i.a i.b) :: else,if head-aloop, list of nums 42 | ?~ a ~ :: disambiguates a 43 | ?~ t.a [i.a ~] :: disambiguates t.a 44 | ?: =(+(c) s) :: rest sorted if +(c)=s 45 | a :: so produce a. 46 | ?: (gth i.a i.t.a) :: else, if head greater 47 | [i.t.a $(a [i.a t.t.a], c +(c))] :: swap, loop w tail,c+1 48 | [i.a $(a t.a, c +(c))] :: else prod. head, loop 49 | s (dec s) :: s - > dec s, s - 1. 50 | == 51 | :: 52 | ++ merge-sort 53 | |= a=(list @u) :: gate, list of numbers 54 | ?: (lth (lent a) 2) :: if <2 elems, "sorted" 55 | a :: so produce a. 56 | =+ mid=(div (lent a) 2) :: else pin mid->lenta/2 57 | %- merge :: call merge 58 | :- (merge-sort (scag mid a)) :: with cons-cell l list 59 | (merge-sort (slag mid a)) :: and right list. 60 | :: 61 | ++ merge 62 | |= [l=(list @u) r=(list @u)] :: gate, two lists= nums 63 | =| merged=(list @u) :: newvar merged,set l8r 64 | |- ^- (list @u) :: loop, prod. list nums 65 | ?. |(?=($~ l) ?=($~ r)) :: unless l or r are nil 66 | ?: (gth i.l i.r) :: if l head > r head, 67 | $(merged [i.r merged], r t.r) :: call loop with <-. 68 | $(merged [i.l merged], l t.l) :: else, call loop w/ <- 69 | ?^ l :: if left is a cell, 70 | $(merged [i.l merged], l t.l) :: call loop with <-. 71 | ?^ r :: else, if r is a cell, 72 | $(merged [i.r merged], r t.r) :: call loop with <-. 73 | (flop merged) :: else prod mrgd revrsd 74 | :: 75 | -- 76 | -------------------------------------------------------------------------------- /wip/lib/strings-kmp.hoon: -------------------------------------------------------------------------------- 1 | :: Knuth-Morris-Pratt string search 2 | :: 3 | :: arms accessible in dojo after `/+ strings-kmp` (two spaces (`gap`) in between) 4 | :: try `test:strings-kmp` 5 | :: 6 | :::: /===/lib/strings-kmp/hoon 7 | :: 8 | !: 9 | :: 10 | |% 11 | ++ test 12 | =+ a==+([a="a" b=15] |-(?~(b (weld a "b") $(a (weld a a), b (dec b))))) 13 | =+ b="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ipsum, ipsum ipsum." 14 | [(kmp "aaaaaaab" a) (kmp "ipsum" b)] 15 | :: 16 | ++ kmp 17 | |= [ptn=tape txt=tape] 18 | (skm ptn (gnx ptn) txt) 19 | :: 20 | ++ skm 21 | |= [ptn=tape nxt=(list @sd) txt=tape] 22 | =| [i=@sd j=@ud] 23 | =| fnd=(list @ud) :: indices of pattern in text 24 | =+ len=(lent txt) 25 | ^- (list @ud) |- 26 | ?~ txt (flop fnd) 27 | =+ ^= k 28 | |- ?. |(=(i -1) =((snag (abs:si i) ptn) -.txt)) 29 | $(i (snag (abs:si i) nxt)) 30 | (abs:si (sum:si i --1)) 31 | ?: (gte k (lent ptn)) 32 | $(i (snag k nxt), j +(j), txt +.txt, fnd [(sub +(j) k) fnd]) 33 | $(i (sun:si k), j +(j), txt +.txt) 34 | :: 35 | ++ gnx :: generate next table 36 | |= ptn=tape 37 | =+ nxt=`(list @sd)`[-1 ~] 38 | =+ [i=-1 j=0] 39 | ^- (list @sd) |- 40 | ?. (lth j (lent ptn)) nxt 41 | =+ ^= k 42 | |- ?. |(=(i -1) =((snag j ptn) (snag (abs:si i) ptn))) 43 | $(i (snag (abs:si i) nxt)) 44 | (abs:si (sum:si i --1)) 45 | ?: &(!=(+(j) (lent ptn)) =((snag +(j) ptn) (snag k ptn))) 46 | $(i (sun:si k), j +(j), nxt (weld nxt (limo (snag k nxt) ~))) 47 | $(i (sun:si k), j +(j), nxt (weld nxt (limo (sun:si k) ~))) 48 | -- 49 | -------------------------------------------------------------------------------- /wip/lib/strings-piglatin.hoon: -------------------------------------------------------------------------------- 1 | :: Simple library for string manipulation to Pig Latin 2 | :: 3 | :: arms accessible in dojo after `/+ strings-piglatin` (two spaces (`gap`) in between) 4 | :: try `test:strings-piglatin` 5 | :: ++pigl turns a single string to piglatin 6 | :: ++plur pluralizes a word 7 | :: 8 | :::: /===/lib/strings-piglatin/hoon 9 | :: 10 | /? 314 11 | :: 12 | !: 13 | :: 14 | |% :: core 15 | ++ test (pigl (plur "what")) :: test:strin 16 | ++ pigl :: pig latin ++arm 17 | |= wrd=(list @t) :: gate, str sample 18 | ^- tape :: check rslt is tape 19 | ?~ wrd :: if null 20 | ~&('please enter an input' ~) :: then 21 | =+ :~ vwl=['a' 'e' 'i' 'o' 'u' ~] end="ay" :: else tuple of vars 22 | fst=i.wrd :: head of list wrd 23 | snd=t.wrd :: tail 24 | == :: close tuple 25 | ?: ?|(=(fst 'a') =(fst 'e') =(fst 'i') =(fst 'o') =(fst 'u')) 26 | (weld wrd end) 27 | (welp snd [fst end]) 28 | 29 | ++ plur :: pluralize 30 | |= wrd=tape :: gate, tape sample 31 | =+ idx=(dec (lent wrd)) 32 | =+ lst=`char`(snag idx wrd) 33 | =+ slast=(dec idx) 34 | ?- lst :: switch (on tile) 35 | $s ?: =((snag slast wrd) 'u') 36 | (welp (scag slast wrd) "i") 37 | (welp wrd "es") 38 | $e (welp wrd "s") 39 | $x (welp wrd "es") 40 | $y (welp (scag idx wrd) "ies") 41 | @ (welp wrd "s") 42 | == 43 | -- 44 | -------------------------------------------------------------------------------- /wip/mar/blockio/balance.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/balance/blockio/mar 3 | :: 4 | /- blockio 5 | /+ blockio, httr-to-json 6 | [. blockio] 7 | |_ bal/(each balance error) 8 | :: 9 | ++ grab ::> convert to balance 10 | |% 11 | ++ noun &+balance ::< ...from noun 12 | :: 13 | ++ httr (cork httr-to-json json) ::< ...from http result 14 | :: 15 | ++ json ::> ...from json 16 | => [jo .] 17 | |= jon/json 18 | ^- (each balance error) 19 | =+ (need ((ot data+(om sa) ~) jon)) 20 | ?: (~(has by -) 'error_message') 21 | |+(~(got by -) 'error_message') 22 | :- %& 23 | :+ (net-cur (~(got by -) 'network')) 24 | (~(got by -) 'available_balance') 25 | (~(got by -) 'pending_received_balance') 26 | -- 27 | -- 28 | -------------------------------------------------------------------------------- /wip/mar/blockio/withdraw.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/withdraw/blockio/mar 3 | :: 4 | /- blockio 5 | /+ blockio, httr-to-json 6 | [. blockio] 7 | |_ wil/(each withdrawal error) 8 | :: 9 | ++ grab ::> convert to balance 10 | |% 11 | ++ noun &+withdrawal ::< ...from noun 12 | :: 13 | ++ httr ::< ...from http result 14 | |= hit/^httr 15 | ::NOTE because httr-to-json errors if not status 2xx. 16 | (json (httr-to-json hit(p 200))) 17 | :: 18 | ++ json ::> ...from json 19 | => [jo .] 20 | |= jon/json 21 | ^- (each withdrawal error) 22 | =+ ((ot data+(om sa) ~) jon) 23 | ?~ - :: if parsing failed, assume local signing is demanded. 24 | |+"Block.io pin not set! Required for transactions. `pin [your-secret]`" 25 | =+ (need -) 26 | ?: (~(has by -) 'error_message') 27 | |+(~(got by -) 'error_message') 28 | :- %& 29 | :* (net-cur (~(got by -) 'network')) 30 | (~(got by -) 'txid') 31 | (~(got by -) 'amount_withdrawn') 32 | (~(got by -) 'amount_sent') 33 | (~(got by -) 'network_fee') 34 | (~(got by -) 'blockio_fee') 35 | == 36 | -- 37 | -- 38 | -------------------------------------------------------------------------------- /wip/mar/mail/message.hoon: -------------------------------------------------------------------------------- 1 | :: A mail message, defined in /sur/mail 2 | :: 3 | :::: /===/mar/mail/message/hoon 4 | :: 5 | /- mail-message 6 | !: 7 | |_ mail-message 8 | ++ grab 9 | |% 10 | += noun 11 | mail-message 12 | -- 13 | -- 14 | -------------------------------------------------------------------------------- /wip/mar/mail/send.hoon: -------------------------------------------------------------------------------- 1 | :: Required sample needed to send a mail-message 2 | :: 3 | :::: /===/mar/mail/send/hoon 4 | :: 5 | /- mail-send 6 | !: 7 | |_ mail-send 8 | ++ grab 9 | |% 10 | += noun 11 | mail-send 12 | ++ json 13 | |= jon/^json 14 | ^- mail-send 15 | %- need 16 | %. jon 17 | => dejs-soft:format 18 | (ot to+(ci (slat %p) so) sub+so bod+(cu to-wain:format so) ~) 19 | -- 20 | -- 21 | -------------------------------------------------------------------------------- /wip/mar/mesh/color.hoon: -------------------------------------------------------------------------------- 1 | :: The node color stored in :mesh's app state 2 | :: 3 | :::: /===/mar/mesh/color/hoon 4 | :: 5 | /- mesh 6 | [. mesh] 7 | :: 8 | !: 9 | |_ color 10 | ++ grab |% 11 | += noun color 12 | ++ json 13 | |= jon=^json ^- color 14 | (need (so:dejs-soft:format jon)) 15 | -- 16 | -- 17 | -------------------------------------------------------------------------------- /wip/mar/mesh/friend.hoon: -------------------------------------------------------------------------------- 1 | :: A friend 2 | :: 3 | :::: /===/mar/mesh/friend/hoon 4 | :: 5 | /- mesh 6 | [. mesh] 7 | :: 8 | !: 9 | |_ friend 10 | ++ grab |% 11 | += noun friend 12 | ++ json 13 | |= jon=^json ^- friend 14 | ~| [%bad-json jon] 15 | `@p`(slav %p (need (so:dejs-soft:format jon))) 16 | -- 17 | -- 18 | -------------------------------------------------------------------------------- /wip/mar/mesh/friends.hoon: -------------------------------------------------------------------------------- 1 | :: Your list of friends 2 | :: 3 | :::: /===/mar/mesh/friends/hoon 4 | :: 5 | /- mesh 6 | [. mesh] 7 | :: 8 | !: 9 | |_ [color friends] 10 | ++ grab |% 11 | += noun [color friends] 12 | -- 13 | -- 14 | -------------------------------------------------------------------------------- /wip/mar/mesh/network.hoon: -------------------------------------------------------------------------------- 1 | :: Your network of friends and friends-of-friends 2 | :: 3 | :::: /===/mar/mesh/network/hoon 4 | :: 5 | /- mesh 6 | [. mesh] 7 | :: 8 | !: 9 | |_ [col=color net=network] 10 | ++ grab |% 11 | += noun [color network] 12 | -- 13 | ++ grow 14 | |% 15 | ++ json 16 | (pairs:enjs:format col+[%s col] net+network-json ~) 17 | :: 18 | ++ network-json 19 | ::> push ++json:grow out of subject 20 | => + 21 | ^- json 22 | %- pairs:enjs:format ^- (list [@t json]) 23 | %+ turn ~(tap by net) 24 | |= [key=ship fes=friends] ^- [@t json] 25 | [(scot %p key) (friends-to-json fes)] 26 | -- 27 | ++ friends-to-json 28 | |= fes=friends 29 | %- pairs:enjs:format ^- (list [@t json]) 30 | %+ turn ~(tap in fes) 31 | |= [frnd=friend col=color] 32 | [(scot %p frnd) [%s col]] 33 | -- 34 | 35 | :: 36 | -------------------------------------------------------------------------------- /wip/mar/ping/message.hoon: -------------------------------------------------------------------------------- 1 | :: A message you ping another ship with 2 | :: 3 | :::: /===/mar/ping/message/hoon 4 | :: 5 | /- ping-message 6 | !: 7 | |_ ping-message 8 | ++ grab 9 | |% 10 | += noun 11 | ping-message 12 | -- 13 | -- 14 | -------------------------------------------------------------------------------- /wip/mar/taskk/change-phase.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/change-phase/taskk/mar 3 | /? 310 4 | /- taskk 5 | !: 6 | [taskk .] 7 | |_ iss/change-ref 8 | ++ grab 9 | |% 10 | ++ json 11 | |= jon/^json 12 | ^- issue 13 | %- need 14 | %. jon 15 | (ot issue+sa from-phase+sa to-phase host+sa board+sa ~):jo 16 | -- 17 | ++ grow 18 | |% 19 | ++ json 20 | %- jobe 21 | :~ [%issue (jape iss.iss)] 22 | [%from-phase (jape fpha.iss)] 23 | [%to-phase (jape tpha.iss)] 24 | [%hose (jape hos.iss)] 25 | [%board (jape boa.iss)] 26 | == 27 | -- 28 | -- 29 | -------------------------------------------------------------------------------- /wip/mar/taskk/create-issue.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/create-issue/taskk/mar 3 | /? 310 4 | /- taskk 5 | !: 6 | [taskk .] 7 | |_ iss/issue 8 | ++ grab 9 | |% 10 | ++ json 11 | |= jon/^json 12 | ^- issue 13 | %- need 14 | %. jon 15 | (ot phase+sa issue+sa description+sa ~):jo 16 | -- 17 | ++ grow 18 | |% 19 | ++ json 20 | %- jobe 21 | :~ [%phase (jape pha.iss)] 22 | [%issue (jape iss.iss)] 23 | [%description (jape des.iss)] 24 | == 25 | -- 26 | -- 27 | -------------------------------------------------------------------------------- /wip/mar/taskk/delete-issue.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/delete-issue/taskk/mar 3 | /? 310 4 | /- taskk 5 | !: 6 | [taskk .] 7 | |_ iss/issue-ref 8 | ++ grab 9 | |% 10 | ++ json 11 | |= jon/^json 12 | ^- issue 13 | %- need 14 | %. jon 15 | (ot phase+sa issue+sa ~):jo 16 | -- 17 | ++ grow 18 | |% 19 | ++ json 20 | %- jobe 21 | :~ [%phase (jape pha.iss)] 22 | [%issue (jape iss.iss)] 23 | == 24 | -- 25 | -- 26 | -------------------------------------------------------------------------------- /wip/mar/taskk/issue.hoon: -------------------------------------------------------------------------------- 1 | :::: /hoon/issue/taskk/mar 2 | :: 3 | :: 4 | :: 5 | /- taskk-phase 6 | :: 7 | |_ $: 8 | boa/@t :: board name 9 | tit/@t :: issue title 10 | des/@t :: issue description 11 | pha/taskk-phase 12 | aut/@p :: issue author 13 | ass/@p :: issue assignee 14 | == 15 | :: 16 | ++ grab :: convert from 17 | |% 18 | ++ noun {@t @t @t @ud @p @p} :: clam from %noun 19 | -- 20 | -- 21 | -------------------------------------------------------------------------------- /wip/mar/taskk/request-board.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/request-board/taskk/mar 3 | /? 310 4 | :: 5 | !: 6 | |_ board/{ho/tape bo/tape} 7 | ++ grab 8 | |% 9 | ++ json 10 | |= jon/^json 11 | ^- {ho/tape bo/tape} 12 | %- need 13 | %. jon 14 | (ot host+sa board+sa ~):jo 15 | -- 16 | -- 17 | -------------------------------------------------------------------------------- /wip/mar/tumblr/blog-post.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/blog-post/tumblr/mar 3 | :: 4 | :: 5 | /? 310 6 | /- tumblr 7 | /+ tumblr-parse, jumblr 8 | !: 9 | |_ bp/post:tumblr 10 | ++ grab 11 | |% 12 | ++ json 13 | |= jon/^json 14 | ^- post:tumblr 15 | %- need 16 | (post:tumblr-parse jon) 17 | ++ noun post:tumblr 18 | -- 19 | ++ grow 20 | |% 21 | ++ json 22 | (jost:jumblr bp) 23 | -- 24 | -- 25 | -------------------------------------------------------------------------------- /wip/mar/tumblr/blog-posts.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/blog-posts/tumblr/mar 3 | :: 4 | :: 5 | /? 310 6 | /- tumblr 7 | /+ tumblr-parse, jumblr 8 | !: 9 | |_ bp/(list post:tumblr) 10 | ++ grab 11 | |% 12 | ++ json 13 | |= jon/^json 14 | ^- (list post:tumblr) 15 | %- need 16 | (blog-posts-r:tumblr-parse jon) 17 | ++ noun (list post:tumblr) 18 | -- 19 | ++ grow 20 | |% 21 | ++ json 22 | [%a (turn bp jost:jumblr)] 23 | -- 24 | -- 25 | -------------------------------------------------------------------------------- /wip/mar/tumblr/get-posts.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/get-posts/tumblr/mar 3 | :: 4 | :: 5 | /? 310 6 | !: 7 | |_ req/{identifier/@t id-start/@u} 8 | ++ grab 9 | |% 10 | ++ json 11 | |= jon/^json 12 | ^- {identifier/@t id-start/@u} 13 | %- need 14 | ((ot 'identifier'^so 'id-start'^ni ~):jo jon) 15 | ++ noun {identifier/@t id-start/@u} 16 | -- 17 | -- 18 | -------------------------------------------------------------------------------- /wip/mar/tumblr/user-info.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :: /hoon/user-info/tumblr/mar 3 | :: 4 | /? 310 5 | /- tumblr 6 | /+ tumblr-parse 7 | !: 8 | |_ info/user-info:tumblr 9 | ++ grab 10 | |% 11 | ++ json 12 | |= jon/^json 13 | ^- user-info:tumblr 14 | %- need 15 | (user-info-r:tumblr-parse jon) 16 | ++ noun info 17 | -- 18 | -- 19 | -------------------------------------------------------------------------------- /wip/mar/wiki/articles.hoon: -------------------------------------------------------------------------------- 1 | /- wiki 2 | [wiki .] 3 | !: 4 | |_ {articles/(list delt)} 5 | ++ grab 6 | |% 7 | ++ noun (list delt) 8 | ++ mime |=(^mime (json (rash q.q apex:poja))) 9 | ++ json 10 | |= jon/^json 11 | ^- (list delt) 12 | (need ((ar (ot author+so at+di article+so content+so version+so message+so ~)):jo jon)) 13 | -- 14 | ++ grow 15 | |% 16 | ++ mime [/text/wiki-articles (taco (crip (pojo json)))] 17 | ++ json 18 | :- %a 19 | %+ turn articles 20 | |= article/delt 21 | %- jobe 22 | :* 23 | [%author (jape (trip aut.article))] 24 | [%at (jode ?:(=(at.article *@da) ~1970.1.1 at.article))] 25 | [%article (jape (trip art.article))] 26 | [%content (jape (trip cot.article))] 27 | [%version (jape (trip ver.article))] 28 | [%message (jape (trip msg.article))] 29 | ~ 30 | == 31 | -- 32 | -- 33 | -------------------------------------------------------------------------------- /wip/mar/wiki/change.hoon: -------------------------------------------------------------------------------- 1 | /- wiki 2 | [wiki .] 3 | !: 4 | |_ {change/delt} 5 | ++ grab 6 | |% 7 | ++ json 8 | |= jon/^json 9 | ^- delt 10 | :- '' 11 | :- ~1970.1.1 12 | %- need 13 | %. jon 14 | (ot article+so content+so version+so message+so ~):jo 15 | -- 16 | ++ grow 17 | |% 18 | ++ json 19 | %- jobe 20 | :* 21 | [%author (jape (trip aut.change))] 22 | [%at (jode ?:(=(at.change *@da) ~1970.1.1 at.change))] 23 | [%article (jape (trip art.change))] 24 | [%content (jape (trip cot.change))] 25 | [%version (jape (trip ver.change))] 26 | [%message (jape (trip msg.change))] 27 | ~ 28 | == 29 | -- 30 | -- 31 | -------------------------------------------------------------------------------- /wip/sec/com/tumblr.hoon: -------------------------------------------------------------------------------- 1 | :: Security driver for :tumblr app 2 | :: 3 | :::: /===/sec/com/tumblr/hoon 4 | :: 5 | /+ oauth1 6 | !: 7 | :::: 8 | :: 9 | |_ {bal/(bale keys:oauth1) to/token:oauth1} 10 | :: ++aut is a "standard oauth1" core, which implements the 11 | :: most common handling of oauth1 semantics. see lib/oauth1 for more details, 12 | :: and examples at the bottom of the file. 13 | ++ aut (~(standard oauth1 bal to) . |=(to/token:oauth1 +>(to to))) 14 | :: Tumblr API wants a content length header 15 | ++ add-cl-header 16 | |= a/sec-move ^+ a 17 | ?. ?=({$send *} a) a 18 | :- %send :- p.p.a 19 | :+ p.q.p.a 20 | (~(add ja q.q.p.a) %content-length (scot %u ?~(r.q.p.a 0 p.u.r.q.p.a))) 21 | r.q.p.a 22 | :: 23 | ++ add-screen-name 24 | |= a/httr ^- httr 25 | :+ p.a 26 | q.a 27 | (some (tact (weld (trip q:(need r.a)) "&screen_name=urbit"))) 28 | :: 29 | ++ filter-request 30 | %+ out-add-header:aut 31 | token-request='https://www.tumblr.com/oauth/request_token' 32 | oauth-dialog='https://www.tumblr.com/oauth/authorize' 33 | :: 34 | ++ filter-response res-handle-request-token:aut 35 | :: NOTE: calling in-exchange-token:aut produces another gate 36 | ++ receive-auth-query-string 37 | %+ cork 38 | %- in-exchange-token:aut 39 | exchange-url='https://www.tumblr.com/oauth/access_token' 40 | add-cl-header 41 | :: 42 | ++ receive-auth-response 43 | (cork add-screen-name bak-save-token:aut) 44 | ++ discard-state ~ 45 | -- 46 | -------------------------------------------------------------------------------- /wip/sec/io/block.hoon: -------------------------------------------------------------------------------- 1 | :: Test url +https://api.github.com/user 2 | :: 3 | :::: /hoon/github/com/sec 4 | :: 5 | /- blockio 6 | /+ basic-auth 7 | [. blockio] 8 | !: 9 | |_ {bal/(bale @) $~} 10 | ++ filter-request 11 | |= req/hiss 12 | ^- sec-move 13 | =+ keys=(secrets (cue key.bal)) 14 | =. r.p.req 15 | :: find pin & api_key and replace value 16 | %+ turn r.p.req 17 | |= {k/@t v/@t} 18 | ?: =(k 'pin') [k q.keys] 19 | ?. =(k 'api_key') [k v] 20 | [k (~(got by p.keys) v)] 21 | [%send req] 22 | -- 23 | -------------------------------------------------------------------------------- /wip/speakrune/README.md: -------------------------------------------------------------------------------- 1 | # speakrune 2 | 3 | A simple generator that tells you how to pronounce a Rune (or any sequence of one or more symbols with Urbit names). 4 | Copy /gen into your ship, `|commit %home` and run `+speakrune "=>"` from the Dojo to test it out. 5 | 6 | ## How speakrune works 7 | 8 | This is a simple example of how to create sets and maps and do lookups with them. A set of the input characters is created 9 | to check there are no invalid characters in the input and then a map of Urbit symbols to names is used to generate the 10 | output showing you how to pronounce the symbols. 11 | -------------------------------------------------------------------------------- /wip/speakrune/gen/speakrune.hoon: -------------------------------------------------------------------------------- 1 | |= runes=tape 2 | ^- tape 3 | |^ ?: (valid runes) 4 | (turn runes convert) 5 | "input contains non-rune characters" 6 | ++ valid 7 | |= x=tape 8 | ^- ? 9 | =/ chars (sy x) 10 | (~(all in chars) ~(has by table)) 11 | ++ convert 12 | |= x=@t 13 | ^- @t 14 | (~(got by table) x) 15 | ++ table 16 | %- my 17 | :~ [' ' 'ace'] 18 | ['|' 'bar'] 19 | ['\\' 'bas'] 20 | ['$' 'buc'] 21 | ['_' 'cab'] 22 | ['%' 'cen'] 23 | [':' 'col'] 24 | [',' 'com'] 25 | ['"' 'doq'] 26 | ['.' 'dot'] 27 | ['/' 'fas'] 28 | ['<' 'gal'] 29 | ['>' 'gar'] 30 | ['#' 'hax'] 31 | ['-' 'hep'] 32 | ['{' 'kel'] 33 | ['}' 'ker'] 34 | ['^' 'ket'] 35 | ['+' 'lus'] 36 | [';' 'mic'] 37 | ['(' 'pal'] 38 | ['&' 'pam'] 39 | [')' 'par'] 40 | ['@' 'pat'] 41 | ['[' 'sel'] 42 | [']' 'ser'] 43 | ['~' 'sig'] 44 | ['\'' 'soq'] 45 | ['*' 'tar'] 46 | ['`' 'tic'] 47 | ['=' 'tis'] 48 | ['?' 'wut'] 49 | ['!' 'zap'] 50 | == 51 | -- 52 | -------------------------------------------------------------------------------- /wip/sur/blockio.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/blockio/sur 3 | :: 4 | |% 5 | ++ currency ::> supported coins 6 | ?($btc $ltc $doge $btc-test $ltc-test $doge-test) :: 7 | ++ error tape ::< error result 8 | ++ balance ::> balance info 9 | $: coin/currency ::< network 10 | have/tape ::< confirmed balance 11 | pend/tape ::< unconfirmed balance 12 | == :: 13 | ++ withdrawal ::> withdrawal info 14 | $: coin/currency ::< network 15 | txid/tape ::< transaction 16 | paid/tape ::< total withdrawn 17 | sent/tape ::< amount to target 18 | feen/tape ::< network fee 19 | feeb/tape ::< block.io fee 20 | == :: 21 | ++ secrets (pair (map currency @t) @t) ::< secrets data format 22 | -- 23 | -------------------------------------------------------------------------------- /wip/sur/mail/message.hoon: -------------------------------------------------------------------------------- 1 | ,[tim=time fom=ship to=ship sub=cord bod=wain] ::< time, from, to, msg. 2 | -------------------------------------------------------------------------------- /wip/sur/mail/send.hoon: -------------------------------------------------------------------------------- 1 | ,[to=ship sub=cord bod=wain] 2 | -------------------------------------------------------------------------------- /wip/sur/mesh.hoon: -------------------------------------------------------------------------------- 1 | !: 2 | |% 3 | += color @t 4 | += friend @p 5 | += friends (map friend color) 6 | += network (map friend friends) 7 | -- 8 | -------------------------------------------------------------------------------- /wip/sur/ping/message.hoon: -------------------------------------------------------------------------------- 1 | ,[to=ship message=cord] 2 | -------------------------------------------------------------------------------- /wip/sur/taskk.hoon: -------------------------------------------------------------------------------- 1 | :: /hoon/taskk/sur 2 | :: 3 | :: 4 | |% 5 | ++ issue {pha/tape iss/tape des/tape} 6 | ++ issue-ref {pha/tape iss/tape} 7 | ++ change-ref {fpha/tape tpha/tape iss/tape} 8 | -- 9 | -------------------------------------------------------------------------------- /wip/sur/tumblr.hoon: -------------------------------------------------------------------------------- 1 | :: These types correspond to the types that Tumblr's API 2 | :: produces, so please check Tumblr's documentation for 3 | :: details. 4 | :: 5 | |% 6 | :: there has to be a better way to get just the response out 7 | ++ blog-posts-r response/blog-posts 8 | ++ blog-posts p/(list post) 9 | ++ post 10 | $% 11 | {$def-post def-post} 12 | {$photo-post photo-post} 13 | {$quote-post quote-post} 14 | {$text-post text-post} 15 | {$link-post link-post} 16 | {$video-post video-post} 17 | == 18 | ++ def-post 19 | $: 20 | blog-name/@t 21 | id/@u 22 | post-url/@t 23 | type/@t 24 | date/@t 25 | timestamp/@u 26 | format/@t 27 | tags/(list @t) 28 | == 29 | ++ user-info-r response/user 30 | ++ user u/user-info 31 | ++ user-info 32 | $: 33 | following/@u 34 | name/@t 35 | default-post-format/@t 36 | likes/@u 37 | blogs/(list blog) 38 | == 39 | ++ blog 40 | $: 41 | name/@t 42 | title/@t 43 | url/@t 44 | tweet/@t 45 | primary/? 46 | followers/@u 47 | == 48 | ++ photo-size 49 | {width/@u height/@u url/@t} 50 | ++ photo 51 | $: 52 | caption/@t 53 | original-size/photo-size 54 | alt-sizes/(list photo-size) 55 | == 56 | ++ quote-post 57 | $: 58 | blog-name/@t 59 | id/@u 60 | post-url/@t 61 | type/@t :: can be $% 62 | date/@t 63 | timestamp/@u 64 | tags/(list @t) 65 | source-url/@t 66 | source-title/@t 67 | text/@t 68 | source/@t 69 | == 70 | ++ text-post 71 | $: 72 | blog-name/@t 73 | id/@u 74 | post-url/@t 75 | type/@t 76 | date/@t 77 | timestamp/@u 78 | format/@t 79 | tags/(list @t) 80 | title/@t 81 | body/@t 82 | == 83 | ++ video-post 84 | $: 85 | blog-name/@t 86 | id/@u 87 | post-url/@t 88 | type/@t 89 | date/@t 90 | timestamp/@u 91 | format/@t 92 | tags/(list @t) 93 | caption/@t 94 | player/(list {width/@u embed-code/@t}) 95 | == 96 | ++ link-post 97 | $: 98 | blog-name/@t 99 | id/@u 100 | post-url/@t 101 | type/@t :: can be $% 102 | date/@t 103 | timestamp/@u 104 | format/@t 105 | tags/(list @t) 106 | title/@t 107 | url/@t 108 | ::link-author/@t 109 | ::excerpt/@t 110 | ::publisher/@t 111 | photos/(list photo) 112 | ::summary/@t 113 | == 114 | ++ photo-post 115 | $: 116 | blog-name/@t 117 | id/@u 118 | post-url/@t 119 | type/@t :: can be $% 120 | date/@t 121 | timestamp/@u 122 | format/@t 123 | tags/(list @t) 124 | caption/@t 125 | photos/(list photo) 126 | == 127 | :: other posts without support right now: question, chat 128 | -- 129 | -------------------------------------------------------------------------------- /wip/sur/wiki.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | ++ delt 3 | $: 4 | aut/cord 5 | at/time 6 | art/cord 7 | cot/cord 8 | ver/cord 9 | msg/cord 10 | == 11 | -- 12 | -------------------------------------------------------------------------------- /wip/web/examples.md: -------------------------------------------------------------------------------- 1 | --- 2 | anchor: none 3 | title: Read Me 4 | --- 5 | 6 | # Urbit examples 7 | 8 | Let's get you running your first examples! 9 | 10 | If you're viewing this from your Urbit, you're ready to try out the example 11 | programs we have copied in to your ship. (If not, follow our [installation 12 | instructions](https://github.com/urbit/examples) on Github). 13 | 14 | ## Examples library 15 | 16 | We have examples of apps, generators, libraries and web pages here. More 17 | formally, Urbit apps hold state and synchronize state and manage subscriptions; 18 | generators are functional shell scripts; libraries present code modules to be 19 | shared across the Urbit system; and Urbit web pages bring pure functional 20 | programming and a powerful build system to conventional HTML. 21 | 22 | - [Applications](/~~/examples/app) 23 | - [Generators](/~~/examples/gen) 24 | - [Libraries](/~~/examples/lib) 25 | - [Web](/~~/examples/web) 26 | 27 | Before diving all the way in, you can start with a few quick `Hello world`-style 28 | examples below. 29 | 30 | ## Quickstart 31 | 32 | #### `:hello` app 33 | 34 | Start your first app, `:hello`, from `:dojo`: 35 | 36 | ~your-urbit:dojo/examples> |start %hello 37 | 38 | `:hello` has a web interface that's being served now via `%eyre`, your Urbit web 39 | server. Visit the URL in your web browser: 40 | 41 | http://localhost:8443/~~/pages/hello 42 | 43 | Once the page loads with the `Hello, world!` delivered from `:hello`'s app 44 | state, click the button to *poke* your running `:hello` app and see an output in 45 | your `:dojo`. 46 | 47 | [%hello %poked 'Hello, world!'] 48 | 49 | You can find the source at `/app/hello.hoon` of this repo. Check out the 50 | [`app`](/~~/examples/app) page for more on what just happened. 51 | 52 | Onto your first generators! 53 | 54 | #### `+hello` generator 55 | 56 | Let's run your first generator, or Urbit shell script, from `:dojo`: 57 | 58 | ~your-urbit:dojo/examples> +hello/h1 59 | 'Hello, world!' 60 | 61 | Try the second `+hello` generator with a custom `cord` sample of your choice: 62 | 63 | ~your-urbit:dojo/examples> +hello/h2 'Mars' 64 | 'Hello, Mars!' 65 | 66 | Try the third with and without a sample where it will default: 67 | 68 | ~your-urbit:dojo/examples> +hello/h3, =txt 'Mars' 69 | 'Hello, Mars!' 70 | 71 | ~your-urbit:dojo/examples> +hello/h3 72 | 'Hello, universe!' 73 | 74 | Generators offer a great combination of simplicity, flexibility and power. You 75 | can find the source for the above examples in `/gen/hello` of this repo and more 76 | information on generators at the [`gen`](/~~/examples/gen) page. 77 | 78 | Let's look at libraries next. 79 | 80 | 81 | ### Contributing / Feedback 82 | 83 | The number one goal for this repository is for it to be fun! People are always 84 | around on [`:talk`](https://urbit.org/docs/using/setup#-messaging-talk) and 85 | [`:fora`](https://urbit.org/~~/fora). Help each other out, and don't hesitate if 86 | you have an idea for a contribution. We'd love to make this both a learning 87 | resource and a record of what people in the community are coming up with. 88 | 89 | Give us feedback in the comments of [this `:fora` 90 | post](https://urbit.org/~~/fora/posts/~2017.8.3..20.53.26..c361~/) after you've 91 | played around with these for a little bit. Let us know about your ideas, 92 | requests, and/or problems and we'll try and get back to you quickly. Pull 93 | requests are more than welcome. 94 | 95 |
96 | 97 | Happy hacking! 98 | -------------------------------------------------------------------------------- /wip/web/examples/app.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Applications 3 | --- 4 | 5 | # Applications 6 | 7 | `%gall` is the Urbit application driver. 8 | 9 | Apps live under `/app` in a `%clay` desk. `%gall` apps hold state, respond to 10 | subscription requests and synchronizes state across ships. 11 | 12 | First apps need to be started, then you can "poke" their arms from either the 13 | `:dojo` or from the web. 14 | 15 | Start an example app from your `:dojo` like this: 16 | 17 | ~your-urbit:dojo/examples> |start %name 18 | 19 | and poke its `++poke-mark-name` arm like this: 20 | 21 | ~your-urbit:dojo/examples> :name &mark-name {insert noun of mark &mark-name} 22 | 23 | where the mark is pointing to a mark source file in `/mar`. Some of these 24 | example apps use *structures* too, or shared molds stored in files in `/sur`. To 25 | understand how these work better, check out their pages: 26 | 27 | - [Marks](/~~/examples/mar) 28 | - [Structures](/~~/examples/sur) 29 | 30 | In the case that the app has a web interface, its web UI will be served at the 31 | URL: 32 | 33 | http://localhost:8443/~~/pages/name 34 | 35 | Visiting that page will subscribe, or `peer`, to the `%gall` app at the 36 | specified web path (in the arm `++peer-web-path-name`). Then, using the 37 | interface will send typed pokes or peers of the specified mark types through our 38 | `urb.js` web API. 39 | 40 | Each individual app has its own set of instructions in 41 | `/examples/app/{app name}`. Click one below to get started! 42 | 43 | 44 | -------------------------------------------------------------------------------- /wip/web/examples/app/blockio.md: -------------------------------------------------------------------------------- 1 | # `:blockio` 2 | 3 | Source: 4 | 5 | - `/app/blockio.hoon` 6 | - `/lib/blockio.hoon` 7 | - `/mar/blockio/balance.hoon` 8 | - `/mar/blockio/withdraw.hoon` 9 | - `/sec/io/block.hoon` 10 | - `/sur/blockio.hoon` 11 | 12 | `:dojo`: 13 | 14 | ~your-urbit:dojo/examples> |start %blockio 15 | ~your-urbit:blockio[doge-test]: coin doge 16 | ~your-urbit:blockio[doge]: key xxxx-xxxx-xxxx-xxxx 17 | ~your-urbit:blockio[doge]: address xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 18 | ~your-urbit:blockio[doge]: talk y 19 | 20 |
21 | 22 | See: [Block.io API integration for Urbit](https://github.com/Fang-/blockio) 23 | 24 | Thanks, `~palfun-foslup`! 25 | -------------------------------------------------------------------------------- /wip/web/examples/app/echo.md: -------------------------------------------------------------------------------- 1 | # `:echo` 2 | 3 | Source: 4 | 5 | - `/app/echo.hoon` 6 | 7 | `:dojo`: 8 | 9 | ~your-urbit:dojo/examples> |start %echo 10 | ~your-urbit:dojo/examples> :echo {insert any noun} 11 | 12 |
13 | 14 | This app demonstrates how to enter input from the command line and print it out 15 | in the `:dojo`. Here the app simply printfs the input and then returns an empty 16 | list of moves and its app state unchanged. 17 | -------------------------------------------------------------------------------- /wip/web/examples/app/feed.md: -------------------------------------------------------------------------------- 1 | # `:feed` 2 | 3 | Source: 4 | 5 | - `/web/pages/feed/init.hoon` 6 | - `/web/pages/feed/init.js` 7 | - `/web/pages/feed.hoon` 8 | - `/web/pages/feed/feed.js` 9 | - `/web/pages/feed/feed.css` 10 | 11 | Web: 12 | 13 | http://localhost:8443/~~/pages/feed/init 14 | 15 |
16 | 17 | `:feed` is a vanilla microblogging web UI built using `:talk` as the backend. 18 | This basic UI works well to highlight the core functionality of our current 19 | `urb.js` and `:talk` web API's. 20 | 21 | `:feed` works by first creating a `%feed` `:talk` station, then loading that 22 | station through the `:feed` web UI which will present a chronological feed of 23 | public `:talk` posts by other ships. When you subscribe and unsubscribe to other 24 | ships' `%public` `:talk` stations (which boot with all urbits by default) 25 | through the web UI, you add those to your `%feed` station's list of 26 | subscriptions. New posts will push to the top of your feed in real time. 27 | 28 | The goal of this demo was to show that building a Twitter replacement actually 29 | isn't that hard at all; and it can be done almost entirely on the frontend. As 30 | shown, you don't even have to use React/Redux. But that's probably the way to go 31 | if you want to build the real thing. 32 | 33 | Anyways, enough *:talk*. 34 | 35 | You will need to have at least two running urbits for this demo. No need to 36 | `|start` any apps as `:feed` uses `:talk` which starts automatically on boot. 37 | 38 | On your first urbit (the only one where you'll be accessing the web UI), you 39 | will need to initialize your `%feed` station. Do this by visiting in the 40 | browser: 41 | 42 | http://localhost:8443/~~/pages/feed/init 43 | 44 | It might take a few seconds. When the page finishes loading, a button to load 45 | your feed will appear. Click it to get redirected to your feed, which brings you 46 | to: 47 | 48 | http://localhost:8443/~~/pages/feed 49 | 50 | Next, fetch your second urbit's feed by typing the name of the second urbit into 51 | the `Fetch` text box (don't forget `@p` syntax: prefix the name/address with a 52 | `~`!). 53 | 54 | The feed will be empty to start. On your second urbit, post a `%public` message 55 | by switching in its console from its `:dojo` prompt to its `:talk` prompt. This 56 | is done by pressing `Ctrl-X` on your keyboard in the terminal window of your 57 | second urbit: 58 | 59 | ~your-urbit-2:dojo/examples> 60 | ~your-urbit-2:talk[] 61 | 62 | Next, switch the second urbit's `:talk` audience to its `%public` station with 63 | the following `:talk` command: 64 | 65 | ~your-urbit-2:talk[] ;%public 66 | 67 | --------------| ;%public 68 | 69 | ~your-urbit-2:talk[%public] 70 | 71 | Type a public message and hit `Enter` on your keyboard to send it: 72 | 73 | ~your-urbit-2:talk[%public] is this thing on? 74 | 75 | ------------[0] 76 | your-urbit-2; is this thing on? 77 | 78 | If you look back in the feed UI of your first urbit that you're viewing in the 79 | browser, the post should have loaded automatically. 80 | 81 | Click `Subscribe` to subscribe to your second urbit's `%public` station, which 82 | will reload the page confirming you've subscribed. Then click the `Home` button 83 | to return to your home feed. Your second urbit's post should appear on the page. 84 | 85 | Post a public message from your second urbit again: 86 | 87 | ~your-urbit-2:talk[%public] i guess this thing does work. 88 | 89 | your-urbit-2; i guess this thing does work. 90 | 91 | The post should push to your first urbit's web feed in real time. 92 | 93 | The plan is to turn this example into a complete written-up tutorial, but we 94 | wanted to share the code with everyone first. For the time being, we're happy to 95 | answer questions in `:talk` or by a [Github 96 | issue](https://github.com/urbit/examples/issues). 97 | -------------------------------------------------------------------------------- /wip/web/examples/app/foos.md: -------------------------------------------------------------------------------- 1 | # `:foos` 2 | 3 | Source: 4 | 5 | - `/app/foos.hoon` 6 | - `/web/pages/foos.hoon` 7 | 8 | `:dojo`: 9 | 10 | ~your-urbit:dojo/examples> |start %foos 11 | 12 | Web: 13 | 14 | http://localhost:8443/~~/pages/foos 15 | 16 |
17 | 18 | This app records foosball scores (one wins by scoring 10) into its state. It 19 | then sends the updated state back to frontend, which then calculates and 20 | displays the standings. 21 | 22 | Start the app in `:dojo` and visit the web interface. Fill in a valid result 23 | (each name must be a string, each score must be between 0-10, and the winner 24 | must have 10). You can open another tab and watch the standings remain in sync. 25 | 26 | Let's walk through what happens when a valid result is submitted: 27 | 28 | - `web/pages/foos/foos.js` catches the click event and checks that the data is 29 | valid. If it is, `foos.js` uses `urb.send` to send JSON to your urbit. 30 | 31 | - Our data is sent as the Hoon mark `json`, which is parsed by /mar/json.hoon 32 | 33 | - Our parsed JSON is received by the `++poke-json` arm of `app/foos.hoon`, 34 | which updates our state with the latest result and then `spam`s the update 35 | all connected clients. 36 | -------------------------------------------------------------------------------- /wip/web/examples/app/lead.md: -------------------------------------------------------------------------------- 1 | # `:lead` 2 | 3 | Source: 4 | 5 | - `/app/lead.hoon` 6 | - `/web/pages/lead.hoon` 7 | 8 | `:dojo`: 9 | 10 | ~your-urbit:dojo/examples> |start %lead 11 | 12 | Web: 13 | 14 | http://localhost:8443/~~/pages/lead 15 | 16 |
17 | 18 | This app is a basic leaderboard that allows you to add contestants and increment 19 | their scores. 20 | 21 | Start the app in `:dojo` and visit the web interface, then `Add` a name to the 22 | leaderboard. It will be stored in the app's state. 23 | 24 | Let's briefly trace what happens on each `Add`: 25 | 26 | - When you click 'Add', or when you increment a contestants score, 27 | `web/pages/lead.hoon` catches the event and sends that json information -- 28 | more specifically data with the mark of `json`--to `app/lead.hoon`. 29 | 30 | - The `json` data is parsed by `mar/json.hoon`, and is then passed to 31 | `++poke-json` (in `app/lead.hoon`). 32 | 33 | - `++poke-json` reparses the `++json` to Hoon data structures, and updates the 34 | app's state to include the latest result. 35 | 36 | - Finally, `++poke-json` passes the updated state to `++deliver`, which sends 37 | the new state back to `lead.js`, whose callback passes it to React, where 38 | our DOM diff is calculated automatically. 39 | -------------------------------------------------------------------------------- /wip/web/examples/app/life.md: -------------------------------------------------------------------------------- 1 | # `:life` 2 | 3 | Source: 4 | 5 | - `/app/life.hoon` 6 | 7 | `:dojo`: 8 | 9 | ~your-urbit:dojo/examples> |start %life 10 | ~your-urbit:dojo/examples> :life [%start [~ 10]] 11 | ~your-urbit:dojo/examples> :life [%step [~ 1]] 12 | ~your-urbit:dojo/examples> :life [%toggle ~[[4 2]]] 13 | ~your-urbit:dojo/examples> :life [%debug ~] 14 | 15 |
16 | 17 | See: [Game of life in Hoon](https://github.com/jalehman/hoon-life) 18 | -------------------------------------------------------------------------------- /wip/web/examples/app/mail.md: -------------------------------------------------------------------------------- 1 | # `:mail` 2 | 3 | Source: 4 | 5 | - `/app/mail.hoon` 6 | - `/mar/mail/message.hoon` 7 | - `/mar/mail/send.hoon` 8 | - `/sur/mail/message.hoon` 9 | - `/sur/mail/send.hoon` 10 | - `/web/pages/mail.hoon` 11 | 12 | `:dojo` (you will need two running urbits to send and receive a message): 13 | 14 | ~your-urbit-1:dojo/examples> |start %mail 15 | 16 | ~your-urbit-2:dojo/examples> |start %mail 17 | 18 | Web: 19 | 20 | http://localhost:8443/~~/pages/mail 21 | 22 | and 23 | 24 | http://localhost:8444/~~/pages/mail 25 | 26 | > Running in an incognito tab might help keep your cookies clean here. 27 | 28 |
29 | 30 | This allows urbits to send typed, email-like message over the network. 31 | 32 | Start the app on two urbits in `:dojo` and visit the web interfaces of both. 33 | Fill out the `To` field in the page of your first urbit with the name of second 34 | urbit (don't forget `@p` syntax: prefix the name/address with a `~`!). 35 | 36 | Then, fill out the `Subject` and `Body` forms with text. 37 | 38 | Click `Send`. 39 | 40 | Your second urbit's console and web page should display the message! 41 | 42 | Let's walk through what just happened: 43 | 44 | - When we click 'send', foos.js uses `urb.send` from `urb.js` to send our 45 | message as an 'mail-send' to the sending urbit's `mail.hoon` app. 46 | 47 | - `mar/mail/send.hoon` parses our message and passes it to the 48 | `++poke-mail-send` arm. 49 | 50 | - `++poke-mail-send` saves the message in the `sent` part of its state, then 51 | sends it with the current timestamp and sender -- as a `mail-message` -- to 52 | the `mail.hoon` app running on the other ship. 53 | 54 | - The other ship's `mail.hoon` parses our message with `mar/mail/message`, 55 | receiving it on the `++poke-mail-message` arm. 56 | 57 | - `++poke-mail-message` saves the received `mail-message` in its state, and 58 | then sends the updated version to the browser client for display. 59 | -------------------------------------------------------------------------------- /wip/web/examples/app/mesh.md: -------------------------------------------------------------------------------- 1 | # `:mesh` 2 | 3 | Source: 4 | 5 | - `/app/mesh.hoon` 6 | - `/mar/mesh/message.hoon` 7 | - `/mar/mesh/send.hoon` 8 | - `/sur/mesh/message.hoon` 9 | - `/sur/mesh/send.hoon` 10 | - `/web/pages/mesh.hoon` 11 | 12 | `:dojo` (you will need three running urbits to demo a full `:mesh` social 13 | network): 14 | 15 | ~your-urbit-1:dojo/examples> |start %mesh 16 | 17 | ~your-urbit-2:dojo/examples> |start %mesh 18 | 19 | ~your-urbit-3:dojo/examples> |start %mesh 20 | 21 | Web: 22 | 23 | http://localhost:8443/~~/pages/mesh 24 | 25 | and 26 | 27 | http://localhost:8444/~~/pages/mesh 28 | 29 | > Running in an incognito tab might help keep your cookies clean here. 30 | 31 |
32 | 33 | `:mesh` is a simple distributed social network. The backend is a `%gall` app 34 | written from scratch, and the frontend uses `D3.js` to render a force-directed 35 | graph representing your `:mesh` network. `:mesh` is a reasonably complete demo 36 | that works well to highlight how `%gall` apps make distributed state 37 | synchronization a breeze for app developers, and how to serve reasonably complex 38 | app data to the web to render with the frontend UI library of your choice. 39 | 40 | Contained in your `:mesh` app state are: your social network, containing your 41 | friends and friends-of-friends; and a HTML hex color that propagates to all of 42 | your friends and colors a node that represents you on your and all of your 43 | friends' graphs. 44 | 45 | Load up your first urbit's web interface at the link above. The `:mesh` networks 46 | of your urbit will start empty. "Friend" your second urbit by typing their name 47 | in the text box and hitting `Enter` on your keyboard (don't forget `@p` syntax: 48 | prefix the name/address with a `~`!). 49 | 50 | After a seconds, a network graph should be drawn showing the new first-degree 51 | connection, represented by a green line edge. 52 | 53 | Both node colors default to grey. Click one of the six preselected color 54 | options, or get fancy and set your own in the `:dojo` of your first urbit: 55 | 56 | ~your-urbit-1:dojo/examples> :mesh &mesh-color '#000000' 57 | 58 | Your first urbit's node on the graph should now be the new color. Now if you 59 | load your second urbit's web UI at the second link above and "friend" your first 60 | urbit back, the connection you make with them will display the correct updated 61 | color. Change your second urbit's color, and the change will push to your first 62 | urbit's UI in real time. 63 | 64 | In your second urbit's UI, friend your third running urbit, which will create a 65 | second first-degree connection in your second urbit's graph. But if you look 66 | back in your first urbit's graph, the connection won't be direct; it will be 67 | second-degree, as the third urbit is the friend of your friend, represented by a 68 | blue line edge. Friending the third urbit directly will change this back to a 69 | first-degree connection. Colors changes on any of the ships will propagate to 70 | all subscribed friends and their friends. 71 | 72 | Like `:feed`, the plan is to turn this example into a complete written-up 73 | tutorial, but we wanted to share the code with everyone first. For the time 74 | being, we're happy to answer questions in `:talk` or by a Github issue. 75 | -------------------------------------------------------------------------------- /wip/web/examples/app/ping.md: -------------------------------------------------------------------------------- 1 | # `:ping` 2 | 3 | Source: 4 | 5 | - `/app/ping.hoon` 6 | - `/mar/ping/message.hoon` 7 | - `/sur/ping/message.hoon` 8 | 9 | `:dojo` (you will need two running urbits to send and receive a message): 10 | 11 | ~your-urbit-1:dojo/examples> |start %ping 12 | 13 | ~your-urbit-2:dojo/examples> |start %ping 14 | 15 | ~your-urbit-1:dojo/examples> :ping &ping-message [~your-urbit-2 'Hey, neighbor!'] 16 | 17 |
18 | 19 | This application demonstrates how to send typed information to an app on another 20 | ship by poking it with a 'mark.' 21 | 22 | Start the app on two urbits in `:dojo` and send a `ping-message` from your first 23 | urbit using the command above. Your second urbit's `:dojo` should print: 24 | 25 | [%ping 'Message received!'] 26 | [%ping %message 'Hey, neighbor!'] 27 | 28 | Let's briefly step through what we just did: 29 | 30 | - We poked `ping.hoon` with data of the `ping-message` mark, which is simply a 31 | ship address and a text `@t` atom. 32 | 33 | - `mar/ping/message.hoon` parses the data, and then passes it along to 34 | `++poke-ping-message`. 35 | 36 | - `++poke-ping-message` then sends a move containing the text atom we 37 | submitted to the corresponding `/ping` app on the urbit we specified (your 38 | second one). 39 | 40 | - Your second urbit's `mar/atom.hoon` parses the atom, and passes it along 41 | to`++poke-atom`, which prints out the output above. 42 | -------------------------------------------------------------------------------- /wip/web/examples/app/pong.md: -------------------------------------------------------------------------------- 1 | # `:pong` 2 | 3 | Source: 4 | 5 | - `/app/pong.hoon` 6 | 7 | `:dojo` (you will need two running urbits to send and receive a message): 8 | 9 | ~your-urbit-1:dojo/examples> |start %pong 10 | 11 | ~your-urbit-2:dojo/examples> |start %pong 12 | 13 | ~your-urbit-1:dojo/examples> :pong &urbit ~your-urbit-2 14 | 15 |
16 | 17 | This app demonstrates how to poke an app with an urbit name. 18 | 19 | Start the app on two urbits in `:dojo` and send a pong to your second urbit from 20 | your first urbit using the command above. Your second urbit should receive: 21 | 22 | [%pong 'Incoming pong!'] 23 | [%pong %received 'Pong'] 24 | 25 | Let's briefly walk through what we just did: 26 | 27 | - We sent data of the `urbit` mark from dojo to the sender (your first 28 | urbit)'s `pong.hoon` app. 29 | 30 | - `mar/urbit` parses the data, and passes it to `++poke-urbit` 31 | 32 | - `++poke-urbit` then sends a move with the message 'Pong' to your second 33 | urbit. 34 | 35 | - Your second urbit received this data with its own `pong.hoon` app. 36 | `pong.hoon` parses it with `mar/atom`, and then receives it on the 37 | `++poke-atom` arm, which simply prints the message out. 38 | -------------------------------------------------------------------------------- /wip/web/examples/app/sink-source.md: -------------------------------------------------------------------------------- 1 | # `:sink` & `:source` 2 | 3 | Source: 4 | 5 | - `/app/sink.hoon` 6 | - `/app/source.hoon` 7 | 8 | `:dojo`: 9 | 10 | ~your-urbit:dojo/examples> |start %sink 11 | 12 | ~your-urbit:dojo/examples> |start %source 13 | 14 | ~your-urbit:dojo/examples> :sink %on 15 | 16 | ~your-urbit:dojo/examples> :source {insert any noun} 17 | 18 |
19 | 20 | These two apps demonstrate how to set up a subscription from one app to another. 21 | This can be two apps on the same urbit, or two apps between different urbits. 22 | This demo only needs one running urbit. 23 | 24 | To run, start both apps from `:dojo`. Then, turn the subscription on (note this 25 | is not a general syntax for starting a subscription). Submit some input to 26 | `sink` on the path where `sink` is subscribed. You should see a printf from 27 | `sink.hoon` confirming it received the subscription update. 28 | 29 | Let's walk through what we did: 30 | 31 | - when we poked `sink.hoon`, it received the noun `%on` with the `++poke-noun` 32 | arm, setting our state to 'available'. `++poke-noun` then sends out a 33 | subcription request to `source.hoon` on the path `/example-path`. 34 | 35 | - `source.hoon` receives the subscription request with `++peer`. `%gall` then 36 | sends confirmation to `++reap` in `sink.hoon` 37 | 38 | - Then we poked `source.hoon` with a noun, which `source.hoon` parses with 39 | `mar/noun.hoon`. `source.hoon` then receives this parsed data on its 40 | `++poke-noun` arm. 41 | 42 | - `++poke-noun` (in `source.hoon`) maps over the list of all clients 43 | subscribed to the path `/example-path`, sending a `%diff %noun` to all of 44 | them. 45 | 46 | - `sink.hoon` receives the update on the `++diff-noun`, and printfs the noun 47 | we submitted. 48 | -------------------------------------------------------------------------------- /wip/web/examples/app/square.md: -------------------------------------------------------------------------------- 1 | # `:square` 2 | 3 | Source: 4 | 5 | - `/app/square.hoon` 6 | 7 | `:dojo`: ~your-urbit:dojo/examples> |start %square 8 | 9 | ~your-urbit:dojo/examples> :square &atom 10 10 | 11 |
12 | 13 | This app prints out the square of an atom. 14 | 15 | Start the app from `:dojo` and poke it with an atom. You should see: 16 | 17 | [%square 100] 18 | 19 | Here's what happened: 20 | 21 | - The `:dojo` noun was type-checked by `mar/atom.hoon` and converted into an 22 | atom 23 | 24 | - The validated atom was then passed to `++poke-atom` in the `square.hoon` 25 | app, which printed out the square of the given number'. 26 | -------------------------------------------------------------------------------- /wip/web/examples/app/sum.md: -------------------------------------------------------------------------------- 1 | # `:sum` 2 | 3 | Source: 4 | 5 | - `/app/sum.hoon` 6 | 7 | `:dojo`: 8 | 9 | ~your-urbit:dojo/examples> |start %sum 10 | 11 | ~your-urbit:dojo/examples> :sum &atom 40 12 | 13 | ~your-urbit:dojo/examples> :sum &atom 2 14 | 15 |
16 | 17 | This app prints out an accumulating sum of numbers stored in `:sum`'s app state. 18 | 19 | Start the app from `:dojo` and poke it with an atom. You should see: 20 | 21 | [%sum 40] 22 | 23 | Then, once more. The sum should now be: 24 | 25 | [%sum 42] 26 | 27 | Here's what happened: 28 | 29 | - The `:dojo` nouns were type-checked by `mar/atom.hoon` and converted into an 30 | atom 31 | 32 | - The validated atoms were then passed to the `++poke-atom` arm in the 33 | `sum.hoon` app, which added the given numbers to the number stored in its 34 | state; the new result is then printed out and then replaces the previous 35 | number in the app state. 36 | -------------------------------------------------------------------------------- /wip/web/examples/app/talkbot.md: -------------------------------------------------------------------------------- 1 | # `:talkbot` 2 | 3 | Source: 4 | 5 | - `/app/talkbot.hoon` 6 | 7 | `:dojo`: 8 | 9 | ~your-urbit-1:talk[] ;create channel %examples 'example channel' 10 | ~your-urbit-1:dojo/examples> |start %talkbot 11 | ~your-urbit-1:dojo/examples> :talkbot [%join our %examples] 12 | ~your-urbit-2:talk[] ;join ~your-urbit-2/examples 13 | ~your-urbit-2:talk+ test 14 | 15 | `~your-urbit-1` running `:talkbot` will auto-respond with: 16 | 17 | ~your-urbit-1+ :: test successful! 18 | 19 |
20 | 21 | See: [~talkbot, the one and only](https://github.com/Fang-/talkbot) 22 | 23 | Thanks, `~palfun-foslup`! 24 | -------------------------------------------------------------------------------- /wip/web/examples/app/taskk.md: -------------------------------------------------------------------------------- 1 | # `:taskk` 2 | 3 | Source: 4 | 5 | - `/app/taskk.hoon` 6 | - `/gen/taskk/yaml.hoon` 7 | - `/mar/taskk/change-phase.hoon` 8 | - `/mar/taskk/create-issue.hoon` 9 | - `/mar/taskk/delete-issue.hoon` 10 | - `/mar/taskk/issue.hoon` 11 | - `/mar/taskk/request-board.hoon` 12 | - `/sur/taskk.hoon` 13 | - `/web/pages/taskk.html` 14 | - `/web/pages/mail.css` 15 | - `/web/pages/mail.js` 16 | 17 | `:dojo`: 18 | 19 | ~your-urbit:dojo/examples> |start %taskk 20 | 21 | Web: 22 | 23 | http://localhost:8443/~~/pages/taskk.html 24 | 25 | Usage: 26 | 1. Each column has its own "create new" button. 27 | 2. Issues are extremely simple, having a title, an assignee, a description 28 | 3. Double click tile to expand. 29 | 4. Drag a tile to change phase. 30 | 5. These boards are stored as a directory of markdown files on your ship, 31 | at `%/app/taskk/HOST/BOARD/PHASE/ISSUE`. If you'd like to sync boards or 32 | collaborate, see the instructions in the docs on syncing desks. 33 | 34 | `:dojo` (poke directly): 35 | 36 | ~your-urbit:dojo/examples> :taskk %taskk-create-issue /tape /tape /tape 37 | ~your-urbit:dojo/examples> :taskk %taskk-delete-issue /tape /tape 38 | ~your-urbit:dojo/examples> :taskk %taskk-change-phase /tape /tape /tape 39 | ~your-urbit:dojo/examples> :taskk %taskk-request-board /tape /tape 40 | 41 | *Manage issues on Urbit* 42 | 43 | 44 | 45 | Taskk is a trello-esque app for managing distributed todo boards on Urbit. We 46 | use clay as our shared state. This allows multiple users to sync issues, etc. 47 | The basic unit of the app is the issue, which is stored as an md file. As much 48 | as possible is encoded in the file path, so that app functions as a wrapper 49 | around clay to enforce rules, etc. 50 | 51 | Any large-scale edits can be done in vim or a similar editor by simply editing 52 | the markdown file associated with an issue. 53 | 54 | -------------------------------------------------------------------------------- /wip/web/examples/app/tumblr.md: -------------------------------------------------------------------------------- 1 | # `:tumblr` 2 | 3 | ## Tumblr Urbit API integration 4 | 5 | *Note* The Tumblr API docs do not accurately reflect all responses. I have 6 | implemented the major keys of blog post responses, but there are some missing. 7 | If you want the "reblog tag," you'll have to work for it ;) 8 | 9 | Source: 10 | 11 | - `/app/tumblr.hoon` 12 | - `/mar/tumblr/blog-posts.hoon` 13 | - `/mar/tumblr/blog-post.hoon` 14 | - `/mar/tumblr/user-info.hoon` 15 | - `/sec/com/tumblr.hoon` 16 | - `/lib/jumblr.hoon` 17 | - `/lib/tumblr-parse.hoon` 18 | - `/lib/tumblr-parse.hoon` 19 | - `/sur/tumblr.hoon` 20 | - `/gen/tumblr/feed.hoon` 21 | 22 | ## Purpose 23 | 24 | This app allows any Urbit app to connect to an authenticated Tumblr account. It 25 | does this by asking you for your keys once and then keeping them in your Urbit. 26 | Every subsequent call to that domain will use the same keys. 27 | 28 | Below you will find the relevant setup instructions as well as the basic 29 | commands that one can run. 30 | 31 | ## Setup 32 | 33 | - `|init-oauth1` 34 | - enter tumblr api endpoint `api.tumblr.com` and your consumer key and secret 35 | for [your app](https://www.tumblr.com/oauth/apps) 36 | - try `+https://api.tumblr.com/user/info` 37 | 38 | ## Connector commands 39 | 40 | To see the information for the authenticated user 41 | 42 | :dojo> /+ tumblr 43 | :dojo> .^(user-info:tumblr %gx /=tumblr=/user/info/tumblr-user-info) 44 | 45 | To see posts for a blog (not fully fleshed out yet) 46 | 47 | :dojo> /+ tumblr 48 | :dojo> .^((list post:tumblr) %gx /=tumblr=/blog//posts/tumblr-blog-posts) 49 | 50 | To see all posts, you can also run the generator with either a blog identifier 51 | or the `@t` 'dashboard'. The latter will show the latest posts from your 52 | dashboard. 53 | 54 | :dojo> +tumblr/feed 55 | -------------------------------------------------------------------------------- /wip/web/examples/app/up.md: -------------------------------------------------------------------------------- 1 | # `:up` 2 | 3 | Source: 4 | 5 | - `/app/up.hoon` 6 | 7 | `:dojo`: 8 | 9 | ~your-urbit:dojo/examples> |start %up 10 | 11 | ~your-urbit:dojo/examples> :up &atom 'https://www.example.com' 12 | 13 | ~your-urbit:dojo/examples> :up &atom %on 14 | 15 |
16 | 17 | This app continually pings a server at the 'target' URL. 18 | 19 | Start the app from `:dojo`, set the URL you want to ping and set your 'pinger' 20 | to `%on`. You should receive either: 21 | 22 | [%all-is-well 200] 23 | 24 | or 25 | 26 | [%we-have-a-problem {status-code}] 27 | 28 | Then, to turn the 'pinger' off: 29 | 30 | ~your-urbit:dojo/examples> :up &atom %off 31 | 32 | Let's walk through what happened, step by step: 33 | 34 | - The first URL `:dojo` nouns was type-checked by `mar/atom.hoon` and 35 | converted into an atom. 36 | 37 | - The validated atom was then passed to the `++poke-atom` arm in the `up.hoon` 38 | app. 39 | 40 | - `++poke-atom` saves the text url as `target` in the app state. 41 | 42 | - We poked `up.hoon` again with the `%on` atom; `%on` also got type-checked 43 | and converted to an atom via `mar/atom.hoon` and got passed to 44 | `++poke-atom`. This time with the text `on`, this pinged the target url with 45 | an http request. 46 | 47 | - `++sigh-httr` receives the http response and displays the result. It then 48 | calls `++wake-timer`, telling it to wait 10 seconds before pinging the 49 | target url again. This process repeats until you poke the app again with 50 | `off`. 51 | -------------------------------------------------------------------------------- /wip/web/examples/app/wiki.md: -------------------------------------------------------------------------------- 1 | # `:wiki` 2 | 3 | Source: 4 | 5 | - `/app/wiki.hoon` 6 | - `/mar/wiki/articles.hoon` 7 | - `/mar/wiki/change.hoon` 8 | - `/sur/wiki.hoon` 9 | - `/web/pages/wiki/main.js` 10 | - `/web/pages/wiki/marked/marked.min.js` 11 | - `/web/pages/wiki/vue-router/vue-router.js` 12 | - `/web/pages/wiki/vue/vue.js` 13 | - `/web/pages/wiki/wiki.css` 14 | 15 | `:dojo`: 16 | 17 | ~your-urbit:dojo/examples> |start %wiki 18 | ~your-urbit:dojo/examples> :wiki [%serve %examples] 19 | 20 |
21 | 22 | See: [Wiki for Urbit](https://github.com/asssaf/urbit-wiki) 23 | 24 | Thanks, `~rophex-hashes`! 25 | -------------------------------------------------------------------------------- /wip/web/examples/gen.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Generators 3 | --- 4 | 5 | # Generators 6 | 7 | Generators are short Urbit shell scripts. 8 | 9 | Generators live under `/gen` in a `%clay` desk, and are invoked with `+name` at 10 | the `:dojo` prompt. 11 | 12 | We've grouped generators by section, like `hello`. To run one you'll need the 13 | directory prefix: 14 | 15 | ~your-urbit:dojo> +hello/h1 16 | 'Hello, world!' 17 | 18 | Get started with one below! 19 | 20 | #### Hello, world! 21 | 22 | **Command:**\\ `~your-urbit:dojo/examples> +hello/h1` 23 | 24 | **Source**:\\ `/gen/hello/h1.hoon` 25 | 26 | #### Hello, Mars! 27 | 28 | **Command:**\\ `~your-urbit:dojo/examples> +hello/h2 'Mars'` 29 | 30 | **Source**:\\ `/gen/hello/h2.hoon` 31 | 32 | #### Hello, {default}! 33 | 34 | **Commands:**\\ `~your-urbit:dojo/examples> +hello/h3, =txt 'Mars'`\\ 35 | `~your-urbit:dojo/examples> +hello/h3` 36 | 37 | **Source**:\\ `/gen/hello/h3.hoon` 38 | 39 | #### Project Euler 1 40 | 41 | > [Multiples of 3 and 5](https://projecteuler.net/problem=2) 42 | 43 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p1` 44 | 45 | **Source**:\\ `/gen/project-euler/p1.hoon` 46 | 47 | #### Project Euler 2 48 | 49 | > [Even Fibonacci numbers](https://projecteuler.net/problem=2) 50 | 51 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p2` 52 | 53 | **Source**:\\ `/gen/project-euler/p2.hoon` 54 | 55 | #### Project Euler 3 56 | 57 | > [Largest prime factor](https://projecteuler.net/problem=3) 58 | 59 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p3` 60 | 61 | **Source**:\\ `/gen/project-euler/p3.hoon` 62 | 63 | #### Project Euler 4 64 | 65 | > [Largest palindrome product](https://projecteuler.net/problem=4) 66 | 67 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p4` 68 | 69 | **Source**:\\ `/gen/project-euler/p4.hoon` 70 | 71 | #### Project Euler 5 72 | 73 | > [Smallest multiple](https://projecteuler.net/problem=5) 74 | 75 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p5` 76 | 77 | **Source**:\\ `/gen/project-euler/p5.hoon` 78 | 79 | #### Project Euler 6 80 | 81 | > [Sum square difference](https://projecteuler.net/problem=6) 82 | 83 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p6` 84 | 85 | **Source**:\\ `/gen/project-euler/p6.hoon` 86 | 87 | #### Project Euler 9 88 | 89 | > [Special Pythagorean triplet](https://projecteuler.net/problem=9) 90 | 91 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p9` 92 | 93 | **Source**:\\ `/gen/project-euler/p9.hoon` 94 | 95 | #### Project Euler 14 96 | 97 | > [Special Pythagorean triplet](https://projecteuler.net/problem=14) 98 | 99 | **Commands:**\\ `~your-urbit:dojo/examples> +project-euler/p14` 100 | 101 | **Source**:\\ `/gen/project-euler/p14.hoon` 102 | 103 | #### Brainf\*\*k > [Wikipedia](https://en.wikipedia.org/wiki/Brainfuck) > > [Esolangs](https://projecteuler.net/problem=14) 104 | 105 | **Commands:**\\ `~your-urbit:dojo/examples> +fun/bf 42` 106 | 107 | **Source**:\\ `/gen/fun/bf.hoon` 108 | -------------------------------------------------------------------------------- /wip/web/examples/lib.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Libraries 3 | --- 4 | 5 | # Libraries 6 | 7 | This directory contains Hoon library modules. 8 | 9 | Libraries live under `/lib` in a `%clay` desk. Each library core contains a 10 | number of arms that take input samples and produce output products. 11 | 12 | First, you need to load the library core into your current `:dojo` subject with 13 | the `/+` `%ford` rune, then to call a library arm you must evaluate it against 14 | the name of the library core. For example, load the `/lib/nock.hoon` library and 15 | decrement a number in `:dojo` using the Nock `++dec` implementation: 16 | 17 | ~your-urbit:dojo/examples> /+ nock 18 | ~your-urbit:dojo/examples> (dec:nock 43) 19 | 42 20 | 21 | (Note the two spaces - this is a tall-form `%ford` rune) 22 | 23 | You can also call the `++test` arm of the library without a sample to evaluate 24 | the test expression in the library file. Here's `++test` in `/lib/sorts`: 25 | 26 | ~your-urbit:dojo/examples> /+ sorts 27 | ~your-urbit:dojo/examples> (test:sorts) 28 | [ [%insertion-sort ~[1 1 2 3 5 8 13]] 29 | [%bubble-sort ~[1 1 2 3 5 8 13]] 30 | %merge-sort ~[1 1 2 3 5 8 13] 31 | ] 32 | 33 | When you're done, simply enter a blank `/+` to reset `:dojo` to the normal 34 | subject. 35 | 36 |
37 | 38 | Try them all! 39 | 40 | #### L-99: Ninety-Nine Lisp Problems 41 | 42 | **Command:**\\ `~your-urbit:dojo/examples> /+ lisp99`\\ 43 | `~your-urbit:dojo/examples> (test:lisp99)` 44 | 45 | **Source**:\\ `/lib/lisp99.hoon` 46 | 47 | #### Nock: Urbit's Nano-VM 48 | 49 | **Command:**\\ `~your-urbit:dojo/examples> /+ nock`\\ 50 | `~your-urbit:dojo/examples> (test:nock)` 51 | 52 | **Source**:\\ `/lib/nock.hoon` 53 | 54 | #### S-Expression Parser 55 | 56 | **Command:**\\ `~your-urbit:dojo/examples> /+ parse-sexpr`\\ 57 | `~your-urbit:dojo/examples> (test:parse-sexpr)` 58 | 59 | **Source**:\\ `/lib/parse-sexpr.hoon` 60 | 61 | #### SKI Combinator Calculus 62 | 63 | **Command:**\\ `~your-urbit:dojo/examples> /+ ski`\\ 64 | `~your-urbit:dojo/examples> (test:ski)` 65 | 66 | **Source**:\\ `/lib/ski.hoon` 67 | 68 | #### Sorting algorithms 69 | 70 | **Command:**\\ `~your-urbit:dojo/examples> /+ sorts`\\ 71 | `~your-urbit:dojo/examples> (test:sorts)` 72 | 73 | **Source**:\\ `/lib/sorts.hoon` 74 | 75 | #### String processing library 76 | 77 | **Command:**\\ `~your-urbit:dojo/examples> |start %string-tester`\\ 78 | `~your-urbit:dojo/examples> :string-tester %test` 79 | 80 | **Source**:\\ `/lib/string.hoon` 81 | 82 | **See**:\\ [String processing library for 83 | Urbit](https://github.com/Fang-/urbit-string) 84 | 85 | #### Knuth-Morris-Pratt String Search 86 | 87 | **Command:**\\ `~your-urbit:dojo/examples> /+ strings-kmp`\\ 88 | `~your-urbit:dojo/examples> (test:strings-kmp)` 89 | 90 | **Source**:\\ `/lib/strings-kmp.hoon` 91 | 92 | #### Pig Latin 93 | 94 | **Command:**\\ `~your-urbit:dojo/examples> /+ strings-piglatin`\\ 95 | `~your-urbit:dojo/examples> (test:strings-piglatin)` 96 | 97 | **Source**:\\ `/lib/strings-piglatin.hoon` 98 | -------------------------------------------------------------------------------- /wip/web/examples/mar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Marks 3 | --- 4 | 5 | # Marks 6 | 7 | A mark is Urbit's version of a MIME type, if a MIME type was an executable 8 | specification. 9 | 10 | Marks live under `/mar` in a `%clay` desk. A mark is just a label that's used as 11 | a path to one of these local source files in the Arvo filesystem. This source 12 | file defines a core that can mold untrusted data, diff and patch, convert to and 13 | from other marks, and more. 14 | 15 | The syntax for molding data from one mark to another is similar to 16 | [casting](https://urbit.org/docs/hoon/twig/ket-cast) from a noun of one mold to 17 | another (and, in fact, mark cores use mold casting under the hood for their 18 | implementations; notice the distinction between type-checking data at the Hoon 19 | level versus validating data at the OS level). A simple example is converting an 20 | atom received as a noun (`*`) into an urbit (`@p`) name. This uses the following 21 | syntax in `:dojo`: 22 | 23 | ~your-urbit:dojo> &urbit &noun 0 24 | ~zod 25 | 26 | Values in the `:dojo` are `&nouns` by default, so you don't need to convert your 27 | data to them explicitly in it: 28 | 29 | ~your-urbit:dojo> &urbit 0 30 | ~zod 31 | 32 | `++poke` arms in `%gall` apps are named by the mark of the data they accept as 33 | samples. For example, `app/square` has a `++poke-atom` arm that takes an atom 34 | validated by the mark system and squares the value. In `:dojo`: 35 | 36 | ~your-urbit:dojo> |start %square 37 | ~your-urbit:dojo> :square &atom 10 38 | [%square 100] 39 | 40 | A `mesh-color` works the same way: 41 | 42 | ~your-urbit:dojo> |start %mesh 43 | ~your-urbit:dojo> :mesh &mesh-color '#000000' 44 | 'Color set! Notifying subscribers:' 45 | [%color '#000000'] 46 | 47 | Many app marks import the same molds from their corresponding structures in 48 | `/sur` that are used in the app. This keeps structure implementations in one 49 | place. See the `sur` page for more details on structures. 50 | 51 | All of the example `%gall` apps have poke arms that take certain mark types as 52 | samples (in the case of `:feed`, `:feed` uses `:talk` as the backend; you can 53 | find the poke arms the web UI is calling by searching for `/app/talk.hoon` for 54 | the `++poke-mark-name` arms). View the source for some of these custom molds 55 | used by these example `%gall` apps and start to play around with them in your 56 | `:dojo`: 57 | 58 | - `/mar/click/click.hoon` 59 | - `/mar/click/clicks.hoon` 60 | - `/mar/hello/world.hoon` 61 | - `/mar/mail/message.hoon` 62 | - `/mar/mail/send.hoon` 63 | - `/mar/mesh/color.hoon` 64 | - `/mar/mesh/friend.hoon` 65 | - `/mar/mesh/friends.hoon` 66 | - `/mar/mesh/network.hoon` 67 | - `/mar/ping/message.hoon` 68 | -------------------------------------------------------------------------------- /wip/web/examples/sur.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Structures 3 | --- 4 | 5 | # Structures 6 | 7 | A Hoon structure file is simply a module containing one or several cores 8 | defining any number of molds. 9 | 10 | Structures live under `/sur` in a `%clay` desk. Keeping structures in one place 11 | allows for them to be used in multiple places, like apps, app marks and app 12 | libraries. Basically, libraries are for sharing code, and structures are for 13 | sharing data structures to use in Hoon code. See the [`lib`](/~~/examples/lib) 14 | page for more details on libraries. 15 | 16 | Just like you can add library cores to your `:dojo` subject to access the code 17 | arms within them, you can add structure cores to your `:dojo` subject to access 18 | the mold arms within them. This uses the same library importing syntax except 19 | with the `%ford` rune `/-` for structures instead of `/+`. 20 | 21 | Load a structure `/sur/name.hoon` into your current `:dojo` subject using the 22 | following command syntax: 23 | 24 | ~your-urbit:dojo/examples> /- name 25 | 26 | (Note the two spaces - this is a tall-form `%ford` rune) 27 | 28 | Each structure arm maps to a [mold](https://urbit.org/~~/docs/hoon/basic/), an 29 | idempotent validator gate. You can cast a `:dojo` noun into the corresponding 30 | typed data of a structure mold, if the noun is in the mold's span. If the 31 | structure is a core with arms, the syntax used to access the arm is `arm:core`. 32 | For example, the `clicks` mold for the `:click` app (the value held in the app 33 | state of `:click`): this is just an unsigned decimal number (`@ud`) counting the 34 | number of times the app has been "clicked" (poked). From `:dojo`: 35 | 36 | ~your-urbit:dojo/examples> /- click 37 | ~your-urbit:dojo/examples> `clicks:click`42 38 | 42 39 | 40 | If the structure file contains only a single, unarmed mold, you can simply use 41 | the structure file name to reference the single mold. A good example is the 42 | `ping-message` structure. 43 | 44 | ~your-urbit:dojo/examples> /- ping-message 45 | ~your-urbit:dojo/examples> `ping-message`[~zod 'Hey, neighbor!'] 46 | [to=~zod message='Hey, neighbor!'] 47 | 48 | When you're done, simply enter a blank `/-` to reset `:dojo` to the normal 49 | subject. 50 | 51 |
52 | 53 | View the source for some custom structures used by the example apps in this 54 | repository and start to play around with them in your `:dojo`: 55 | 56 | - `/sur/click.hoon` 57 | - `/sur/mail/message.hoon` 58 | - `/sur/mail/send.hoon` 59 | - `/sur/mesh.hoon` 60 | - `/sur/ping/message.hoon` 61 | -------------------------------------------------------------------------------- /wip/web/examples/web.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Web 3 | --- 4 | 5 | # Web 6 | 7 | Here you'll find the files for the example `%gall` applications that have a web 8 | frontend, as well as standalone `%ford` web examples that show how to use the 9 | Urbit build system to render data to the web. 10 | 11 | Web files live under `/web` in a `%clay` desk. The Urbit example web pages here 12 | are written in *Sail*, Hoon markup for XML. Using Sail for rendering web files 13 | allows us to embed Hoon code in our XML and vice versa, offering a pure 14 | functional programming boost to raw HTML (vaguely similar to JSX in the React 15 | world). A Fora post overviewing Sail syntax can be found 16 | [here](https://urbit.org/~~/fora/posts/~2017.7.6..21.27.00..bebb~/): 17 | 18 | Each examples `%gall` app that has a web interface has a Sail file to render and 19 | serve to the web. See the [`app`](/~~/examples/app) page for those. 20 | 21 | This section contains simpler, more isolated `%ford` web examples to demonstrate 22 | how to use Sail. These are being served at: 23 | 24 | http://localhost:8443/~~/pages/ford/{n} 25 | 26 | where `{n}` is the number of the example, and the true `%clay` path is 27 | `/~your-urbit/examples/{latest case or current date}/web/pages/ford/{n}` or 28 | `/===/web/pages/{n}`. Your `%ford` build system will render the `{n}.hoon` Sail 29 | file and serve that to the web at that URL. 30 | 31 | Get started with a `%ford` web example by clicking below: 32 | 33 | - [`%ford 1`: Simple HTML](/~~/pages/ford/1) 34 | - [`%ford 2`: Call a Function](/~~/pages/ford/2) 35 | - [`%ford 3`: Assignment](/~~/pages/ford/3) 36 | - [`%ford 4`: Cores 1](/~~/pages/ford/4) 37 | - [`%ford 5`: Cores 2](/~~/pages/ford/5) 38 | - [`%ford 6`: Loops](/~~/pages/ford/6) 39 | - [`%ford 7`: Page Variables](/~~/pages/ford/7) 40 | - [`%ford 8`: Query String Parameters](/~~/pages/ford/8) 41 | - [`%ford 9`: Computing with Parameters](/~~/pages/ford/9) 42 | - [`%ford 10`: Breaking Code Into Parts](/~~/pages/ford/10) 43 | - [`%ford 11`: Computing with Parameters (and Libraries)](/~~/pages/ford/11) 44 | - [`%ford 12`: Loading Resources by Number](/~~/pages/ford/12) 45 | 46 |
47 | 48 | > The examples pages that you're reading now are also in here, as well as the 49 | > Docs if you cloned and copied them. :) 50 | -------------------------------------------------------------------------------- /wip/web/pages/feed.hoon: -------------------------------------------------------------------------------- 1 | !: 2 | ^- manx 3 | ;html 4 | ;head 5 | ;meta(charset "UTF-8"); 6 | ;meta 7 | =name "viewport" 8 | =content "width=device-width, initial-scale=1.0"; 9 | ;title: Examples - Feed 10 | ;script 11 | =type "text/javascript" 12 | =src "/~~/~/at/lib/js/urb.js"; 13 | ;script 14 | =type "text/javascript" 15 | =src "/~~/pages/feed/feed.js"; 16 | ;link 17 | =type "text/css" 18 | =rel "stylesheet" 19 | =href "/~~/pages/feed/feed.css"; 20 | == 21 | ;body 22 | ;h1: :feed 23 | ;div(id "loading"): Loading... 24 | ;div(id "home"); 25 | ;br; 26 | ;div 27 | ;input 28 | =id "fetchBox" 29 | =type "text" 30 | =placeholder "~tonlur-sarret"; 31 | ;br; 32 | ;button(onclick "fetch();"): Fetch 33 | == 34 | ;br; 35 | ;div 36 | ;h1(id "shipDisplay", class "ship-display"); 37 | == 38 | ;br; 39 | ;div 40 | ;button 41 | =id "subscribeButton" 42 | =class "hidden" 43 | =onclick "subscribe();": Subscribe 44 | == 45 | ;br; 46 | ;div 47 | ;button 48 | =id "unsubscribeButton" 49 | =class "hidden" 50 | =onclick "subscribe();": Unsubscribe 51 | == 52 | ;br; 53 | ;div 54 | ;input 55 | =id "postBox" 56 | =class "hidden" 57 | =type "text" 58 | =maxlength "64" 59 | =placeholder "Hello, world!"; 60 | ;br; 61 | ;button 62 | =id "postButton" 63 | =class "hidden" 64 | =onclick "fetch();": Post 65 | == 66 | ;br; 67 | ;div(id "posts"); 68 | ;script 69 | ; if (!(window.location.search)) { 70 | ; document.getElementById('shipDisplay').innerHTML = '~' + window.urb.user; 71 | ; } else { 72 | ; document.getElementById('home').innerHTML = ''; 73 | ; document.getElementById('shipDisplay').innerHTML = '~' + window.location.search.substring(7); 74 | ; } 75 | 76 | ; document.getElementById('fetchBox').addEventListener('keyup', function fetchOnEnter(event) { 77 | ; if (!event) { event = window.event; } 78 | ; event.preventDefault(); 79 | ; if (event.keyCode === 13) { fetch(); } 80 | ; }, false); 81 | ; document.getElementById('postBox').addEventListener('keyup', function postOnEnter(event) { 82 | ; if (!event) { event = window.event; } 83 | ; event.preventDefault(); 84 | ; if (event.keyCode === 13) { sendPost(); } 85 | ; }, false); 86 | ; document.getElementById('loading').classList.remove('hidden'); 87 | == 88 | == 89 | == 90 | -------------------------------------------------------------------------------- /wip/web/pages/feed/feed.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "scp"; 3 | src: url("//media.urbit.org/fonts/scp-regular.woff"); 4 | font-weight: 400; 5 | font-style: normal; 6 | } 7 | 8 | h1 { 9 | font-family: scp, monospace; 10 | } 11 | 12 | 13 | #loading { 14 | position: absolute; 15 | top: 0; left: 0; 16 | background-color: #000; 17 | color: #fff; 18 | padding: 20px; 19 | } 20 | 21 | .hidden { 22 | display: none; 23 | } 24 | 25 | body { 26 | font-family: sans-serif; 27 | } 28 | 29 | .ship-display { 30 | font-family: scp, monospace; 31 | } 32 | 33 | input, 34 | button { 35 | border: 3px solid #000; 36 | padding: 10px; 37 | font-size: 18px; 38 | } 39 | 40 | input { 41 | line-height: 20px; 42 | width: 84%; 43 | max-width: 600px; 44 | font-family: sans-serif; 45 | } 46 | 47 | button { 48 | background-color: #fff; 49 | color: #000; 50 | font-weight: 500; 51 | display: block; 52 | margin-top: 12px; 53 | } 54 | 55 | button:hover { 56 | background-color: #000; 57 | color: #fff; 58 | cursor: pointer; 59 | } 60 | -------------------------------------------------------------------------------- /wip/web/pages/feed/init.hoon: -------------------------------------------------------------------------------- 1 | !: 2 | ^- manx 3 | ;html 4 | ;head 5 | ;meta(charset "UTF-8"); 6 | ;meta(name "viewport", content "width=device-width, initial-scale=1.0"); 7 | ;title: Examples - Initialize Feed 8 | ;script(type "text/javascript", src "/~~/~/at/lib/js/urb.js"); 9 | ;script(type "text/javascript", src "/pages/feed/init.js"); 10 | ;link(type "text/css", rel "stylesheet", href "/pages/feed/feed.css"); 11 | == 12 | ;body 13 | ;div(id "loading"): Loading... 14 | ;div(id "feedButton"); 15 | == 16 | == 17 | -------------------------------------------------------------------------------- /wip/web/pages/feed/init.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | // main 4 | 5 | var feedURL = window.location.protocol + '//' + window.location.host + '/~~/pages/feed'; 6 | var redirectButton = ''; 7 | 8 | function redirect() { 9 | window.location.href = feedURL; 10 | } 11 | 12 | function subscribe() { 13 | var design = { 14 | design: { 15 | party: 'feed', 16 | config: { 17 | sources: [ 18 | '~' + window.urb.user + '/public' 19 | ], 20 | caption: '~' + window.urb.user + "'s Feed.", 21 | cordon: { 22 | posture: 'green', 23 | list: [] 24 | } 25 | } 26 | } 27 | }; 28 | 29 | window.urb.send( 30 | design, // data 31 | { // params 32 | appl: 'talk', 33 | mark: 'talk-command', 34 | ship: window.urb.user 35 | }, 36 | function subscribed(error, response) { // callback 37 | if (error || !response.data || response.fail) { 38 | console.warn('`urb.send` to ~' + window.urb.user + ' the data payload:'); 39 | console.warn(design); 40 | console.warn('failed. Error:'); 41 | console.warn(error); 42 | console.warn(response); 43 | return; 44 | } 45 | console.log('`urb.send` to ~' + window.urb.user + ' the data payload:'); 46 | console.log(design); 47 | console.log('succeeded! Response:'); 48 | console.log(response.data); 49 | document.getElementById('feedButton').innerHTML = redirectButton; 50 | document.getElementById('loading').classList.add('hidden'); 51 | }); 52 | } 53 | 54 | function lookHouse(house) { 55 | var feedCreated = false; 56 | house.forEach(function checkForFeed(station) { 57 | if (station.name === 'feed') { 58 | document.getElementById('feedButton').innerHTML = redirectButton; 59 | feedCreated = true; 60 | document.getElementById('loading').classList.add('hidden'); 61 | } 62 | }); 63 | 64 | if (!(feedCreated === true)) { 65 | subscribe(); 66 | } 67 | } 68 | 69 | // onLoad 70 | 71 | (function bindHouse() { // bind to all local stations on ship. 72 | var path = '/'; // path for `house`. 73 | return window.urb.bind( 74 | path, // path 75 | { // params 76 | appl: 'talk', 77 | mark: 'json', 78 | ship: window.urb.user 79 | }, 80 | function gotHouse(error, response) { // callback 81 | if (error || !response.data || response.fail) { 82 | console.warn('urb.bind at path `' + path + '` failed. Error: '); 83 | console.warn(error); 84 | console.warn(response); 85 | return; 86 | } 87 | console.log('urb.bind at path: `' + path + '` succeeded! Response data: '); 88 | console.log(response.data); 89 | lookHouse(response.data.house); 90 | }); 91 | }()); 92 | 93 | window.module = window.module || {}; // eslint-disable-line no-global-assign 94 | module.exports = { 95 | redirect: redirect, 96 | subscribe: subscribe 97 | }; 98 | -------------------------------------------------------------------------------- /wip/web/pages/foos.hoon: -------------------------------------------------------------------------------- 1 | /= gas 2 | /$ fuel:html 3 | :: 4 | !: 5 | ^- manx 6 | ;html 7 | ;head 8 | ;meta(charset "UTF-8"); 9 | ;meta 10 | =name "viewport" 11 | =content "width=device-width, initial-scale=1.0"; 12 | ;title: Examples - Foos 13 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/foos/foos.css"); 14 | ;script@"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"; 15 | ;script@"https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js"; 16 | ;script@"/~~/~/at/lib/js/urb.js"; 17 | == 18 | ;body 19 | ;h1: :foos 20 | ;div#container; 21 | ;script@"/~~/pages/foos/foos.js"; 22 | == 23 | == 24 | -------------------------------------------------------------------------------- /wip/web/pages/foos/foos.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "scp"; 3 | src: url("//media.urbit.org/fonts/scp-regular.woff"); 4 | font-weight: 400; 5 | font-style: normal; 6 | } 7 | 8 | body, 9 | html { 10 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 11 | font-size: 18px; 12 | } 13 | 14 | h1 { 15 | font-family: scp, monospace; 16 | } 17 | 18 | #container { 19 | position: absolute; 20 | width: 32rem; 21 | left: 50%; 22 | margin-left: -16rem; 23 | } 24 | 25 | input { 26 | outline: none; 27 | font-size: 1rem; 28 | border: 0; 29 | padding: .3rem; 30 | } 31 | 32 | input, 33 | button { 34 | font-family: inherit; 35 | } 36 | 37 | input.black { 38 | background-color: #000; 39 | color: #fff; 40 | } 41 | 42 | input.yellow { 43 | background-color: rgb(249, 255, 0); 44 | color: #000; 45 | } 46 | 47 | button { 48 | background-color: transparent; 49 | font-size: .8rem; 50 | border: 3px solid #000; 51 | margin-left: -.3rem; 52 | text-align: left; 53 | text-transform: uppercase; 54 | font-weight: 500; 55 | } 56 | 57 | #afix div, 58 | input, 59 | ul.fixturesList li > div { 60 | margin-right: 2rem; 61 | } 62 | 63 | #afix div, 64 | ul.standings li:first-child div{ 65 | font-weight: 600; 66 | } 67 | 68 | ul, 69 | li { 70 | list-style-type: none; 71 | } 72 | 73 | ul { 74 | padding: 0; 75 | } 76 | 77 | #afix div, 78 | ul li > div { 79 | display: inline-block; 80 | } 81 | 82 | .pending { 83 | opacity: .5; 84 | } 85 | 86 | .contestant { 87 | width: 6rem; 88 | } 89 | 90 | .score { 91 | width: 4rem; 92 | } 93 | 94 | .standings { 95 | display: block; 96 | border-top: 3px solid #000; 97 | padding-top: 1 rem; 98 | } 99 | 100 | 101 | .standElem { 102 | width: 6rem; 103 | } 104 | -------------------------------------------------------------------------------- /wip/web/pages/ford/1.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 1 2 | :: accessible at http://localhost:8443/~~/pages/ford/1 3 | :: 4 | :::: /===/web/pages/ford/1/hoon 5 | :: 6 | ;html 7 | ;head 8 | ;meta(charset "utf-8"); 9 | ;title: Examples - Ford 1 10 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 11 | == 12 | ;body 13 | ;h1#title: %ford: 1 14 | ;div 15 | ;h1: Simple HTML 16 | ;p: As you may notice, Urbit has no problem talking to the web. 17 | == 18 | == 19 | == 20 | -------------------------------------------------------------------------------- /wip/web/pages/ford/10.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 10 2 | :: accessible at http://localhost:8443/~~/pages/ford/10 3 | :: 4 | :::: /===/web/pages/ford/10/hoon 5 | :: 6 | /= gas 7 | /$ fuel:html 8 | :: 9 | // /%%/10/lib 10 | ^- manx 11 | ;html 12 | ;head 13 | ;meta(charset "utf-8"); 14 | ;title: Examples - Ford 10 15 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 16 | == 17 | ;body 18 | ;h1#title: %ford: 10 19 | ;div 20 | ;h1: Breaking Code Into Parts 21 | ;div: {<(fib 70)>} 22 | == 23 | == 24 | == 25 | -------------------------------------------------------------------------------- /wip/web/pages/ford/10/lib.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | ++ fib 3 | |= x/@ 4 | ~+ 5 | ?: (lth x 2) 6 | 1 7 | (add $(x (dec x)) $(x (sub x 2))) 8 | -- 9 | -------------------------------------------------------------------------------- /wip/web/pages/ford/11.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 11 2 | :: accessible at http://localhost:8443/~~/pages/ford/11 3 | :: 4 | :::: /===/web/pages/ford/11/hoon 5 | :: 6 | /= gas 7 | /$ fuel:html 8 | // /%%/11/lib 9 | :: 10 | !: 11 | =+ ^= arg 12 | %+ slav 13 | %ud 14 | %+ fall 15 | %- ~(get by qix.gas) %number 16 | '0' 17 | :: 18 | ^- manx 19 | ;html 20 | ;head 21 | ;meta(charset "utf-8"); 22 | ;title: Examples - Ford 11 23 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 24 | == 25 | ;body 26 | ;h1#title: %ford: 11 27 | ;h1: Computing With Parameters (and Libraries) 28 | ;div: {<(fib arg)>} 29 | == 30 | == 31 | -------------------------------------------------------------------------------- /wip/web/pages/ford/11/lib.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | ++ fib 3 | |= x/@ 4 | ~+ 5 | ?: (lth x 2) 6 | 1 7 | (add $(x (dec x)) $(x (sub x 2))) 8 | -- 9 | -------------------------------------------------------------------------------- /wip/web/pages/ford/12.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 12 2 | :: accessible at http://localhost:8443/~~/pages/ford/12 3 | :: 4 | :::: /===/web/pages/ford/12/hoon 5 | :: 6 | /= posts /: /%%/12/lib 7 | /; |= a=(list [@ud manx]) 8 | (turn (sort a lor) tail) 9 | /; |= a=(map @ manx) 10 | ~& a 11 | %+ murn 12 | ~(tap by a) 13 | |= [a=@ b=manx] 14 | ^- (unit [@ud manx]) 15 | =+ c=(slaw %ud a) 16 | ?~ c ~ 17 | `[u.c b] 18 | /_ 19 | /elem/ 20 | :: 21 | !: 22 | ^- manx 23 | ;html 24 | ;head 25 | ;meta(charset "utf-8"); 26 | ;title: Examples - Ford 12 27 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 28 | == 29 | ;body 30 | ;h1#title: %ford: 12 31 | ;div 32 | ;h1: Loading Resources by Number 33 | ;* posts 34 | == 35 | == 36 | == 37 | -------------------------------------------------------------------------------- /wip/web/pages/ford/12/lib/1.md: -------------------------------------------------------------------------------- 1 | # 1 2 | 3 | This is my first post. 4 | -------------------------------------------------------------------------------- /wip/web/pages/ford/12/lib/2.md: -------------------------------------------------------------------------------- 1 | # 2 2 | 3 | This is my second post. 4 | -------------------------------------------------------------------------------- /wip/web/pages/ford/2.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 2 2 | :: accessible at http://localhost:8443/~~/pages/ford/2 3 | :: 4 | :::: /===/web/pages/ford/2/hoon 5 | :: 6 | ;html 7 | ;head 8 | ;meta(charset "utf-8"); 9 | ;title: Examples - Ford 2 10 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 11 | == 12 | ;body 13 | ;h1#title: %ford: 2 14 | ;div 15 | ;h1: Call a Function 16 | ;p: Although it may be obvious, 2+2={<(add 2 2)>} 17 | == 18 | == 19 | == 20 | -------------------------------------------------------------------------------- /wip/web/pages/ford/3.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 3 2 | :: accessible at http://localhost:8443/~~/pages/ford/3 3 | :: 4 | :::: /===/web/pages/ford/3/hoon 5 | :: 6 | =+ ^= a 1 7 | =+ b=2 8 | :: 9 | ^- manx 10 | ;html 11 | ;head 12 | ;meta(charset "utf-8"); 13 | ;title: Examples - Ford 3 14 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 15 | == 16 | ;body 17 | ;h1#title: %ford: 3 18 | ;div 19 | ;h1: Assignment 20 | ;p: a={} 21 | ;p: b={} 22 | ;p: a+b={<(add a b)>} 23 | == 24 | == 25 | == 26 | -------------------------------------------------------------------------------- /wip/web/pages/ford/4.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 4 2 | :: accessible at http://localhost:8443/~~/pages/ford/4 3 | :: 4 | :::: /===/web/pages/ford/4/hoon 5 | :: 6 | |% 7 | ++ start 1 8 | ++ end 10 9 | ++ length 10 | |= [s=@ud e=@ud] 11 | (sub e s) 12 | -- 13 | :: 14 | ^- manx 15 | ;html 16 | ;head 17 | ;meta(charset "utf-8"); 18 | ;title: Examples - Ford 4 19 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 20 | == 21 | ;body 22 | ;h1#title: %ford: 4 23 | ;div 24 | ;h1: Cores 1 25 | ;p: We'll be starting at {} 26 | ;p: And ending at {} 27 | ;p: Looks like a length of {<(length start end)>} 28 | == 29 | == 30 | == 31 | -------------------------------------------------------------------------------- /wip/web/pages/ford/5.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 5 2 | :: accessible at http://localhost:8443/~~/pages/ford/5 3 | :: 4 | :::: /===/web/pages/ford/5/hoon 5 | :: 6 | |% 7 | += dist [start=@ud end=@ud] 8 | ++ length 9 | |= [d=dist] 10 | (sub end.d start.d) 11 | -- 12 | :: 13 | ^- manx 14 | ;html 15 | ;head 16 | ;meta(charset "utf-8"); 17 | ;title: Examples - Ford 5 18 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 19 | == 20 | ;body 21 | ;h1#title: %ford: 5 22 | ;div 23 | ;h1: Cores 2 24 | ;p: How long does it take to get from 2 to 20? {<(length 2 20)>} 25 | == 26 | == 27 | == 28 | -------------------------------------------------------------------------------- /wip/web/pages/ford/6.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 6 2 | :: accessible at http://localhost:8443/~~/pages/ford/6 3 | :: 4 | :::: /===/web/pages/ford/6/hoon 5 | :: 6 | |% 7 | ++ fib 8 | |= x=@ 9 | ?: (lth x 2) 10 | 1 11 | (add $(x (dec x)) $(x (sub x 2))) 12 | -- 13 | :: 14 | ^- manx 15 | ;html 16 | ;head 17 | ;meta(charset "utf-8"); 18 | ;title: Examples - Ford 6 19 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 20 | == 21 | ;body 22 | ;h1#title: %ford: 6 23 | ;div 24 | ;h1: Loops 25 | ;p: {<(fib 1)>}, {<(fib 2)>}, {<(fib 3)>}, {<(fib 4)>} 26 | == 27 | == 28 | == 29 | -------------------------------------------------------------------------------- /wip/web/pages/ford/7.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 7 2 | :: accessible at http://localhost:8443/~~/pages/ford/7 3 | :: 4 | :::: /===/web/pages/ford/7/hoon 5 | :: 6 | /= gas 7 | /$ fuel:html 8 | :: 9 | ^- manx 10 | ;html 11 | ;head 12 | ;meta(charset "utf-8"); 13 | ;title: Examples - Ford 7 14 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 15 | == 16 | ;body 17 | ;h1#title: %ford: 7 18 | ;div 19 | ;h1: Page Variables 20 | ;div.who: Whoami? {<(~(get ju aut.ced.gas) 0)>} 21 | ;div.where: Whereami? {(spud s.bem.gas)} 22 | ;div.what: Whatcase? {(scow %ud p.r.bem.gas)} 23 | ;div.code: Session auth credential: 24 | ;code 25 | ;pre: {} 26 | == 27 | == 28 | == 29 | == 30 | -------------------------------------------------------------------------------- /wip/web/pages/ford/8.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 8 2 | :: accessible at http://localhost:8443/~~/pages/ford/8 3 | :: 4 | :::: /===/web/pages/ford/8/hoon 5 | :: 6 | /= gas 7 | /$ fuel:html 8 | :: 9 | ^- manx 10 | ;html 11 | ;head 12 | ;meta(charset "utf-8"); 13 | ;title: Examples - Ford 8 14 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 15 | == 16 | ;body 17 | ;h1#title: %ford: 8 18 | ;div 19 | ;h1: Query String Parameters 20 | ;div: Do you have a code? 21 | ;div: ?code={<(fall (~(get by qix.gas) %code) '')>} 22 | == 23 | == 24 | == 25 | -------------------------------------------------------------------------------- /wip/web/pages/ford/9.hoon: -------------------------------------------------------------------------------- 1 | :: Ford example 9 2 | :: accessible at http://localhost:8443/~~/pages/ford/9 3 | :: 4 | :::: /===/web/pages/ford/9/hoon 5 | :: 6 | /= gas 7 | /$ fuel:html 8 | :: 9 | |% 10 | ++ fib 11 | |= x=@ 12 | ?: (lth x 2) 13 | 1 14 | (add $(x (dec x)) $(x (sub x 2))) 15 | ++ arg 16 | %+ fall 17 | %+ biff 18 | (~(get by qix.gas) %number) 19 | (slat %ud) 20 | 0 21 | -- 22 | :: 23 | ^- manx 24 | ;html 25 | ;head 26 | ;meta(charset "utf-8"); 27 | ;title: Examples - Ford 9 28 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 29 | == 30 | ;body 31 | ;h1#title: %ford: 9 32 | ;div 33 | ;h1: Computing With Parameters 34 | ;div: {<(fib arg)>} 35 | == 36 | == 37 | == 38 | -------------------------------------------------------------------------------- /wip/web/pages/ford/ford.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "scp"; 3 | src: url("//media.urbit.org/fonts/scp-regular.woff"); 4 | font-weight: 400; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: "bau"; 10 | src: url("//media.urbit.org/fonts/bau.woff"); 11 | font-weight: 400; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: "bau"; 17 | src: url("//media.urbit.org/fonts/bau-medium.woff"); 18 | font-weight: 500; 19 | font-style: normal; 20 | } 21 | 22 | h1#title { 23 | font-family: scp, monospace; 24 | } 25 | 26 | body { 27 | font-family: bau, sans-serif; 28 | } 29 | 30 | h1 { 31 | font-family: bau, sans-serif; 32 | font-weight: 500; 33 | } 34 | 35 | code { 36 | font-family: scp, monospace; 37 | } 38 | -------------------------------------------------------------------------------- /wip/web/pages/ford/hello.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /===/web/pages/ford/hello/hoon 3 | :: 4 | // /%%/hello/lib 5 | |% 6 | ++ hello 7 | |= * 8 | (weld "Hello, " (weld (trip (world ~)) "!")) 9 | -- 10 | ^- manx 11 | ;html 12 | ;head 13 | ;meta(charset "utf-8"); 14 | ;title: Examples - Ford - Hello 15 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/ford/ford.css"); 16 | == 17 | ;body 18 | ;h1#title: %ford: hello 19 | ;div 20 | ;h1: {(hello ~)} 21 | == 22 | == 23 | == 24 | -------------------------------------------------------------------------------- /wip/web/pages/ford/hello/lib.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | ++ world 3 | |= * 4 | 'world' 5 | -- 6 | -------------------------------------------------------------------------------- /wip/web/pages/lead.hoon: -------------------------------------------------------------------------------- 1 | !: 2 | ^- manx 3 | ;html 4 | ;head 5 | ;meta(charset "UTF-8"); 6 | ;meta 7 | =name "viewport" 8 | =content "width=device-width, initial-scale=1.0"; 9 | ;title: Example - Lead 10 | ;link(type "text/css", rel "stylesheet", href "/~~/pages/lead/lead.css"); 11 | ;script(type "text/javascript", src "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"); 12 | ;script(type "text/javascript", src "/~~/~/at/lib/js/urb.js"); 13 | == 14 | ;body 15 | ;h1#title: :lead 16 | ;div#cont 17 | ;input#add(type "text", placeholder "NAME"); 18 | ;input#go(type "button", value "Add"); 19 | ;div#err(class "disabled"); 20 | ;ul#board 21 | ;li 22 | ;div(class "info") 23 | ;div(class "scor"):"Points" 24 | ;div(class "name"):"Name" 25 | == 26 | == 27 | == 28 | == 29 | ;script(type "text/javascript", src "/~~/pages/lead/lead.js"); 30 | == 31 | == 32 | -------------------------------------------------------------------------------- /wip/web/pages/lead/lead.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "scp"; 3 | src: url("//media.urbit.org/fonts/scp-regular.woff"); 4 | font-weight: 400; 5 | font-style: normal; 6 | } 7 | 8 | body, 9 | input { 10 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 11 | } 12 | 13 | body { 14 | font-size: 18px; 15 | font-weight: 400; 16 | margin: 4rem; 17 | line-height: 2rem; 18 | } 19 | 20 | #cont { 21 | width: 42rem; 22 | margin-left: auto; 23 | margin-right: auto; 24 | } 25 | 26 | h1#title { 27 | font-family: scp, monospace; 28 | } 29 | 30 | h1 { 31 | letter-spacing: 1px; 32 | font-size: 2rem; 33 | margin: 0 0 1rem 0; 34 | } 35 | 36 | input { 37 | outline: none; 38 | border: 3px solid #ccc; 39 | height: 2.3rem; 40 | font-size: 1rem; 41 | } 42 | 43 | input#add { 44 | margin: 0 .2rem 0 0; 45 | } 46 | 47 | ::-webkit-input-placeholder { 48 | letter-spacing: 1px; 49 | } 50 | 51 | :-moz-placeholder { 52 | letter-spacing: 1px; 53 | } 54 | 55 | ::-moz-placeholder { 56 | letter-spacing: 1px; 57 | } 58 | 59 | input#go, 60 | .bump { 61 | border: 3px solid #69F19A; 62 | color: #69F19A; 63 | cursor: pointer; 64 | } 65 | 66 | input#go { 67 | background-color: #fff; 68 | text-align: center; 69 | padding: .2rem .6rem; 70 | } 71 | 72 | #err { 73 | color: #ff1D1D; 74 | margin-top: .5rem; 75 | } 76 | 77 | #err.disabled { 78 | display: none; 79 | } 80 | 81 | ul { 82 | list-style-type:none; 83 | margin: 1rem 0 0 0; 84 | padding: 0; 85 | } 86 | 87 | ul > li { 88 | padding-bottom: .6rem; 89 | } 90 | 91 | ul > li:first-child { 92 | font-size: .8rem; 93 | text-transform: uppercase; 94 | letter-spacing: 1px; 95 | } 96 | 97 | .disabled { 98 | opacity: .5; 99 | } 100 | 101 | li > div { 102 | display: inline-block; 103 | width: 16rem; 104 | } 105 | 106 | .info { 107 | text-align: justify; 108 | } 109 | 110 | .info > div { 111 | display: inline-block; 112 | } 113 | 114 | .scor { 115 | width: 4rem; 116 | } 117 | 118 | .bump { 119 | display: inline-block; 120 | height: 2rem; 121 | max-width: 4rem; 122 | text-align: center; 123 | } 124 | -------------------------------------------------------------------------------- /wip/web/pages/lead/lead.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | var vat, _vat, 3 | $board, $add, $go, $err 4 | 5 | $board = $('#board') 6 | $add = $('#add') 7 | $go = $('#go') 8 | $err = $('#err') 9 | 10 | append_row = function(name,scor) { 11 | id = name.replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '') 12 | $row = $("
  • ") 13 | $info = $("
    ") 14 | info = "
    "+scor+"
    "+ 15 | "
    "+name+"
    " 16 | $info.html(info) 17 | $row.append($info) 18 | $row.append("
    +1
    ") 19 | $board.append($row) 20 | } 21 | 22 | render = function() { 23 | $board.find('li.row').remove() 24 | _vat = [] 25 | keys = Object.keys(vat) 26 | for(k in keys) { 27 | _vat.push([keys[k],vat[keys[k]]]) 28 | } 29 | _vat.sort(function(a,b) { return b[1] - a[1]; }) 30 | for(k in _vat) { 31 | append_row(_vat[k][0],_vat[k][1]) 32 | } 33 | } 34 | 35 | add = function() { 36 | window.urb.send( 37 | {"new-lead":$add.val()} 38 | ,function(err,res) { 39 | if(err) 40 | return $err.removeClass('disabled').text("There was a communication error. Sorry!") 41 | if(res.data !== undefined && 42 | res.data.ok !== undefined && 43 | res.data.ok !== true) 44 | $err.removeClass('disabled').text(res.data.res) 45 | else 46 | $add.val('') 47 | $add.attr('disabled', false).removeClass('disabled') 48 | $go.attr('disabled', false).removeClass('disabled') 49 | }) 50 | $go.attr('disabled', true).addClass('disabled') 51 | $add.attr('disabled', true).addClass('disabled') 52 | $err.addClass('disabled').text('') 53 | } 54 | 55 | $add.on("keyup", function(e) { 56 | if(e.keyCode == 13) 57 | add() 58 | }) 59 | 60 | $go.on("click", add) 61 | 62 | $board.on('click', '.bump', function(e) { 63 | $t = $(e.target).closest('li') 64 | $t.addClass('disabled') 65 | window.urb.send( 66 | {"add-lead":$t.attr('data-id')} 67 | ,function(err,res) { 68 | $t.removeClass('disabled') 69 | }) 70 | }) 71 | 72 | 73 | window.urb.appl = "lead" 74 | window.urb.bind('/', 75 | function(err,dat) { 76 | vat = dat.data 77 | render() 78 | } 79 | ) 80 | window.urb.bind("/data",function(err,res) { 81 | if(!err) { 82 | if(res.data && res.data['upd-lead']) { 83 | name = Object.keys(res.data['upd-lead'])[0] 84 | scor = res.data['upd-lead'][name] 85 | vat[name] = scor 86 | render() 87 | } 88 | } 89 | }) 90 | }) 91 | -------------------------------------------------------------------------------- /wip/web/pages/mail.hoon: -------------------------------------------------------------------------------- 1 | /= gas 2 | /$ fuel:html 3 | !: 4 | ^- manx 5 | ;html 6 | ;head 7 | ;meta(charset "UTF-8"); 8 | ;meta 9 | =name "viewport" 10 | =content "width=device-width, initial-scale=1.0"; 11 | ;title: Example - Mail 12 | ;link(rel "stylesheet", type "text/css", href "/~~/pages/mail/mail.css"); 13 | ;script@"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"; 14 | ;script@"https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js"; 15 | ;script@"/~~/~/at/lib/js/urb.js"; 16 | == 17 | ;body 18 | ;h1: :mail 19 | ;div#container; 20 | ;script@"/~~/pages/mail/mail.js"; 21 | == 22 | == 23 | -------------------------------------------------------------------------------- /wip/web/pages/mail/mail.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "scp"; 3 | src: url("//media.urbit.org/fonts/scp-regular.woff"); 4 | font-weight: 400; 5 | font-style: normal; 6 | } 7 | 8 | body, 9 | html, 10 | button, 11 | input, 12 | textarea { 13 | font-family: sans-serif; 14 | font-size: 18px; 15 | } 16 | 17 | h1 { 18 | font-family: scp, monospace; 19 | } 20 | 21 | .to { 22 | font-family: scp, monospace; 23 | } 24 | 25 | #container { 26 | position: absolute; 27 | left: 50%; 28 | margin-left: -9rem; 29 | } 30 | 31 | #container, 32 | input, 33 | textarea { 34 | width: 18rem; 35 | } 36 | 37 | button, 38 | input, 39 | textarea { 40 | border: 0; 41 | outline: none; 42 | background-color: #f9f9f9; 43 | padding: .3rem; 44 | margin-bottom: 1rem; 45 | } 46 | 47 | button:focus, 48 | input:focus, 49 | textarea:focus { 50 | background-color: #ccc; 51 | } 52 | 53 | button { 54 | border: 2px solid #555; 55 | background-color: #fff; 56 | font-weight: 500; 57 | } 58 | 59 | textarea { 60 | resize: none; 61 | } 62 | 63 | .Message { 64 | border-top: 2px solid #555; 65 | padding-top: 1rem; 66 | margin-bottom: 1rem; 67 | } 68 | -------------------------------------------------------------------------------- /wip/web/pages/mail/mail.js: -------------------------------------------------------------------------------- 1 | recl = React.createClass 2 | div = React.DOM.div 3 | input = React.DOM.input 4 | button = React.DOM.button 5 | textar = React.DOM.textarea 6 | 7 | Page = recl({ // top level component 8 | displayName: 'Page', 9 | 10 | render: function(){ 11 | return div({}, Compose({}), Inbox({messages:this.props.messages})) 12 | } 13 | }) 14 | 15 | Compose = recl({ // compose 16 | displayName: 'Mess', 17 | 18 | validate: function(to,sub,bod){ // validate outgoing 19 | valid = true 20 | if(to[0] !== "~" || to.length < 4) 21 | valid = "to" 22 | if(sub.length < 1) 23 | valid = "sub" 24 | if(bod.length < 1) 25 | valid = "bod" 26 | return valid 27 | }, 28 | 29 | handleClick: function(){ 30 | $to = $(this.getDOMNode()).find('.to') // aliases 31 | $sub = $(this.getDOMNode()).find('.sub') 32 | $bod = $(this.getDOMNode()).find('.bod') 33 | 34 | if(this.validate($to.val(),$sub.val(),$bod.val()) !== true) { // validate 35 | $(this.getDOMNode()).find('.'+valid).focus() // return if needed 36 | return false 37 | } 38 | 39 | urb.send({ // send to server 40 | to: $to.val(), 41 | sub: $sub.val(), 42 | bod: $bod.val() 43 | }, { 44 | appl:"mail", 45 | mark:"mail-send", 46 | }), 47 | 48 | $to.val('') // reset 49 | $sub.val('') 50 | $bod.val('') 51 | }, 52 | 53 | render: function(){ 54 | return( 55 | div({}, 56 | div({}, input({className:"to", placeholder: "To"})), 57 | div({}, input({className:"sub",placeholder: "Subject"})), 58 | div({}, textar({className:"bod",placeholder: "Body"})), 59 | button({onClick:this.handleClick}, "Send") 60 | ) 61 | ) 62 | } 63 | }) 64 | 65 | 66 | Message = recl({ // simple message 67 | render: function(){ 68 | return div({className:"Message"}, 69 | div({className:"fom"}, this.props.message.fom), 70 | div({className:"sub"}, this.props.message.sub), 71 | div({className:"bod"}, this.props.message.bod)) 72 | } 73 | }) 74 | 75 | Inbox = recl({ // list of received messages 76 | displayName: 'Inbox', 77 | 78 | render: function(){ 79 | messages = [] 80 | for (i in this.props.messages){ 81 | messages.push(Message({message:this.props.messages[i]})) 82 | } 83 | return div({}, messages) 84 | } 85 | }) 86 | 87 | $(document).ready(function(){ // render when ready 88 | mounted = React.render(Page({}), $("#container")[0]) 89 | urb.bind("/", {appl:'mail'}, function(e,d){ // bind to backend 90 | mounted.setProps({messages:d.data}) 91 | }) 92 | }) 93 | -------------------------------------------------------------------------------- /wip/web/pages/mesh.hoon: -------------------------------------------------------------------------------- 1 | !: 2 | ^- manx 3 | ;html 4 | ;head 5 | ;meta 6 | =charset "UTF-8"; 7 | ;meta 8 | =name "viewport" 9 | =content "width=device-width, initial-scale=1.0"; 10 | ;title: Examples - Mesh 11 | ;link 12 | =type "text/css" 13 | =rel "stylesheet" 14 | =href "/~~/pages/mesh/mesh.css"; 15 | ;script 16 | =type "text/javascript" 17 | =src "https://d3js.org/d3.v4.js"; 18 | ;script 19 | =type "text/javascript" 20 | =src "/~~/~/at/lib/js/urb.js"; 21 | == 22 | ;body 23 | ;h1: :mesh 24 | ;svg; 25 | ;div(class "inputs") 26 | ;input 27 | =id "subscribeBox" 28 | =class "subscribe" 29 | =type "text" 30 | =maxlength "57" 31 | =placeholder "~tonlur-sarret"; 32 | ;div(class "colors") 33 | ;input 34 | =class "color" 35 | =type "radio" 36 | =style "background: #ee3124" 37 | =onclick "selectColor('#ee3124');"; 38 | ;input 39 | =class "color" 40 | =type "radio" 41 | =style "background: #ffac6e" 42 | =onclick "selectColor('#ffac6e');"; 43 | ;input 44 | =class "color" 45 | =type "radio" 46 | =style "background: #ffd522" 47 | =onclick "selectColor('#ffd522');"; 48 | ;input 49 | =class "color" 50 | =type "radio" 51 | =style "background: #9ee574" 52 | =onclick "selectColor('#9ee574');"; 53 | ;input 54 | =class "color" 55 | =type "radio" 56 | =style "background: #317bff" 57 | =onclick "selectColor('#317bff');"; 58 | ;input 59 | =class "color" 60 | =type "radio" 61 | =style "background: #d27dff" 62 | =onclick "selectColor('#d27dff');"; 63 | == 64 | == 65 | ;script 66 | ; document.getElementById('subscribeBox').addEventListener( 67 | ; 'keyup', 68 | ; function fetchOnEnter(event) { 69 | ; if (!event) { event = window.event; } 70 | ; event.preventDefault(); 71 | ; if (event.keyCode === 13) { subscribe(); } 72 | ; }, false); 73 | == 74 | ;script 75 | =type "text/javascript" 76 | =src "/~~/pages/mesh/mesh.js"; 77 | == 78 | == 79 | -------------------------------------------------------------------------------- /wip/web/pages/mesh/mesh.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "scp"; 3 | src: url("//media.urbit.org/fonts/scp-regular.woff"); 4 | font-weight: 400; 5 | font-style: normal; 6 | } 7 | 8 | line { 9 | /*stroke: #999;*/ 10 | /*stroke-opacity: 0.6;*/ 11 | } 12 | 13 | input.color { 14 | -webkit-appearance: none; 15 | border-radius: 50%; 16 | radius: 5px; 17 | } 18 | .nodes circle { 19 | /*stroke: #fff;*/ 20 | stroke-width: 1.5px; 21 | } 22 | 23 | h1 { 24 | font-family: scp, monospace; 25 | } 26 | 27 | text { 28 | font-family: scp, monospace; 29 | } 30 | 31 | input { 32 | padding: 10px; 33 | font-size: 16px; 34 | text-align: center; 35 | line-height: 18px; 36 | } 37 | 38 | 39 | input.subscribe { 40 | border: 3px solid #000; 41 | border-radius: 10em; 42 | width: 80%; 43 | } 44 | 45 | .colors { 46 | display: block; 47 | margin: auto; 48 | padding: auto; 49 | width: 33%; 50 | } 51 | 52 | .inputs { 53 | display: block; 54 | margin: auto; 55 | width: 33%; 56 | } 57 | -------------------------------------------------------------------------------- /wip/web/pages/taskk.html: -------------------------------------------------------------------------------- 1 | taskk
    -------------------------------------------------------------------------------- /wip/web/pages/taskk/main.css: -------------------------------------------------------------------------------- 1 | div.tile{border-left:10px solid #000;border-bottom:10px solid #000;border-right:10px solid #000;margin-left:-5px;width:calc(100% - 10px);cursor:pointer;-webkit-transition:margin-top .1s;-o-transition:margin-top .1s;transition:margin-top .1s;position:static}div.column:last-child div.tile.expanded{margin-left:calc(-5px - 100%);width:calc(200% - 15px)}div#col2 div.tile.expanded{width:calc(200% - 15px)}div.tile.expanded{height:620px;width:calc(200% - 10px);-webkit-transition-delay:.2s;-o-transition-delay:.2s;transition-delay:.2s;-webkit-transition:height 80ms;-o-transition:height 80ms;transition:height 80ms;-webkit-transition:width 80ms;-o-transition:width 80ms;transition:width 80ms;position:relative;margin-top:-10px;border-top:10px solid #000}div.tile.expanded .description{height:calc(100% - 115px)}div.tile .submit{display:none}div.tile .delete{display:none;color:#a9a9a9;float:left;margin-left:10px;margin-top:7px;font-size:1.7em}div.tile.expanded .delete{display:inherit}div.tile.expanded .delete:hover{color:#000}div.tile.expanded .submit{display:inherit}input.submit:hover{background-color:#000}input.submit{float:right;margin-top:8px;width:80px;margin-right:10px;border-style:none;padding:5px;background-color:#a9a9a9;color:#fff;font-weight:700}div.tile .tile-container{float:left;display:block;width:60%;overflow:hidden;margin-top:10px;margin-left:10px}div.tile .indicator{height:20px;width:20px;margin-right:10px;background-color:#000;float:right;display:none}div.tile.active .indicator{display:block}div.col-container .tile:last-child{border-bottom:10px solid #000}div.column:last-child div.tile{width:calc(100% - 15px)}div.one{height:100px}div.two{height:210px}div.three{height:430px}div.tile .title{text-transform:uppercase}div.tile input.title{border:none;font-weight:700;outline:none;font-size:1em;width:100%}div.tile .description{font-family:scp;width:calc(100% - 30px);height:calc(100% - 80px);padding:10px;background-color:#f5f5f5;overflow:hidden;border:none;outline:none;resize:none;font-size:1em}div#col3 div.tile div.description{width:calc(100% - 20px)}div.tile .assignee{display:none}div.tile input.author{outline:none;border:none;font-size:1em;margin:0;padding:0}div.column{width:25%;float:left}div.headlet{background-color:#000;color:#fff;text-align:center;padding-top:10px;-webkit-transition:height .1s;-o-transition:height .1s;transition:height .1s;height:2em;text-transform:uppercase}div.headlet:hover{height:40px}div.headlet:hover .add-button{display:inherit}div.headlet .add-button{display:none;font-size:1.2em;cursor:pointer}div.col-container.nothing{height:400px}div.headlet .add-button:hover{color:#a9a9a9}body{margin:0;font-family:bau}div#loading-indicator{height:20px;width:20px;background-color:#ff0}.show{display:default;position:absolute}.hide{display:none}#ghost-tile{border-left:10px solid #000;border-bottom:10px solid #000;border-right:10px solid #000;margin-left:-5px;width:300px;cursor:pointer}#ghost-tile .tile-container{float:left;display:block;width:60%;overflow:hidden;margin-top:10px;margin-left:10px}#ghost-tile .title{text-transform:uppercase}#ghost-tile input.title{border:none;font-weight:700;outline:none;font-size:1em;width:100%}#ghost-tile .description{font-family:scp;width:calc(100% - 10px);height:calc(100% - 60px);padding:10px;background-color:#f5f5f5;overflow:hidden;border:none;outline:none;resize:none;font-size:1em}body{margin:0;padding:0;font-family:sans-serif} 2 | /*# sourceMappingURL=main.c937e625.css.map*/ -------------------------------------------------------------------------------- /wip/web/pages/wiki.hoon: -------------------------------------------------------------------------------- 1 | ;html 2 | ;head 3 | ;meta(name "viewport", content "width=device-width, initial-scale=1"); 4 | ;meta(name "apple-mobile-web-app-capable", content "yes"); 5 | ;meta(name "mobile-web-app-capable", content "yes"); 6 | 7 | ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"); 8 | ;script(type "text/javascript", src "/~/at/lib/js/urb.js"); 9 | ;script(type "text/javascript", src "/pages/wiki/vue/vue.js"); 10 | ;script(type "text/javascript", src "/pages/wiki/vue-router/vue-router.js"); 11 | ;script(type "text/javascript", src "//unpkg.com/bootstrap-vue@0.18.0/dist/bootstrap-vue.js"); 12 | ;script(type "text/javascript", src "/pages/wiki/marked/marked.min.js"); 13 | 14 | ;title:"Wiki" 15 | 16 | ;link(type "text/css", rel "stylesheet", href "//unpkg.com/bootstrap@4.0.0-alpha.6/dist/css/bootstrap.min.css"); 17 | ;link(type "text/css", rel "stylesheet", href "//unpkg.com/bootstrap-vue@0.18.0/dist/bootstrap-vue.css"); 18 | ;link(type "text/css", rel "stylesheet", href "/pages/wiki/wiki.css"); 19 | == 20 | ;body 21 | ;div#app 22 | ;router-view; 23 | == 24 | ;footer 25 | ;small 26 | ;a/"https://github.com/asssaf/urbit-wiki"(target "_blank"): Source 27 | == 28 | == 29 | 30 | ;script(type "text/javascript", src "/pages/wiki/main.js"); 31 | == 32 | == 33 | -------------------------------------------------------------------------------- /wip/web/pages/wiki/wiki.css: -------------------------------------------------------------------------------- 1 | /* style to apply to html tables inside markdown rendered container */ 2 | .rendered table { 3 | width: 100%; 4 | max-width: 100%; 5 | margin-bottom: 1rem; 6 | background-color: transparent; 7 | } 8 | 9 | .rendered table th, 10 | .rendered table td { 11 | padding: 0.75rem; 12 | vertical-align: top; 13 | border-top: 1px solid #e9ecef; 14 | } 15 | 16 | .rendered table thead th { 17 | vertical-align: bottom; 18 | border-bottom: 2px solid #e9ecef; 19 | } 20 | 21 | .rendered table tbody + tbody { 22 | border-top: 2px solid #e9ecef; 23 | } 24 | 25 | .rendered table table { 26 | background-color: #fff; 27 | } 28 | 29 | /* striped */ 30 | .rendered table tbody tr:nth-of-type(odd) { 31 | background-color: rgba(0, 0, 0, 0.05); 32 | } 33 | --------------------------------------------------------------------------------