Merge remote-tracking branch 'upstream/test' into test

This commit is contained in:
Max G 2015-07-15 22:12:52 +03:00
commit 4aba7d1204
26 changed files with 349 additions and 1683 deletions

View File

@ -90,7 +90,7 @@
++ poke-helm-reset (wrap poke-reset):from-helm
++ poke-helm-send-hi (wrap poke-send-hi):from-helm
++ poke-helm-verb (wrap poke-verb):from-helm
++ poke-hood-begin (wrap poke-begin):from-helm
++ poke-helm-begin (wrap poke-begin):from-helm
++ poke-hood-sync (wrap poke-sync):from-kiln
++ poke-kiln-cp (wrap poke-cp):from-kiln
++ poke-kiln-label (wrap poke-label):from-kiln

View File

@ -413,7 +413,7 @@
vix=(bex +((cut 0 [25 2] mag))) :: width of sender
tay=(cut 0 [27 5] mag) :: message type
==
?> =(0 vez)
?> =(2 vez)
?> =(chk (end 0 20 (mug bod)))
:+ [(end 3 wix bod) (cut 3 [wix vix] bod)]
(kins tay)
@ -433,7 +433,7 @@
=+ tay=(ksin q.kec)
%+ mix
%+ can 0
:~ [3 0]
:~ [3 2]
[20 (mug bod)]
[2 yax]
[2 qax]
@ -1018,7 +1018,7 @@
++ gnaw :: gnaw:am
|= [kay=cape ryn=lane pac=rock] :: process packet
^- [p=(list boon) q=fort]
?. =(0 (end 0 3 pac)) [~ fox]
?. =(2 (end 0 3 pac)) [~ fox]
=+ kec=(bite pac)
?: (goop p.p.kec) [~ fox]
?. (~(has by urb.ton.fox) q.p.kec)

View File

@ -882,7 +882,7 @@
%= +>.$
lim (max (fall lem lim) lim)
hit.dom hit
let.dom let
let.dom (max let let.dom)
hut.ran hut
lat.ran lat
==
@ -1451,9 +1451,13 @@
++ make-nako
|= [a=aeon b=aeon]
^- nako
:+ hit.dom
let.dom
?~ =(0 b)
:+ ?> (lte b let.dom)
|-
?: =(b let.dom)
hit.dom
$(hit.dom (~(del by hit.dom) let.dom), let.dom (dec let.dom))
b
?: =(0 b)
[~ ~]
(data-twixt-takos (~(get by hit.dom) a) (aeon-to-tako b))
::
@ -1483,8 +1487,8 @@
far
=+ gar=(lobe-to-blob lob)
?- -.gar
%direct (~(put in far) lob)
%delta (~(put in $(lob q.q.gar)) lob)
%direct (~(put in far) lob)
%delta (~(put in $(lob q.q.gar)) lob)
%indirect (~(put in $(lob r.gar)) lob)
==
::
@ -1504,9 +1508,8 @@
|= p=tako :: XX slow
^- (set tako)
=+ y=(tako-to-yaki p)
=+ t=(~(put in *(set tako)) p)
%+ roll p.y
=< .(s t)
=< .(s (~(put in *(set tako)) p))
|= [q=tako s=(set tako)]
?: (~(has in s) q) :: already done
s :: hence skip
@ -2455,9 +2458,13 @@
?^ bem
u.bem
[[?>(?=(^ fat.ruf) p.n.fat.ruf) %base %ud 1] ~]
=+ rom=(~(got by fat.ruf) p.bem)
=+ dos=(~(got by dos.rom) q.bem)
?: =(0 let.dom.dos)
=+ rom=(~(get by fat.ruf) p.bem)
?~ rom
~
=+ dos=(~(get by dos.u.rom) q.bem)
?~ dos
~
?: =(0 let.dom.u.dos)
=+ cos=(mode-to-soba ~ s.bem q.q.hic r.q.hic)
=+ ^- [one=(list ,[path miso]) two=(list ,[path miso])]
%+ skid q.cos
@ -2471,7 +2478,7 @@
:~ [hen %pass /one %c %info p.bem q.bem %& p.cos one]
[hen %pass /two %c %info p.bem q.bem %& p.cos two]
==
=+ yak=(~(got by hut.ran.ruf) (~(got by hit.dom.dos) let.dom.dos))
=+ yak=(~(got by hut.ran.ruf) (~(got by hit.dom.u.dos) let.dom.u.dos))
=+ cos=(mode-to-soba q.yak (flop s.bem) q.q.hic r.q.hic)
[hen %pass / %c %info p.bem q.bem %& cos]~
::

View File

@ -141,10 +141,10 @@
=+ yen=(scot %p (shax :(mix %ticket eny now)))
=+ ^= beg ^- [his=@p tic=@p yen=@t ges=gens]
[p.kyz q.kyz yen ges]
=+ cag=`cage`[%hood-begin !>(beg)]
=+ cmd=[%hood %poke `cage`[%helm-begin !>(beg)]]
%= +>.$
moz
:_(moz [hen %pass ~ %g %deal [our our] %hood %poke cag])
:_(moz [hen %pass ~ %g %deal [our our] cmd])
==
%veer (dump kyz)
%vega (dump kyz)
@ -360,7 +360,7 @@
[~ ~]
80
0
(tuba "<awaiting {(trip p.kyz)}>")
(tuba "<awaiting {(trip p.kyz)}, this may take a few minutes>")
==
--
|% :: poke/peek pattern

View File

@ -44,7 +44,7 @@
== == ::
$: %f :: by %ford
$% [%made p=@uvH q=gage] ::
[%news ~] ::
[%news p=@uvH] ::
== == ::
$: @tas :: by any
$% [%crud p=@tas q=(list tank)] ::
@ -58,7 +58,7 @@
[%hi p=mark ~] :: outbound HTTP
[%si ~] :: response done
[%of p=ixor q=$|(~ whir-of)] :: associated view
[%on p=span:,@uvH ~] :: dependency
[%on ~] :: dependency
== ::
++ whir-of ,[p=span:ship q=term r=wire] :: path in dock
-- ::
@ -99,7 +99,7 @@
++ honk $%([%nice ~] [%mean p=ares]) :: old gall result
++ even :: client event
$% [%mean p=[dock path] q=ares]
[%news p=@uv]
[%news p=@uvH]
[%rush p=[dock path] q=json]
==
::
@ -694,16 +694,15 @@
(give-json 200 ~ (joba %beat %b &))
::
%news :: dependency updated
?. ?=([%on ^] tee)
?. ?=([%on ~] tee)
~&(e/lost/[tee hen] +>.$)
=+ dep=(slav %uv p.tee)
%+ roll (~(tap in (~(get ju liz) dep)))
=< .(con ..axon(liz (~(del by liz) dep)))
%+ roll (~(tap in (~(get ju liz) p.sih)))
=< .(con ..axon(liz (~(del by liz) p.sih)))
|= [sus=(each duct ixor) con=_..axon]
=. ..axon con
?- -.sus
%& (give-json(hen p.sus) 205 ~ %b &)
%| (get-even:(ire-ix p.sus) [%news dep])
%| (get-even:(ire-ix p.sus) +.sih)
==
::
%made
@ -941,7 +940,7 @@
=+ had=(~(has by liz) a)
=. liz (~(put ju liz) a b)
?: had done
(pass-note on//(scot %uv a) %f [%wasp our a])
(pass-note on/~ %f [%wasp our a])
::
++ parse
^- (each perk httr)
@ -1429,7 +1428,8 @@
++ poll
|= a=@u ^+ ..ix
?: =(a p.eve)
?^ ude ~&(e/ix/wait/replaced=p.u.ude abet(u.ude [hen &]))
?^ ude :: ~& e/ix/wait/replaced=p.u.ude :: XX needs %thud handling
abet(u.ude [hen &])
=. era (add ~s30 now)
(pass-note:abet(ude [~ hen &]) of//[ire] [%b %wait era])
?: (gth a p.eve) ~|(seq-high/cur=p.eve !!)

View File

@ -70,7 +70,7 @@
== ::
++ task :: problem in progress
$: nah=duct :: cause
[bek=beak kas=silk] :: problem
[bek=beak kas=silk] :: problem
keg=(map (pair term beam) cage) :: block results
kig=[p=@ud q=(map ,@ud ,[p=care q=beam])] :: blocks
== ::
@ -240,7 +240,7 @@
%sent
=- [[%done ~] +>.$(mow (weld - mow))]
^- (list move)
%+ weld (turn (~(tap in p.dap)) |=(hen=duct [hen %give %news ~]))
%+ weld (turn (~(tap in p.dap)) |=(hen=duct [hen %give %news dep]))
=. q.dap (~(del in q.dap) bem)
%+ turn (~(tap in q.dap)) :: cancel outstanding
|= bem=beam
@ -255,12 +255,12 @@
?~ dep
~&(dep-empty/hen +>.$)
?: =(dep 0vtest) :: upstream testing
+>.$(mow :_(mow [hen %give %news ~]))
+>.$(mow :_(mow [hen %give %news dep]))
=+ dap=(~(get by deh.bay) dep)
?~ dap ~&(dep-missed/dep +>.$) :: XX ~| !!
:: ~& awap/[dep u.dap]
?- -.u.dap
%done +>.$(mow :_(mow [hen %give %news ~]))
%done +>.$(mow :_(mow [hen %give %news dep]))
%sent
=. p.u.dap (~(put in p.u.dap) hen)
+>.$(deh.bay (~(put by deh.bay) dep u.dap))

View File

@ -481,26 +481,26 @@
==
::
++ les ^- (list ,@da)
:~ ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1 ~1996.1.1
~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1 ~1988.1.1
~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1 ~1979.1.1
~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1 ~1973.1.1
~1972.7.1
:~ ~2015.7.1 ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1
~1996.1.1 ~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1
~1988.1.1 ~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1
~1979.1.1 ~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1
~1973.1.1 ~1972.7.1
==
++ lef ^- (list ,@da)
:~ ~2012.6.30..23.59.59 ~2008.12.31..23.59.58
~2005.12.31..23.59.57 ~1998.12.31..23.59.56
~1997.6.30..23.59.55 ~1995.12.31..23.59.54
~1994.6.30..23.59.53 ~1993.6.30..23.59.52
~1992.6.30..23.59.51 ~1990.12.31..23.59.50
~1989.12.31..23.59.49 ~1987.12.31..23.59.48
~1985.6.30..23.59.47 ~1983.6.30..23.59.46
~1982.6.30..23.59.45 ~1981.6.30..23.59.44
~1979.12.31..23.59.43 ~1978.12.31..23.59.42
~1977.12.31..23.59.41 ~1976.12.31..23.59.40
~1975.12.31..23.59.39 ~1974.12.31..23.59.38
~1973.12.31..23.59.37 ~1972.12.31..23.59.36
~1972.6.30..23.59.35
:~ ~2015.6.30..23.59.59 ~2012.6.30..23.59.59
~2008.12.31..23.59.58 ~2005.12.31..23.59.57
~1998.12.31..23.59.56 ~1997.6.30..23.59.55
~1995.12.31..23.59.54 ~1994.6.30..23.59.53
~1993.6.30..23.59.52 ~1992.6.30..23.59.51
~1990.12.31..23.59.50 ~1989.12.31..23.59.49
~1987.12.31..23.59.48 ~1985.6.30..23.59.47
~1983.6.30..23.59.46 ~1982.6.30..23.59.45
~1981.6.30..23.59.44 ~1979.12.31..23.59.43
~1978.12.31..23.59.42 ~1977.12.31..23.59.41
~1976.12.31..23.59.40 ~1975.12.31..23.59.39
~1974.12.31..23.59.38 ~1973.12.31..23.59.37
~1972.12.31..23.59.36 ~1972.6.30..23.59.35
==
--
::
@ -2552,7 +2552,7 @@
++ gift-ford :: out result <-$
$% [%made p=@uvH q=gage] :: computed result
[%mass p=mass] :: memory usage
[%news ~] :: fresh depends
[%news p=@uvH] :: fresh depends
== ::
++ kiss-ford :: in request ->$
$% [%exec p=@p q=(unit bilk)] :: make / kill

View File

@ -6,7 +6,10 @@
::::
!:
|= $: [now=@da eny=@uvI bec=beak]
[arg=[pax=path pot=@tas ~] ~]
[[pax=path pot=$|(~ [v=@tas ~])] ~]
==
?~ pot
=+ bem=(need (tome pax))
$(pot ~[?^(s.bem i.s.bem q.bem)])
:- %kiln-mount
[pax pot]:arg
[pax v.pot]

View File

@ -8,11 +8,16 @@
!:
=> |%
++ begs ,[his=@p tic=@p yen=@t ges=gens]
++ scug |*([a=@ b=(pole)] ?~(b ~ ?~(a ~ [-.b $(b +.b, a (dec a))])))
--
|= $: [now=@da eny=@uvI bec=beak]
[~ ~]
[arg=_(scug *@ ~[his=*@p tic=*@p]) ~]
==
^- (sole-result (cask begs))
=- ?~ arg -
=+ (fun.q.q his.arg)
?~ +.arg -
(fun.q.q tic.arg)
%+ sole-lo
[%& %helm-begin "your ship: ~"]
%+ sole-go fed:ag

View File

@ -63,7 +63,7 @@
%- ~(gas in *(set well))
=+ myr=(clan our)
?: =(%pawn myr)
[[%base %dojo] ~]
[[%base %talk] [%base %dojo] ~]
?: =(%earl myr) ~
[[%home %talk] [%home %dojo] ~]
::
@ -72,8 +72,8 @@
%- ~(gas in *(set gill))
^- (list gill)
=+ myr=(clan our)
?: =(%pawn myr)
[[our %dojo] ~]
:: ?: =(%pawn myr)
:: [[our %dojo] ~]
?: =(%earl myr)
=+ dad=(sein our)
[[dad %talk] [dad %dojo] ~]

View File

@ -79,6 +79,11 @@
^+ +>
?~(+< +> $(+< t.+<, +> (emit i.+<)))
::
++ render
|= [mez=tape sud=desk who=ship syd=desk]
:^ %palm [" " ~ ~ ~] leaf/mez
~[leaf/"from {<sud>}" leaf/"on {<who>}" leaf/"to {<syd>}"]
::
++ poke-mount
|= kiln-mount
=+ bem=(tome pax)
@ -100,15 +105,13 @@
++ poke-sync ::
|= hos=kiln-sync
?: (~(has by syn) hos)
=+ "already syncing from {<sud.hos>} on {<her.hos>} to {<syd.hos>}"
abet:(spam leaf/- ~)
abet:(spam (render "already syncing" [sud her syd]:hos) ~)
abet:abet:start:(auto hos)
::
++ poke-unsync ::
|= hus=kiln-unsync
?. (~(has by syn) hus)
=+ "not syncing from {<sud.hus>} on {<her.hus>} to {<syd.hus>}"
abet:(spam leaf/- ~)
abet:(spam (render "not syncing" [sud her syd]:hus) ~)
%* . abet:abet:stop:(auto hus)
syn (~(del by syn) hus)
==
@ -182,8 +185,9 @@
::
++ spam
|= mes=(list tank)
%- emit
[%poke /kiln/spam [our %talk] (said our %kiln now eny mes)]
((slog 0 mes) ..spam)
:: %- emit :: XX not displayed/immediately
:: [%poke /kiln/spam [our %talk] (said our %kiln now eny mes)]
::
++ auto
|= kiln-sync
@ -199,7 +203,7 @@
::
++ spam |*(* %_(+> ..auto (^spam +<)))
++ stop
=> (spam leaf/"ended autosync from {<sud>} on {<her>} to {<syd>}" ~)
=> (spam (render "ended autosync" sud her syd) ~)
%- blab :_ ~
:* ust %warp
/kiln/sync/[syd]/(scot %p her)/[sud]
@ -207,11 +211,9 @@
==
::
++ start
:: XX remove feedback for demo
:: =. . %- spam
:: [leaf/"activated sync from {<sud>} on {<her>} to {<syd>}" ~]
=> (spam (render "activated sync" sud her syd) ~)
%- blab
:~ [ost %mont /mount syd our syd /]
:~ :: [ost %mont /mount syd our syd /]
:* ost %warp
/kiln/sync/[syd]/(scot %p her)/[sud]
[our her] sud ~ %sing %w [%da now] /
@ -221,8 +223,8 @@
|= rot=riot
?~ rot
%^ spam
leaf/"bad %writ response on sync"
leaf/"from {<sud>} on {<her>} to {<syd>}"
leaf/"bad %writ response"
(render "on sync" sud her syd)
~
=. let ?. ?=(%w p.p.u.rot) let ((hard ,@ud) q.q.r.u.rot)
%- blab :_ ~
@ -240,9 +242,9 @@
=. +>.$
%- spam
?: ?=(%& -.mes)
[leaf/"sync succeeded from {<sud>} on {<her>} to {<syd>}" ~]
[(render "sync succeeded" sud her syd) ~]
?+ p.p.mes
:* leaf/"sync failed from {<sud>} on {<her>} to {<syd>}"
:* (render "sync failed" sud her syd)
leaf/"please manually merge the desks with"
leaf/":+merge %{(trip syd)} {(scow %p her)} %{(trip sud)}"
leaf/""
@ -251,8 +253,8 @@
==
::
%no-ali-desk
:~ leaf/"sync activated from {<sud>} on {<her>} to {<syd>}"
leaf/"note: {<sud>} on {<her>} is a blank desk"
:~ (render "sync activated" sud her syd)
leaf/"note: blank desk {<sud>} on {<her>}"
==
==
%- blab :_ ~

View File

@ -33,7 +33,7 @@ window.urb.req = function(method,url,params,json,cb) {
if(res.data.reload)
res.reload = res.data.reload
} catch(e) {
if(urb.wall !== false) document.write(this.responseText) // XX
// if(urb.wall !== false) document.write(this.responseText) // XX
err = {
message:"Failed to parse JSON",
raw:this.responseText

View File

@ -154,7 +154,8 @@
%^ cat 3 ' '
%^ cat 3 `@t`(scot %p bos)
%^ cat 3 '/'
bos
bod
:- bob
:- ~['------------']
:- bas

View File

@ -11,146 +11,246 @@ You can find them in `/main/app`.
------------------------------------------------------------------------
### [`:begin`](#begin)
### [`:?begin`](#begin)
`~zod/try=> :begin [~ship-name [~valid-ticket-for-ship]]`
`~zod:dojo> :?begin [~ship-name [~valid-ticket-for-ship]]`
Start a ship. `:begin` collects all of the necessary information to
Start a ship. `:?begin` collects all of the necessary information to
start an Urbit ship. Takes an option `[~ship-name]` or
`[~ship-name [~valid-ticket-for-ship]]` pair.
------------------------------------------------------------------------
### [`:cat`](#cat)
### [`+cat`](#cat)
`~zod/try=> :cat path-to-file [...]`
`~zod:dojo> +cat /path/to/file [...]`
"cat" a file. `:cat` either prints a file, or concatenates and then
"cat" a file. `+cat` either prints a file, or concatenates and then
prints multiple files to the terminal.
~zod:dojo> +cat %/spec/nock/5/txt
> +cat %/spec/nock/5/txt
/~zod/home/~2015.6.29..22.33.04..fc76/spec/nock/5/txt
A noun is an atom or a cell.
------------------------------------------------------------------------
### [`:cp`](#cp)
### [`|cp`](#cp)
`~zod/try=> :cp /path/to/source /path/to/destination`
`~zod:dojo> |cp /path/to/source /path/to/destination`
Copy a file to a given location.
~zod:dojo> |cp %/spec/nock/5/txt %/try/6/txt
> |cp %/spec/nock/5/txt %/try/6/txt
+ /~zod/home/2/try/6/txt
>=
------------------------------------------------------------------------
### [`:grep`](#grep)
### [`grep`](#grep)
`~zod/try=> :grep 'literal'`
<mark>GONE</mark>
<s>`~zod:dojo> :grep 'literal'`
"grep" a file or standard input. Currently only supports a literal cord,
but will eventuall support regular expressions.
but will eventuall support regular expressions.</s>
------------------------------------------------------------------------
### [`:hi`](#hi)
### [`|hi`](#hi)
`~zod/try=> :hi ~ship ["message"]`
`~zod:dojo> |hi ~ship ["message"]`
Send a ship a message which is empty by default, becoming their neighbor
in the process. Often used to ping ships to check connectivity.
~zod:dojo> |hi ~doznec
> |hi ~doznec
ames: czar zod.urbit.org: ip .192.241.195.84
>=
hi ~doznec succesful
; ~doznec is your neighbor
; ~doznec is your neighbor
and on ~doznec
~doznec:dojo>
< ~zod:
; ~zod is your neighbor
send a message
~zod:dojo> |hi ~doznec "say something"
>=
hi ~doznec succesful
and on ~doznec
< ~zod: say something
------------------------------------------------------------------------
### [`:into`](#into)
`~zod/try=> :into /path/to/file 'contents'`
<mark>GONE</mark>
<s>
`~zod:dojo> :into /path/to/file 'contents'`
Write text to a file. If the specified file does not exist, create a
file by that name. If it does exist, replace its contents.
</s>
------------------------------------------------------------------------
### [`:label`](#label)
### [`|label`](#label)
`~zod/try=> :label %path %label`
<mark>GONE? returns file not found</mark>
<s>
`~zod:dojo> |label %path %label`
"label". Add a label to a change number.
~zod/try=> :label %try %zebra
~zod:dojo> |label %try %zebra
= new /~zod/try/3
~zod/try=> :ls /=try/zebra
~zod:dojo> :ls /=try/zebra
readme
Note that adding a label is part of the delta stream and creates a new
change number, `3`.
</s>
------------------------------------------------------------------------
### [`:ls`](#ls)
### [`+ls`](#ls)
`~zod/try=> :ls path/to/directory`
`~zod:dojo> :+ls path/to/directory`
"ls". List files at a path. Unlike "ls" in Unix, the current path `%`
must be explicitly given (you cannot call `:ls` with no arguments to
must be explicitly given (you cannot call `+ls` with no arguments to
display the files at the current path).
~zod:dojo> +ls %try
> +ls %/try/
readme/md
------------------------------------------------------------------------
### [`:mv`](#mv)
### [`|mount`](#mount)
`~zod/try=> :mv /path/to/source /path/to/destination`
`~zod:dojo> |mount /path/to/directory/version %mount-point`
Your files are not synced to unix by default.
To sync a subtree to unix, run `|mount /path/to/directory %mount-point`.
This will sync it into <pier>/<mount-point>.
If you want to sync your whole home desk into f0/home, for example,
run `|mount % %home` You can also [`|unmount`](#unmount).
~zod:dojo> |mount /~zod/base/0 %base
> |mount /~zod/base %base
>=
------------------------------------------------------------------------
### [`|mv`](#mv)
`~zod:dojo> |mv /path/to/source /path/to/destination`
Move a file to a given location, creating a new revision of the source
that omits the moved file.
~zod:dojo> |mv %/try/6/txt %/try/7/txt
> |mv %/try/6/txt %/try/7/txt
+ /~zod/home/3/try/7/txt
>=
------------------------------------------------------------------------
### [`:reload`](#reload)
### [`|reload`](#reload)
`~zod/try=> :reload %vane-name [...]`
`~zod:dojo> |reload %vane-name [...]`
Reload the standard library (zuse) and/or arvo vanes. If zuse is
reloaded, vanes depending on the changes must be reloaded as well. For
example `:reload %zuse %ford` is necessary to make use of changes in
example `|reload %zuse %ford` is necessary to make use of changes in
application code or the REPL.
Possible values for %vane-name see [Overview](overview "overview"):
------------------------------------------------------------------------
### [`:reset`](#reset)
`~zod/try=> :reset`
Reloads all vanes. See [`:reset`] for reloading only or a specific vane.
~zod:dojo> |reload %zuse
[%tang /~zod/home/~2015.6.29..23.50.29..134d/arvo/zuse ~hillyx-salhet]
> |reload %zuse
>=
------------------------------------------------------------------------
### [`:rm`](#rm)
### [`|reset`](#reset)
`~zod/try=> :rm /path/to/source`
`~zod:dojo> |reset`
Reloads all vanes. See [`|reload`](#reload) for reloading only or a specific vane.
~zod:dojo> |reset
[%vega-start /~zod/home/~2015.6.29..23.51.42..f335/arvo/hoon]
%vega-parsed
[%vega-compiled %163 163]
%hoon-load
[%tang /~zod/home/~2015.6.29..23.51.42..f335/arvo/zuse ~hillyx-salhet]
[%vane %a /~zod/home/~2015.6.29..23.51.42..f335/arvo/ames ~tilwyl-talren]
%ames-reload
[%vane %c /~zod/home/~2015.6.29..23.51.42..f335/arvo/clay ~molmur-panlus]
[%vane %d /~zod/home/~2015.6.29..23.51.42..f335/arvo/dill ~sicbet-miphes]
[%vane %e /~zod/home/~2015.6.29..23.51.42..f335/arvo/eyre ~solrux-sibnep]
[gub=30 hov=19 ged=18 ded=1 pox=1 ask=1 kes=1 ney=35 dop=1 liz=1 wup=1 sop=1 wix=1]
[%vane %f /~zod/home/~2015.6.29..23.51.42..f335/arvo/ford ~librem-sopseg]
[%vane %g /~zod/home/~2015.6.29..23.51.42..f335/arvo/gall ~sidsub-fasrev]
[%vane %t /~zod/home/~2015.6.29..23.51.42..f335/arvo/time ~ritwyn-lanrev]
> |reset
<<<reset>>>
>=
------------------------------------------------------------------------
### [`|rm`](#rm)
`~zod:dojo> |rm /path/to/source`
Remove a file.
~zod:dojo> |rm %/try/7/txt
>=
------------------------------------------------------------------------
### [`:solid`](#solid)
### [`+solid`](#solid)
`~zod/try=> :solid`
`~zod:dojo> +solid`
compiles a kernel into a new full urbit.pill
------------------------------------------------------------------------
### [`:sync`](#sync)
### [`|sync`](#sync)
`:sync %source-desk ~hidduc-posmeg %target-desk`
`~zod:dojo> |sync %source-desk ~hidduc-posmeg %target-desk`
Sets up a subscription to the source desk on the target ship name to the
target desk on your ship.
------------------------------------------------------------------------
### [`:ticket`](#ticket)
### [`+ticket`](#ticket)
`~zod/try=> :ticket ~ship-name`
`~zod:dojo> +ticket ~ship-name`
Creates a will for a ship. `:ticket` outputs the ticket for a Urbit
Creates a will for a ship. `+ticket` outputs the ticket for a Urbit
ship. Takes an option `[~ship-name]`. On destroyes this command creates
a yacht and takes the option \`[\~yacht-name-destroyer-name]
@ -158,7 +258,10 @@ a yacht and takes the option \`[\~yacht-name-destroyer-name]
### [`:thumb`](#thumb)
`~zod/try=> :thumb ~ship-name`
<mark>GONE</mark>
<s>
`~zod:dojo> :thumb ~ship-name`
Show the ships information. Only works if you issued a [`:hi`]
[\`\~ship-name] beforehand.
@ -168,21 +271,37 @@ This command is not avaible since the switch from batz to `%gall`!
Use this for the time beeing: - will:
`~zod/try=> ((hard (unit gcos)) .^(%a /=gcos=/~ship-name))` - raw will:
`~zod/try=> ((hard will) .^(%a /=will=/~ship-name))`
</s>
------------------------------------------------------------------------
### [`:unsync`](#unsync)
### [`|unmount`](#unmount)
`:unsync %source-desk ~hidduc-posmeg %target-desk`
`~zod:dojo> |unmount /path/to/directory`
Your files are not synced to unix by default.
To sync a subtree to unix, run [`|mount`](#mount).
You can unmount with either `|unmount /path/to/directory`
or `|unmount %mount-point`.
~zod:dojo> |unmount %base
> |unmount %base
>=
------------------------------------------------------------------------
### [`|unsync`](#unsync)
`~zod:dojo> |unsync %source-desk ~hidduc-posmeg %target-desk`
Cancels the subscription to the source desk on the target ship name to
the target desk on your ship.
------------------------------------------------------------------------
### [`:verb`](#verb)
### [`|verb`](#verb)
`~zod/try=> :verb`
`~zod:dojo> |verb`
Turn verbose arvo mode on/off.
@ -220,9 +339,9 @@ You'll see events, internal cards, and effects.
------------------------------------------------------------------------
### [`:ye`](#ye)
### [`|ye`](#ye)
`~zod/try=> :ye ["message"]`
`~zod:dojo> |ye ["message"]`
Send a message to all ships. Often used to announce a continuity breach.

View File

@ -1,15 +0,0 @@
<div class="short">
Guides
======
These guides are designed to get you oriented in urbit.
Each one covers a specific topic. Although it's not necessary to follow
them in order, they do get increasingly complex.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -1,813 +0,0 @@
`%ford` Guide
=============
#### basic `hoon` and talking to the web
<div class="short">
`%ford` is the arvo vane that handles asset management and publishing.
We use `%ford` to compose our files when programming, and also to bundle
files together for the web.
This guide assumes that you have installed and started your urbit.
Assuming you cloned the repo into `/$URB_DIR` you should be able to find
the unix mirror of your ship's filesystem in
`/$URB_DIR/$PIER/$SHIP-NAME`. All of the filesystem paths in this guide
are relative to that Unix directory.
Also, we refer to `http://ship-name.urbit.org/` in our URLs, but you can
also use `http://localhost:8080/` if you prefer to just talk to your
machine directly.
</div>
<hr>
</hr>
1. Let's publish a webpage
--------------------------
#### In
/main/pub/fab/guide/exercise/1/hymn.hook
#### Put
;html
;head
;meta(charset "utf-8");
;title: Exercise 1
==
;body
;div
;h1: Exercise 1 — Simple HTML
;p: As you may notice, urbit has no problem talking to the web.
==
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/1/
#### What did you just do?
The code you just wrote is urbit's native programming langauge, hoon.
Generating HTML with hoon is similar to writing [jade]() or other
similar HTML shorthand. In hoon, this shorthand is called [`++sail`]()
and it's a native part of the hoon language.
In `++sail` node-names are prefixed with a `;` and closed with a `==`.
Nodes that have text content and are only on one line use a `:`, such as
our `;h1:` above, and are closed implicitly with a new line. Nodes with
no content are closed with another `;`, such as `;br;`.
You can find more information about `++sail` in our [rune library
documentation]().
<hr>
</hr>
2. Let's do some programming on the page.
-----------------------------------------
#### In
/pub/fab/guide/exercise/2/hymn.hook
#### Put
;html
;head
;meta(charset "utf-8");
;title: Exercise 2
==
;body
;div
;h1: Exercise 2 — Call a function
;p: Although it may be obvious, 2+2={<(add 2 2)>}
==
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/2/
### What's going on there?
Clearly, the code `(add 2 2)` is generating `4`, and it's not too hard
to see why. `add` is one of the library functions that are a part of
`hoon.hoon`. Try replacing `(add 2 2)` with `(sub 2 (add 2 2))`. You can
find documentation for the full hoon library in the [library
reference]().
Since the product of `(add 2 2)` is a number, we need a few extra things
to have it print properly. In `++sail` we use `{` and `}` to do string
interpolation. Everything after the `:` is expected to be a string, so
we need to tell the parser when we start writing code. The `<` and `>`
inside our `{` `}` are converting our result `4`, a number, to the
string `"4"`. hoon is a strongly typed language kind of like haskell, so
we need to explicitly convert our types.
<hr>
</hr>
3. Let's assign some variables.
-------------------------------
#### In
/pub/fab/guide/exercise/3/hymn.hook
#### Put
=+ ^= a 1
=+ b=2
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 3
==
;body
;div
;h1: Exercise 3 — Assignment
;p: a={<a>}
;p: b={<b>}
;p: a+b={<(add a b)>}
==
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/3/
#### How does that work?
The first thing you should notice in this example is the `=+` at the top
of our file. `=+` is a rune. hoon is a programming with no reserved
words. We don't use `if` `this` or `function` at all. Instead, runes
have their own pronunciation. `=+` is pronounced 'tislus'. You can find
the table of pronunciation [here](). In hoon you construct your
programs using runes, which are two character ascii pairs. You can see
the whole set of runes in the [rune index]().
`=+` pushes an expression on to our subject. The subject in hoon is
similar to `this` in other languages. hoon being a functional language
if we want something to be available further on in our computation we
need to attach it to the subject first.
The second thing you should notice is the `^- manx`. Here the rune
`[^-]()` is used to cast our product to a [++manx](), which you can
think of like the hoon MIME type for XML. Using a `^-` is not required,
but helps us produce more informative error messages when we generate a
type error or mismatch.
Looking at the rendered page it's clear that we're assigning `a` to be
`1` and `b` to be `2`. Looking at the code, however, you can see that
we're doing this in two different ways. Runes in hoon can have irregular
forms, and `^=` is one of them. The first two lines of our example are
doing the same thing, where `a=2` is simply the irregular form of
`^= a 2`. You can see the full list of irregular forms [here]().
Looking at the simple computation on the page, you can try changing the
values of `a` and `b` to any integers to produce similar results.
<hr>
</hr>
4. Let's build our own computation
----------------------------------
#### In
/pub/fab/guide/exercise/4/hymn.hook
#### Put
|%
++ start 1
++ end 10
++ length
|= [s=@ud e=@ud]
(sub e s)
--
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 4
==
;body
;div
;h1: Exercise 4 — Cores
;p: We'll be starting at {<start>}
;p: And ending at {<end>}
;p: Looks like a length of {<(length start end)>}
==
==
==
#### Try it
(and be sure to put two spaces between `++` and arm names)
http://ship-name.urbit.org/main/pub/fab/guide/exercise/4/
### What's happening?
As you can see from the output, we have written a little function that
takes two numbers, `s` and `e` and returns their difference. The first
thing to notice about our code is the first rune. `|%` is a `core` rune.
You can think of cores like functions or objects in other languages.
`|%` runes contain an arbitrary number of arms, denoted with either `++`
or `+-` and closed with `--`.
Each arm has a value, either static data (in the case of `++start` and
`++end`) or a gate (in the case of `++length`). A gate is a kind of
core. Gates only have one arm and are quite similar to a function in
other languages. We use `|=` to construct our gate. Runes in hoon are
generally categorized by their first character. `|` indicates a rune
having to do with cores. You can find all of the `|` runes in the [rune
library]().
Our `++length` [gate]() takes two arguments, `s` and `e`. In hoon we
call the data passed in to a gate the 'sample'. Every `|=` has two
parts: the sample type and the computation, also known as a `tile` and a
`twig`. Casually, `[s=@ud e=@ud]` means that the gate takes two
arguments, labelled going forward as `s` and `e`, and required to both
be `@ud` or unsigned decimal. Our computation, `(sub e s)` simply
computes the difference between `e` and `s`.
`@ud` is an odor. Odors aren't quite types, but they're similar. You'll
learn the difference by example as we progress, and you can always refer
to the [odor index]().
You probably also noticed our indentation. In general hoon has both tall
and wide forms. In tall form, hoon uses two spaces for indentation and
is back-stepped so nested code doesn't drift away toward the right
margin. In wide form we use parenthesis just like almost everyone else.
<hr>
</hr>
5.
--
#### In
/pub/fab/guide/exercise/5/hymn.hook
#### Put
|%
++ dist ,[start=@ud end=@ud]
++ length
|= [d=dist]
(sub end.d start.d)
--
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 5
==
;body
;div
;h1: Exercise 5 — Cores
;p: How long does it take to get from 2 to 20? {<(length 2 20)>}
==
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/5/
#### What's the difference?
Clearly we're producing the same result as before, but we're doing it in
a different way.
The first line in our gate, `++length` always specifies the sample tile.
As you can see here, our sample tile is actually a `++dist`, the body of
which, `,[start=@ud end=@ud]` looks very similar to our previous example
in that it accepts two `@ud`. The important difference is that `++dist`
is now defined in a way that can be re-used. hoon is a strongly typed
language, but it encourages the creation of your own types using what we
call tiles.
At a high level you can think of hoon as being composed of two things,
tiles and twigs. Twigs are the actual AST structures that get consumed
by the compiler. Tiles reduce to twigs and provide major affordances for
the programmer. If you're interested in learning about tiles more deeply
you can find an in-depth explanation in the [tile overview]().
It should suffice, for now, to say that we create tiles in the same way
that you would think of creating type definitions in another language.
The primary way we do this is with `$` runes you can find more about
them in the [`$` section]() of the rune library.
In this specific example we are using the `$,` tile rune in its
irregular form, `,`. `,` generates a validator from the given
expression. In effect, `++dist` uses the type system to only produce
cells that appear in the form `[start=@ud end=@ud]`. When we use it in
our `++length` gate we assert that our input must be validated by
`++dist`. To test that out, you can try passing something that isn't an
unsigned decimal (or `@ud`) to `++length`. Try replacing `(length 2 20)`
with `(length 2 'a')`. As we continue you'll see how this pattern can be
quite useful.
One other thing to point out which may be immediately confusing coming
from other languages is the order of addressing `start` and `end`. We
call these labels faces, and we address them in the opposite order than
you're usually familiar with. We still separate our addressing with `.`,
but do it from the inside out. Given a tuple such as
`[a=1 b=[c=[d=2 e=3]]]` we can address the value of `e` with `e.c.b`.
You can read more about how faces work in the commentary on `++type`
[here]().
<hr>
</hr>
6.
--
#### In
/pub/fab/guide/exercise/6/hymn.hook
#### Put
|%
++ fib
|= x=@
?: (lte x 2)
1
(add $(x (dec x)) $(x (sub x 2)))
--
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 6
==
;body
;div
;h1: Exercise 6 — Loops
;p: {<(fib 1)>}, {<(fib 2)>}, {<(fib 3)>}, {<(fib 4)>}
==
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/6/
#### What is that doing?
We're printing a few members of the [fibonacci sequence]() by
calling our arm `++fib` with a few values. The fibonacci sequence is a
fairly straight forward algorithm: `F(n-1) + F(n-2)` where `F(1) = 1`
and `F(2) = 1`. As is obvious from the formula, generating the fibonacci
value at any number requires us to recurse, or loop. Let's walk through
the code.
Our example here should look similar to the previous one. We build a
core with `|%` and add the arm `++fib`. `++fib` is a gate which takes
one argument `x`, an atom. Using [`?:`]() we test if `x` is less
than `2` with the library function [`lte`]() to handle our seed
values of `F(1) = 1` and `F(2) = 1`. `?:` is a member of the [`?`
runes](), related to true / false values, or loobeans. In hoon true
and false are `0` and `1` respectively and take the odor `@f`. We tend
to say 'yes' and 'no' instead of 'true' and 'false' to keep track of the
switch. Our built-in function `lte` produces a loobean, so we evaluate
our first line if true, and second if false.
If `x` is not less than `2` we compute `F(n-1) + F(n-2)` by using `$`.
We mentioned previously that a gate is a special kind of core with only
one arm, called `$`. Here we're using `$` to mimic the behavior of a
loop. You can read the expression `$(x (dec x))` as 'call the gate again
with `x` replaced by `(dec x)`. For more on how this works, check out
the documentation of [`%=`]() and [`%-`](). With that in mind it
should be clear how the last line of `++fib` produces the member of the
sequence at a given value `x`.
<hr>
</hr>
7.
--
#### In
/pub/fab/guide/exercise/7/hymn.hook
#### Put
::
::
:::: /hook/hymn/7/exercise/guide/fab/pub/
::
/? 314
/= gas /$ fuel
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: %ford Example 1
==
;body
;div
;h1: %ford Example 1 — Page Variables
;div.who: {<(~(get ju aut.ced.gas) 0)>}
;div.where: {(spud s.bem.gas)} rev {(scow %ud p.r.bem.gas)}
;code
;pre: {<gas>}
==
==
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/7/
http://ship-name.urbit.org/gin/del/main/pub/fab/guide/exercise/7/
Here we're putting our publishing framework, `%ford` to work a little
bit. We're printing out some of the parameters our page is passed: who
is looking at it, where it is and what revision our desk is on. We have
also thrown in all our FCGI parameters in a codeblock for reference.
To do this we have introduced some new runes, `/?`, `/=` and `/$`. We
tend to call runes with a leading `/` "`%ford` runes" since they are
used by the `%ford` vane for resource loading and composition. By
convention, we indent four spaces after them to make them more obvious.
They belong at the top of the file.
`/?` simply checks for compatibility. In this case the line means 'need
urbit 314 or below', or in hoon: `(lte zuse 314)`. `314` is the number
in the kelvin versioning system, which you can read about [here]().
`/=` is similar to the combination of `=+ =^`, or assignment. `/$`
calls a parsing function, which we specify as [`++fuel`]() with the
[`++beam`]() and [`++path`]() of our current file.
`/= gas /$ fuel` is a common way to open your page, since the
product of `++fuel` is useful when writing pages to the web. The use of
`++fuel` is not enforced — you can also write your own parser.
Our page is made up of two generated parts: who requested the page, the
location of the page and its revision. Both are parsed out of the `gas`
variable using some straightforward library functions, [`++ju`](),
[`++spud`]() and [`++scow`](). You can follow those links to the
library reference to learn more about them. You'll also notice our
addressing moving in the opposite direction as you may be used to.
`aut.ced.gas` pulls `aut` from inside `ced` from inside `gas`.
Inside of the `;code` tag we also print (for our own reference) the
entire `gas`, so you can take a look at the contents. This can be a
helpful trick when debugging. To fully understand what gets put in
`gas`, we can take a look at `++fuel` and note that it produces a
[`++epic`](), which also contains a [`++cred`](). You can follow
those links to learn more about them.
When we try changing the url from `main` to `gin/del/main` we're
using some of the access methods from `%eyre` (the urbit webserver) to
pretend to be the urbit `~del`. You can find documentation on those
access methods in the `%eyre` commentary, [here]().
Path and identity are useful, but there are some other parameters worth
checking out as well.
<hr>
</hr>
8.
--
#### In
/pub/fab/guide/exercise/8/hymn.hook
#### Put
::
::
:::: /hook/hymn/8/exercise/guide/fab/pub/
::
/? 314
/= gas /$ fuel
::
^- manx
;html
;head
;title: %ford Example 2
==
;body
;div: Do you have a code?
;div: ?code={<(fall (~(get by qix.gas) %code) '')>}
==
==
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/8/
http://ship-name.urbit.org/main/pub/fab/guide/exercise/8/?code=yes-i-do
This is a simple example, showing off another use of
`/= gas /$ fuel`. In this case we're just pulling out the value of
the `code` query string parameter. You should be able to change that
value to any url-safe string and see it appear on the page.
We're using a few simple library functions to actually pull the value
out, [`++fall`]() and [`get:by`](). Query string parameters are
stored in `qix.gas` as a `++map`, one of the main container constructs
used in hoon. We'll encounter a lot of maps along the way, and you can
learn more about them in the [map section]() of the library doc.
<hr>
</hr>
9.
--
#### In
/pub/fab/guide/exercise/9/hymn.hook
#### Put
::
::
:::: /hook/hymn/exercise/9/guide/fab/pub/
::
/? 314
::
// /%%/lib
^- manx
;html
;head
;title: %ford Example 3
==
;body
;h1: %ford Example 3
;p: {<(fib 1)>}, {<(fib 2)>}, {<(fib 3)>}, {<(fib 4)>}
==
==
#### And in
/pub/fab/guide/exercise/9/lib.hoon
#### Put
|%
++ fib
|= x=@
?: (lte x 2)
1
(add $(x (dec x)) $(x (sub x 2)))
--
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/9/
#### How are they getting combined?
Clearly this looks a lot like our previous example using `++fib`, only
now we're using two separate files. The majority of this code should be
familiar to you from example 6, so let's focus on a single line,
`// /%%/lib`.
`//` is a `%ford` rune that loads a resource from a given path. `//` is
used as a way to organize project code into separate files, not for
loading libraries and structures. We'll show some examples of how urbit
handles those things shortly. You can think of `//` as a kind of
`include` or `require`. `//` takes a `beam`, an absolute global path in
`%clay` — the global urbit filesystem.
In `%clay` we use `%` to navigate relative paths. `%` is sort of like
`.` when moving around the unix file system. Although we put our code in
the unix path `/pub/fab/guide/exercise/9/hymn.hook` the file extension
is just a hint to the system. `/%/` (the equivalent of a unix `./`)
actually resolves to `/pub/fab/guide/exercise/9/hymn`.
We commonly use two kinds of extensions, `.hoon` for source files and
`.hook` for files that generate something else. Since our hymn file is
generating html, it's a `.hook`, and our source file is just a `.hoon`.
In order to find our file one level up we need two `%%` to get to
`/pub/fab/guide/exercise/9/`. Adding `lib` resolve to our neighboring
file. You can read more about how `%clay` paths are parsed in the
[`%clay` overview](link). It's also pretty easy to try them out using
`/=main=`, `/=try`, `/try/a/b/c/d`, etc.
and `:ls` in your `%arvo` terminal.
<hr>
</hr>
10.
---
#### In
/pub/fab/guide/exercise/10/hymn.hook
#### Put
::
::
:::: /hook/hymn/10/exercise/guide/fab/pub/
::
/? 314
/= gas /$ fuel
// /%%/lib
::
=+ ^= arg
%+ slav
%ud
%+ fall
%- ~(get by qix.gas) %number
'0'
::
^- manx
;html
;head
;title: %ford Example 4
==
;body
;div: {<(fib arg)>}
==
==
#### And in
/pub/fab/guide/exercise/10/lib.hoon
#### Put
|%
++ fib
|= x=@
?: (lte x 2)
1
(add $(x (dec x)) $(x (sub x 2)))
--
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/10/
http://ship-name.urbit.org/main/pub/fab/guide/exercise/10/?number=7
http://ship-name.urbit.org/main/pub/fab/guide/exercise/10/?number=12
As you can see by changing the URL, we're now passing our query string
parameter to our `++fib` script and printing the output. It's common to
pull some data out of the URL and do something with it, but we don't
have any type information about our query string parameters and hoon is
a strongly typed languge. As you can see, we're calling `++fib` with a
parameter `arg`. Let's look closely at how we generate `arg`.
The first part of our assignment should look familiar from previous
example, `=+ ^= arg` puts the face `arg` on the product of our
remaining computation. In short, you can read the code that produces
`arg` as `(slav %ud (fall (~(get by qix.gas) %number) '0'))`. We use `%`
runes to write this in tall form. `%` runes are used for calling gates
or evaluating changes. `%+` 'slams' or calls a gate with two arguments,
and `%-` 'slams' or calls a gate with one argument. As usual, you can
find more about the `%` runes in the [`%` section]() of the rune
library.
To get a value out of our map of query string parameters `qix.gas` we
use a method from the [maps library]() that produces a `++unit`.
`++unit`s are a common type in hoon used for optional values. A
[`++unit`]() is either `~` or `[~ p=value]`. Since we need to
specify a value for `(fib arg)` even when someone doesn't enter the
query string we use [`++fall`](), which produces either the value of
the unit, or the second argument if the `++unit` is null. Since our
`qix.gas` has string values in it we specify a string in our second
argument, `'0'`. As an aside, `'0'` is different from `"0"` in hoon. You
can read about the difference in [`++cord`]() and [`++tape`]().
Our outermost call, to [`++slav`](), casts our string to a `@ud`
which is the type expected by `++fib`. `++slav` takes the name of an
odor and a value, and tries to cast the value to that odor.
<hr>
</hr>
11.
---
#### In
/pub/fab/guide/exercise/11/hymn.hook
#### Put
/= posts /: /%%/lib
/; |= a=(list (pair ,@ ,manx))
%+ turn
a
|= [* b=manx]
b
/@
/psal/
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: %ford Example 11
==
;body
;h1: Ford example — Loading Resources by Number
;* posts
==
==
#### In
/pub/fab/guide/exercise/11/lib/1.md
#### Put
#1
This is my first post.
#### In
/pub/fab/guide/exercise/11/lib/2.md
#### Put
#2
This is my second post.
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/exercise/11/
http://ship-name.urbit.org/main/pub/fab/guide/exercise/11/lib/1/
http://ship-name.urbit.org/main/pub/fab/guide/exercise/11/lib/2/
#### Experiment with it
Try adding other `.md` files with numeric file names (such as `3.md`) to
the `11/lib/` directory to get a feel for what's going on.
What's happening?
As you can see, we're loading the markdown files in `11/lib` and putting
them in to our page. Let's dive into the code.
We're using `/=` to assign the `posts` face. `/:` sets the `++beam` for
the computation below it. You can think of it sort of like setting an
environment variable. Everything below uses our `++beam` `/%%/lib`.
If we take the next few lines and write them as pseudo code in wide form
they might look something like this, `(/; [gate] (/@ /psal/))`. That
being the case, let's start at the bottom and move upwards since that's
how our data flows. In depth documentation on individual `++horn` runes
can be found in the [horn section of the rune library]().
`/psal/` loads our `psal` mark. Marks are like content types, and we
keep them in `/main/mar/`. You can open `/main/mar/psal/door.hook` to
see that we specify the ways in which a particular mark can be converted
to produced well typed output. The general form of this is [`/mark/`]()
where `mark` exists in the `/main/mar/` directory. A `psal` is a partial
`hymn`, where `hymn` is the hoon structure for `html`.
`/@` loads a list of files in numerical order from the previously
specified `++beam` using our mark, `psal`. `/@` has a few close
relatives. `/&`, for example, reads files by `@da` or absolute date. You
can see the rest in the [horn section of the library]().
`/;` takes the output from `/@` and `/psal/` and passes it to a twig. In
this case, a gate. Our `/@` actually produces a [`++list`]() of
pairs of `[@ manx]` where the `@` is the filename, and the `manx` is the
converted contents. We use [`++turn`](), one of our `++list`
operator functions, to iterate through the list and produce only a list
of `++manx`. This is the output assigned to `posts`.
Then, further down, we use [`;*`]() to write the list to the page.
<hr>
</hr>
12.
---
#### Look in
/pub/fab/guide/hymn.hook
/pub/fab/guide/main.css
/pub/fab/guide/main.js
#### Try it
http://ship-name.urbit.org/main/pub/fab/guide/
#### Bring it all together
It turns out it's pretty easy to pull our examples together into a
single blog-like page using what we just covered. We include some css to
make things a bit prettier, and this should give you a good jumping off
point for experimenting with your own publishing code.
#### Have fun!

View File

@ -1,273 +0,0 @@
XX The CLI is under heavy development with, with pieces being folded
into the "window manager" `sole` and the new cli `dojo`. Don't expect
any of the following to work as described.
This guide is intended to get you oriented in the Arvo command prompt
and give you a tour of some basic utilities. The command prompt comes in
two flavors, in a web browser and in a terminal. For the most part
they're the same, except that in a browser you can evaluate tall-form
Hoon expressions but you can't run readline apps, such as `:talk`.
Every Arvo command prompt is also a Hoon REPL. The command line is a
great place to test out your hoon knowledge. In this guide we're just
going to talk about some basic system utilities and get comfortable
moving around in `%clay`. If you'd just like to see a list of
command-line utilities, you can find the Arvo man pages
[here](../arvo/util).
This rudimentary tour should work well in both places.
1
Move around `%clay`
After finishing the [setup instructions]() you should have an Arvo
prompt that looks like this:
~talsur-todres/try=>
The path at the beginning of your prompt is actually a path in the
global filesystem of Urbit, called `%clay`. Since `%clay` is universal
across all of Urbit, each full path starts with a ship name. `%clay` is
also versioned on a per-desk basis. Desks are the top-level directories
in your pier.
Moving around `%clay` is simple. There is no equivalent of `cd`.
Instead, just type a valid path name at the prompt to move to that
directory. Here we'll move to our starting root path in the try desk,
`/try=` to the `main` desk:
~talsur-todres/try=> /=main=
=% /~talsur-todres/main/0
~talsur-todres/main=>
We have two shortcuts in `%clay` that are worth noting, `=` and `%`.
`=` copies in some corresponding part of our current path. In the second
line above you can see how the `=` in `/=main=` pull in the
`~talsur-todres` and `0` in from our starting directory,
`/~talsur-todres/try/0`. It's important to note that our full prompt to
start is `/~talsur-todres/try=`, where the trailing `=` indicates the
current revision. In the shell, revision `0` never exists — it's used as
a pointer to the head.
`%` is similar to `.` in unix:
~talsur-todres/main=> %
=% /~talsur-todres/main/0
~talsur-todres/main=> %%
[~.~talsur-todres ~.main ~]
~talsur-todres/main=> %%%
[~.~talsur-todres ~]
~talsur-todres/main=> %%%%
~
When using `%` to move around in `%clay` you need to make sure to use
leading and trailing `/` to ensure your path is interpolted correctly:
~talsur-todres/main=> /%%%/try=
=% /~talsur-todres/try/0
~talsur-todres/try=>
2
Create some revisions
Let's use `:into`, our simple utility for writing text to a file, to
create a new file:
~talsur-todres/try=> :into %/helo/txt 'helo mars'
written
~talsur-todres/try=>
To confirm that our file was written, we can use `:ls`. `:ls` prints a
list of directory contents, but requires that you specify a path. `%`
will suffice for the current path:
~talsur-todres/try=> :ls %
readme helo
~talsur-todres/try=>
Let's quickly switch back to a unix command prompt to see a few things
about both how files are synced between `%clay` and unix, and where your
apps live.
my-pier/talsur-todres/$ ls try
helo.txt readme.md
my-pier/talsur-todres/$ cat try/helo.txt
helo mars
Here you can see that our files are synced back to unix as they are
changed in urbit, and vice-versa. As you change files in unix you'll see
those changes appear in `%clay`.
my-pier/talsur-todres/$ ls base/app/
bang grep peek solid tweet
began helm poke sync twit
begin hi pope talk twitter-auth
cat into reboot tease twitter-feed
code label reload terminal type
cp ls reset test unsync
curl matrix rm ticket verb
dojo mv shell time wipe
gnab nop sole tree ye
my-pier/talsur-todres/$ cat base/app/ls/core.hook
:: ConCATenate file listings
::
:::: /hook/core/cat/app
::
/+ sh-utils
// /%%%/ls/subdir
!:
::::
::
|_ [hid=hide ~]
++ peer ,_`.
++ poke--args
%+ args-into-gate .
|= [arg=(list path)]
=- tang/(zing -)
%+ turn arg
|= pax=path
^- tang
=+ ark=;;(arch .^(%cy pax))
?^ q.ark
:- leaf/(spud pax)
%+ turn (lore ;;(@t .^(%cx pax)))
|=(a=cord leaf/(trip a))
?- r.ark :: handle ambiguity
~
[rose/[" " `~]^~[leaf/"~" (smyt pax)]]~
[[@t ~] ~ ~]
$(pax (welp pax /[p.n.r.ark]))
*
=- [palm/[": " ``~]^-]~
:~ rose/[" " `~]^~[leaf/"*" (smyt pax)]
`tank`(subdir pax r.ark)
==
==
--
Here you can see that `/base/app` is the main location where our apps
are stored, and the contents of the `:ls` app. urbit applications are of
course written in hoon, our naitive programming language. Don't worry
about the contents of the file for now. Since changes in unix are synced
back in to urbit, we can develop urbit programs by simply editing them
in our favorite editor and saving them.
For the time being let's switch back to urbit and update our file with
some new content, so we can see how `%clay` stores revisions.
~talsur-todres/try=> :into %/helo/txt 'gbye mars'
written
~talsur-todres/try=> :ls /=try/1
readme helo
~talsur-todres/try=> :cat /=try/1/helo/txt
/~talsur-todres/try/9/helo/txt
helo mars
~talsur-todres/try=> :cat /=try/2/helo/txt
/~talsur-todres/try/10/helo/txt
gbye mars
~talsur-todres/try=> :cat /=try=/helo/txt
/~talsur-todres/try/~2014.11.26..01.06.33..c93a/helo/txt
gbye mars
~talsur-todres/try=>
Here we use `:ls` to investigate the filesystem across versions. You can
see that our `helo` file exists in our first revision. Using the simple
`:cat` command we can print the contents of `/=try/helo/txt` in its two
separate, versioned states.
We can even move to a different version of our desk and look around:
~talsur-todres/try=> /=try/1
=% /~talsur-todres/try/1
~talsur-todres/try/1> :ls %
readme helo
~talsur-todres/try/1>
This is sort of like being in a detached HEAD in git.
3
Start a yacht
Each Urbit destroyer can delegate around four billion yachts. Yachts are
also urbit ships, but are pegged to their parent identity, and are set
up to mirror their filesystem. We can generate a `[ship: ticket]` pair
for a yacht by using the `:ticket` utility:
~talsur-todres/try=> :ticket ~talsur-todres-talsur-todres
~talsur-todres-talsur-todres: ~figpem-fapmyl-wacsud-racwyd
Every yacht for a particular destroyer ends in the same `ship-name`, and
has every possible destroyer prefix. For example,
`~tasfyn-partyv-talsur-todres` is also a valid yacht from
`~talsur-todres`.
Start up a new `vere` process with something like `bin/vere -c yacht`.
Then run `:begin` and enter the `[ship: ticket]` pair you just generated
when prompted. When the process is complete you should get a
`; ~talsur-todres-talsur-todres :y1: is your neighbor` message on your
destroyer. To confirm that everything is working properly, you can use
`:hi` to send a message:
~talsur-todres/try=> :hi ~talsur-todres-talsur-todres "whats up"
hi ~talsur-todres-talsur-todres successful
~talsur-todres/try=>
Which will appear on your new yacht:
< ~talsur-todres: whats up
~talsur-todres-talsur-todres/try=>
You should also see the contents of your `/try` desk mirrored on your
yacht:
~talsur-todres-talsur-todres/try=> :ls %
readme helo
~talsur-todres-talsur-todres/try=>
Making another change on your destroyer should automatically propagate
down to your yacht:
~talsur-todres/try=> :into %/helo/txt 'back to mars'
written
~talsur-todres/try=>
[%merge-fine ~talsur-todres %try]
~talsur-todres-talsur-todres/try=> :cat %/helo/txt
back to mars
~talsur-todres-talsur-todres/try=>
4
Move files around
Another familiar command line utility is `:mv`:
~talsur-todres/try=> :mv %/helo/txt %/test/helo/txt
moved
~talsur-todres/try=>
[%merge-fine ~talsur-todres %try]
~talsur-todres-talsur-todres/try=> :cat %/test/helo/txt
back to mars
~talsur-todres-talsur-todres/try=>
In `%clay` we don't use file extensions or folders. A path either does
or does not have anything in it. There's no need to do the equivalent of
`mkdir` before moving something.
We also implement the familiar `:rm`:
~talsur-todres/try=> :rm %/test/helo/txt
removed
~talsur-todres/try=> :cat %/test/helo/txt
file /~talsur-todres/try/~2014.11.26..16.49.52..3f5e/test/helo/txt not available
~talsur-todres/try=>
[%merge-fine ~talsur-todres %try]
~talsur-todres-talsur-todres/try=> :cat %/test/helo/txt
file /~tasfyn-partyv-talsur-todres/try/~2014.11.26..16.50.15..556b/test/helo/txt not available
~talsur-todres-talsur-todres/try=>

View File

@ -1,284 +0,0 @@
This guide is focussed on storing application state using the `%gall`
vane. To show off how we store and distribute data in Urbit we're going
to examine a simple webapp. Some of the material here expects that you
have looked over the [`%ford` guide](). If you haven't, it's a good idea
to start there. There's also more information in the [`%gall`
overview]() and [`%gall` commentary]() but it's not necessary that you
read those before going forward.
One important thing to keep in mind is that `%gall` services aren't
'started' or 'stopped' as in a unix system. When your files are copied
in they are compiled and begin running immediately and permanently.
`%gall` services simply wake up when certain events happen.
If you need to make updates to the structure of your stored data, you
write connector functions or (when developing) just throw your existing
data away. We'll see examples of how this works, just keep in mind that
when we talk about a `%gall` 'service' it has no concept of 'running'.
Going forward we'll refer to the directory you cloned the repo in as
`/$URB_DIR` and assume that your pier is listening for HTTP connections
on port `8080`.
1.
Get the code.
Clone the GitHub repository and move the files into your `/main` desk,
under the corresponding paths. You will need four files:
- /main/app/lead/core.hook
- /main/pub/lead/hymn.hook
- /main/pub/lead/src/main.css
- /main/pub/lead/src/main.js
When everything is in place, try it:
http://localhost:8080/main/pub/lead/
That URL should render a page and be self explanatory. Try adding names
to the leaderboard and incrementing their scores. It's also fun to open
a few tabs and watch how the state gets updated simultaneously.
2.
How is the code structured?
In our `%ford` guide we generated pages by defining all of their
possible states, but we didn't exactly store any data. When building
applications on top of Urbit we think of them as existing in two natural
parts: page resources and state services. Effectively, we think of any
Urbit app talking to the web as a single page app whose resources are
generated by `%ford` which talks to a `%gall` service if it needs to
persist any state. Let's look more closely at the specifics in this
simple app.
When we load our page, we render the contents of our
`/main/pub/lead/hymn.hook`. This file should look familiar as
[`++sail`](). Our `hymn.hook` file writes the basic HTML elements to the
page, and pulls in our supporting CSS and JavaScript resources.
Our application-specific resources are stored in `/main/pub/lead/src/`.
`/main/pub/lead/src/main.css` simply produces the page layout, while
`/main/pub/lead/src/main.js` updates the page and sends data.
We also use two utility scripts: `/gop/hart.js` and
`/main/lib/urb.js`. These are the standard libraries for handling
data transfer from a browser to Urbit, and are very frequently used.
`hart.js` handles the page heartbeat, making regular AJAX requests so we
can keep track of subscribers, and `urb.js` offers a more complete set
of helper functions. `urb.js` depends on `hart.js`, so that's why
`hart.js` always goes in the `<head>`. For complete documentation, check
out the [`urb.js` reference]().
Our application state is stored and distributed to connected clients by
`/main/app/lead/core.hook`. Let's take a closer look at how that works.
At the top of our `core.hook` we have:
/? 314 :: need urbit 314
This should be familiar from the `%ford` guide. Here we're requiring
that this code run on an Urbit ship where `(lte zuse 314)` is `yes`. In
this `core.hook` we only use one `%ford` rune, but this is where we
would also pull in any dependencies we might have or use other [`/`
runes]().
Below our `/?` you can see that our code is divided into two sections: a
[`|%`]() where we define our models, and a [`|_`]() where we define the
body of our program. We'll look at these more closely one at a time.
3.
How is our state stored?
In `/main/app/lead/core.hook`:
++ axle
$% [%0 p=(map ,@t ,@ud)]
==
is the first arm inside our leading `|%` that's important to notice.
`++axle` defines the tile for our state. By convention we store our
state as a [`$%`](), or labelled cases. We assume that our state can be
versioned, so we want its model to be one of many tagged cases. This
makes it possible to migrate our state to a new version of the service.
Since this is the first version of our app, we tag our state with `%0`.
In this simple application we're keeping track of pairs of names to
scores, and we define that here as `(map ,@t ,@ud)`. You can think of
this kind of like an associative array of strings to numbers, or an
object with string keys and numeric values.
When we use `++axle` to define the type of our state it's kind of like
declaring a schema definition. There's no secondary data storage layer.
Since `%gall` services run permanently your data persists as normal
application state. We use tiles the way we normally would to declare the
type of data that we're passing around.
Looking ahead, you can see that our main `|_` takes a `++axle` as part
of its sample. Let's look at how that core actually works, to get a
sense of what our application is doing.
4.
Where do requests go?
In `/main/app/lead/core.hook`:
++ peer
|= [ost=bone you=ship pax=path]
^- [(list move) _+>]
?~ pax
[[ost %give %rust %json vat-json]~ +>.$]
:_ +>.$
:_ ~
?+ -.pax
=- [ost %give %mean -]
`[%not-found [%leaf "you need to specify a path"]~]
%data
=- [ost %give %rush %json -]
(joba %conn %b &)
==
is the most important arm to look at first. `++peer` is one of the
predefined arms that `%gall` calls when certain events happen. You can
find them all in the [`%gall` overview]().
We 'get a `++peer`' when we get either a HTTP request, or a subscription
request. Each time this happens our main `|_` is populated with a
`++hide` and our current `++axle` in its sample and `++peer` gets passed
three things: `[ost=bone you=ship pax=path]`. The sample in the `|_`
that contains `++peer` is our application state and all of the contained
arms have access to that sample as part of their context. To change the
state we simply produce a new context with changed values.
Let's look at each of these parts of our context and the sample in
`++peer`.
`++hide`, labelled `hid` in peer's context, gives us some information
about the `++request` being passed in. You can look at the specifics in
the [`%arvo` `++models`](), but for our purposes we can think of it
simply as request metadata.
`++axle`, labelled as `vat` in peer's context, should be familiar from
the discussion in the previous step.
`ost` is a `++bone`, or an identifier for an `%arvo` duct. 'Duct' is
actually a pretty good word for what a ++duct does. Informally, when an
event is processed in `%arvo` we patch together our requisite
computations with `++ducts`. For example, when we get a network packet,
parse it, pass it to the webserver, and then pass it to the application
framework we use a `++duct` to make all those connections. In `++peer`
our ost just identifies the incoming request by number. We don't have
access to the connecting `++duct`, but we use `ost` in the effects we
produce so our responses are correctly coupled to the incoming request.
`you` is a `++ship`, which is just a [`@p`]() or a phonemic string like
`~tasfyn- partyv`. `%eyre` does some work to figure out who this is, or
uses a submarine name if it can't be determined. You can read more about
how we parse identities in `%eyre` in the [`%eyre` reference]().
`pax` is a `++path`, or a list of `@ta`. In Hoon we most often write
paths as you would expect, `/something/like/this`. In `%gall` services
requests come in on a specific path, like `/data` or `/`.
`++peer`, as with any arm that handles events, must produce a pair of a
`(list ++move)` and our context, with any intended changes. In this peer
we handle two cases, when `pax` is empty, or `~`, when our `pax` is
`/data`. We throw an error if `pax` is anything else.
5.
What exactly is a list of moves?
Try pointing your browser at:
http://localhost:8082/lead/
to see our response when `pax` in `++peer` is `~`. In our case we use
this URL to load the initial state of the application as JSON. This is
produced by the line `[[ost %give %rust %json vat-json]~ +>.$]` which
produces a single `++move`, and our local context. Let's look more
closely at our `++move`.
++ move ,[p=bone q=[%give gift]] :: output operation
From our prior discussion we're familiar with a `++bone`, and `++gift`
is defined right above in `core.hook`:
++ gift :: output action
$% [%rust gilt] :: total update
[%rush gilt] :: partial update
[%mean (unit (pair term (list tank)))] :: Error, maybe w/ msg
[%nice ~] :: Response message
==
::
Which clearly depends on `++gilt`:
++ gilt :: subscription frame
$% [%hymn p=manx] :: html tree
[%json p=json] :: json
==
::
`++gift` defines the possible actions we can take in the moves that we
produce. We can send either partial or total updates with `%rush` or
`%rust` respectively. We can also send either an error, `%mean` or
default acknowledgement, `%nice`.
Returning to our original `++move`, `[ost %give %rust %json vat-json]`
we can now read it as 'send a total update with `++vat-json` as
`++json`'. `++vat-json` simply takes our `(map @t @ud)` and turns it in
to JSON.
Looking at the remainer of `++peer` we can see that it is mostly
control-flow that produces a `%mean` if our `pax` is not matched, and a
`%rush` if our `pax` is `%data`. We'll revisit this `%data` path later
on.
5.
How do we change our state?
All of our state changes happen in `++poke-json`. Incoming messages are
handled by `++poke` arms in `%gall` services. If an incoming message has
a `%logo` it is appeneded after a `-`. Messages from the web are often
sent as JSON, so `++poke- json` is common for services that face the
web.
Let's walk through this part:
=. p.vat
(~(put by p.vat) newl)
:_ +>.$
:* [ost %give %nice ~]
(deliver %upd-lead (joba -.newl [%n (scot %ud +.newl)]))
==
Using [`=.`]() we update the value of `p.vat` in our context using
[`put:by`](), one of our map container functions. Then, we produce
`+>.$` as our context. Since we have changed the value of `p.vat` within
our immediate context, `$`, this is equivalient to updating the state of
our service. Changing a value in your context and producing it is all
you need to do to update your permanent state. That's one of the main
goals of `%gall`, to be a single-level store.
So, how did we get to this point in `++poke-json`?
=+ ^= jop
^- kiss
%- need %. jon
=> jo %- of
:~ [%new-lead so]
[%add-lead so]
==
6.
`++deliver`
7.
main.js

View File

@ -1 +0,0 @@
A fully featured app using %ford and %gall

View File

@ -1,100 +0,0 @@
Doing development can be a messy process. Since Urbit ships are meant to
last forever it can be convenient to development on a disposable ship as
to not permanently destroy any of your own part of the urbit network. In
this short guide we're going to go over how to set up a fake network for
development on a single physical machine.
This guide assumes that you have already followed the [setup
instructions](). Going forward we'll refer to the directory you cloned
the repo in as `/$URB_DIR`.
1.
Start a fake `vere` for the carrier `~zod`.
In `/$URB_DIR`, run
$ bin/vere -F -I ~zod -c zod
This will boot `vere` into the carrier `~zod`. Because we're using the
flag `-F` `vere` doesn't check any of the keys to confirm that we are in
fact the owner of `~zod`. We use `-I` here to signal to `vere` that we
want to start an 'imperial' ship, or carrier. `-I` takes a ship name.
You can enter any one of the 256 Urbit carriers. More information on
`vere` and its command line options can be found [here]().
You should see `vere` start as usual, although instead of copying its
files from a parent ship the files are copied from `urb/zod` inside your
Urbit directory.
For most development tasks, using a fake carrier works really well. You
get a very short name, and a safe testing environment. If you need to
test out a collection of ships talking to each other, let's keep going.
2.
Start a second fake `vere`.
In a new terminal, cd to `/$URB_DIR` and run:
$ bin/vere -F -c doznec
Since we don't specify a carrier with `-I` here, this should boot into a
submarine, as if you had started vere normally. In your running fake
`~zod` you should see a [`~&`]() alerting you that the sub you just
started is your neighbor. This means that a key exchange has happened,
and your packets are being transmitted directly. Now, let's get a ticket
for a cruiser.
In your fake `~zod`, ticket a cruiser:
~zod/try=> :ticket ~doznec
This line should return a `[ship: ticket]` pair of [`@p`](). You can Now
you can return to your submarine and run:
~sipmyl-wolmeb-haswel-losmyl--dibten-holdyn-dacdyn-natsep/try=> :begin
Use the `[ship: ticket]` pair you got from your fake `~zod` to complete
the `:begin` process for `~doznec`. When finished you should see
something like `; ~doznec _doz_ is your neighbor` on your fake `~zod`.
You can repeat this process on `~doznec`, ticketing destroyers that are
children of `~doznec` by running `:ticket` with a valid destroyer.
`:ticket` actually takes two arguments, a ship name and a number
indicating how many tickets to generate. `~tasfyn-partyv` is the first
destroyer under `~doznec`, so you can run `:ticket ~tasfyn-partyv 5` to
get five `[ship: ticket]` pairs.
3.
Add some files, make sure the network if functioning.
You should now have a directory `/$URB_DIR/zod`.
In
/$URB_DIR/zod/zod/try/test.txt
Put
hello from mars
You should see a sync event on `~zod` indicated by a `+` with the file
path, and at least one `%merge-fine` messages on `~doznec`. On your
filesystem, you should see the file mirrored in
`/$URB_DIR/doznec/doznec/try/test.txt`.
You can also send a few `:hi` messages over the network. On `~doznec`
try:
~doznec/try=> :hi ~zod "just checking in from urth"
You should see the message appear on your `~zod` and get a
`hi ~zod successful` on your `~doznec`.
This is a good way to set up a test environment where you can try
anything out and break anything you want. When working in these test
environments it is usually safest to keep your working files outside of
your pier and copy them in. This way you can quickly
`rm -rf zod/ && bin/vere -F -I ~zod -c zod` to start again.

View File

@ -139,7 +139,7 @@ Produces a [tape]() of the date in UTC format.
`yed` is a [`date`]().
~zod/try=> (dust (yore -<-))
~zod/try=> (dust (yore ->-))
"Tue, 21 Oct 2014 21:35:12 +0000"
~zod/try=> (dust [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]])
"Fri, 11 Oct 2002 12:20:55 +0000"
@ -282,17 +282,18 @@ beginning with Sunday.
Leap second dates
++ les ^- (list ,@da)
:~ ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1 ~1996.1.1
~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1 ~1988.1.1
~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1 ~1979.1.1
~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1 ~1973.1.1
~1972.7.1
:~ ~2015.7.1 ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1
~1996.1.1 ~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1
~1988.1.1 ~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1
~1979.1.1 ~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1
~1973.1.1 ~1972.7.1
==
Produces a list of the (absolute) dates ([`@da`]) of the 25 leap seconds
~zod/try=/hom> les:yu
~[
~2015.7.1
~2012.7.1
~2009.1.1
~2006.1.1
@ -329,19 +330,19 @@ Produces a list of the (absolute) dates ([`@da`]) of the 25 leap seconds
Back-shifted leap second dates
++ lef ^- (list ,@da)
:~ ~2012.6.30..23.59.59 ~2008.12.31..23.59.58
~2005.12.31..23.59.57 ~1998.12.31..23.59.56
~1997.6.30..23.59.55 ~1995.12.31..23.59.54
~1994.6.30..23.59.53 ~1993.6.30..23.59.52
~1992.6.30..23.59.51 ~1990.12.31..23.59.50
~1989.12.31..23.59.49 ~1987.12.31..23.59.48
~1985.6.30..23.59.47 ~1983.6.30..23.59.46
~1982.6.30..23.59.45 ~1981.6.30..23.59.44
~1979.12.31..23.59.43 ~1978.12.31..23.59.42
~1977.12.31..23.59.41 ~1976.12.31..23.59.40
~1975.12.31..23.59.39 ~1974.12.31..23.59.38
~1973.12.31..23.59.37 ~1972.12.31..23.59.36
~1972.6.30..23.59.35
:~ ~2015.6.30..23.59.59 ~2012.6.30..23.59.59
~2008.12.31..23.59.58 ~2005.12.31..23.59.57
~1998.12.31..23.59.56 ~1997.6.30..23.59.55
~1995.12.31..23.59.54 ~1994.6.30..23.59.53
~1993.6.30..23.59.52 ~1992.6.30..23.59.51
~1990.12.31..23.59.50 ~1989.12.31..23.59.49
~1987.12.31..23.59.48 ~1985.6.30..23.59.47
~1983.6.30..23.59.46 ~1982.6.30..23.59.45
~1981.6.30..23.59.44 ~1979.12.31..23.59.43
~1978.12.31..23.59.42 ~1977.12.31..23.59.41
~1976.12.31..23.59.40 ~1975.12.31..23.59.39
~1974.12.31..23.59.38 ~1973.12.31..23.59.37
~1972.12.31..23.59.36 ~1972.6.30..23.59.35
==
::
@ -350,6 +351,7 @@ Galactc Time equivalents of the UTC leap second dates in [`++les`](/doc/hoon/lib
~zod/try=/hom> lef:yu
~[
~2015.6.30..23.59.59
~2012.6.30..23.59.59
~2008.12.31..23.59.58
~2005.12.31..23.59.57

View File

@ -464,3 +464,16 @@ Compute direct senior.
~del
~zod/main=> (sein ~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet)
~zod
Compute Phonemic base.
~zod/main=> (saxo ~rabdec-monfer)
~[~rabdec-monfer ~dalnel ~del]
~zod/main=> `@rd`~rabdec-monfer
0x5fd25
[%rlyd 0x5.fd25]
0b1.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
~zod/main=> `@p`0x5.fd25
~rabdec-monfer
For `@rd` and `@p` see the [odors](../reference/odors) reference

View File

@ -1,84 +1,84 @@
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau.woff");
src: url("//storage.googleapis.com/urbit-extra/bau.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-italic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-italic.woff");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-medium.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-bold.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-super.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-super.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-superitalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-extralight.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-extralight.woff");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-light.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-light.woff");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-regular.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-regular.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-medium.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-bold.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-black.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-black.woff");
font-weight: 700;
font-style: normal;
}

View File

@ -1,84 +1,84 @@
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau.woff");
src: url("//storage.googleapis.com/urbit-extra/bau.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-italic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-italic.woff");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-medium.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-bold.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-super.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-super.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-superitalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-extralight.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-extralight.woff");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-light.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-light.woff");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-regular.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-regular.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-medium.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-bold.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-black.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-black.woff");
font-weight: 700;
font-style: normal;
}

View File

@ -4,42 +4,42 @@
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau.woff")
src url("//storage.googleapis.com/urbit-extra/bau.woff")
font-weight 400
font-style normal
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-italic.woff")
src url("//storage.googleapis.com/urbit-extra/bau-italic.woff")
font-weight 400
font-style italic
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-medium.woff")
src url("//storage.googleapis.com/urbit-extra/bau-medium.woff")
font-weight 500
font-style normal
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-mediumitalic.woff")
src url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff")
font-weight 500
font-style italic
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-bold.woff")
src url("//storage.googleapis.com/urbit-extra/bau-bold.woff")
font-weight 600
font-style normal
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-bolditalic.woff")
src url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff")
font-weight 600
font-style italic
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-super.woff")
src url("//storage.googleapis.com/urbit-extra/bau-super.woff")
font-weight 600
font-style normal
@font-face
font-family "bau"
src url("https://storage.googleapis.com/urbit-extra/bau-superitalic.woff")
src url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff")
font-weight 600
font-style italic
@ -49,21 +49,21 @@
@font-face
font-family "scp"
src url("https://storage.googleapis.com/urbit-extra/scp-extralight.woff")
src url("//storage.googleapis.com/urbit-extra/scp-extralight.woff")
font-weight 200
font-style normal
@font-face
font-family "scp"
src url("https://storage.googleapis.com/urbit-extra/scp-light.woff")
src url("//storage.googleapis.com/urbit-extra/scp-light.woff")
font-weight 300
font-style normal
@font-face
font-family "scp"
src url("https://storage.googleapis.com/urbit-extra/scp-regular.woff")
src url("//storage.googleapis.com/urbit-extra/scp-regular.woff")
font-weight 400
font-style normal
@font-face
font-family "scp"
src url("https://storage.googleapis.com/urbit-extra/scp-medium.woff")
src url("//storage.googleapis.com/urbit-extra/scp-medium.woff")
font-weight 500
font-style normal

View File

@ -1,72 +1,72 @@
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau.woff");
src: url("//storage.googleapis.com/urbit-extra/bau.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-italic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-italic.woff");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-medium.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-bold.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-super.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-super.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("https://storage.googleapis.com/urbit-extra/bau-superitalic.woff");
src: url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-extralight.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-extralight.woff");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-light.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-light.woff");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-regular.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-regular.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("https://storage.googleapis.com/urbit-extra/scp-medium.woff");
src: url("//storage.googleapis.com/urbit-extra/scp-medium.woff");
font-weight: 500;
font-style: normal;
}